From af80317b64503ce9272a4d559c7e7b242c76d0b4 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 01:31:08 +0100 Subject: [PATCH 01/34] Remove Gatekeeper submodule and related code; refactor API endpoints to eliminate gatekeeper usage for rate limiting and security checks. --- .gitmodules | 3 - eslint.config.js | 1 - src/server/GameServer.ts | 225 ++++++------- src/server/Gatekeeper.ts | 160 --------- src/server/Master.ts | 86 +++-- src/server/README.md | 3 - src/server/Worker.ts | 702 ++++++++++++++++++--------------------- src/server/gatekeeper | 1 - 8 files changed, 473 insertions(+), 708 deletions(-) delete mode 100644 src/server/Gatekeeper.ts delete mode 100644 src/server/README.md delete mode 160000 src/server/gatekeeper diff --git a/.gitmodules b/.gitmodules index 45ff7b389..e69de29bb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "src/server/gatekeeper"] - path = src/server/gatekeeper - url = https://github.com/openfrontio/gatekeeper.git diff --git a/eslint.config.js b/eslint.config.js index 7977a4e11..4e3ac8acd 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -13,7 +13,6 @@ const gitignorePath = path.resolve(__dirname, ".gitignore"); /** @type {import('eslint').Linter.Config[]} */ export default [ includeIgnoreFile(gitignorePath), - { ignores: ["src/server/gatekeeper/**"] }, { files: ["**/*.{js,mjs,cjs,ts}"] }, { languageOptions: { globals: { ...globals.browser, ...globals.node } } }, pluginJs.configs.recommended, diff --git a/src/server/GameServer.ts b/src/server/GameServer.ts index 231990620..25e57eb89 100644 --- a/src/server/GameServer.ts +++ b/src/server/GameServer.ts @@ -26,7 +26,6 @@ import { GameEnv, ServerConfig } from "../core/configuration/Config"; import { GameType } from "../core/game/Game"; import { archive } from "./Archive"; import { Client } from "./Client"; -import { gatekeeper } from "./Gatekeeper"; import { rankingService } from "./RankingService"; const profanityFilter = new Filter(); @@ -262,139 +261,133 @@ export class GameServer { this.allClients.set(client.clientID, client); client.ws.removeAllListeners("message"); - client.ws.on( - "message", - gatekeeper.wsHandler(client.ip, async (message: string) => { - try { - const parsed = ClientMessageSchema.safeParse(JSON.parse(message)); - if (!parsed.success) { - const error = z.prettifyError(parsed.error); - this.log.error("Failed to parse client message", error, { - clientID: client.clientID, - }); - client.ws.send( - JSON.stringify({ - type: "error", - error, - message, - } satisfies ServerErrorMessage), - ); - client.ws.close(1002, "ClientMessageSchema"); - return; - } - const clientMsg = parsed.data; - switch (clientMsg.type) { - case "intent": { - if (clientMsg.intent.clientID !== client.clientID) { + client.ws.on("message", async (message: string) => { + try { + const parsed = ClientMessageSchema.safeParse(JSON.parse(message)); + if (!parsed.success) { + const error = z.prettifyError(parsed.error); + this.log.error("Failed to parse client message", error, { + clientID: client.clientID, + }); + client.ws.send( + JSON.stringify({ + type: "error", + error, + message, + } satisfies ServerErrorMessage), + ); + client.ws.close(1002, "ClientMessageSchema"); + return; + } + const clientMsg = parsed.data; + switch (clientMsg.type) { + case "intent": { + if (clientMsg.intent.clientID !== client.clientID) { + this.log.warn( + `client id mismatch, client: ${client.clientID}, intent: ${clientMsg.intent.clientID}`, + ); + return; + } + switch (clientMsg.intent.type) { + case "mark_disconnected": { this.log.warn( - `client id mismatch, client: ${client.clientID}, intent: ${clientMsg.intent.clientID}`, + `Should not receive mark_disconnected intent from client`, ); return; } - switch (clientMsg.intent.type) { - case "mark_disconnected": { - this.log.warn( - `Should not receive mark_disconnected intent from client`, - ); - return; - } - // Handle kick_player intent via WebSocket - case "kick_player": { - const authenticatedClientID = client.clientID; - - // Check if the authenticated client is the lobby creator - if (authenticatedClientID !== this.LobbyCreatorID) { - this.log.warn(`Only lobby creator can kick players`, { - clientID: authenticatedClientID, - creatorID: this.LobbyCreatorID, - target: clientMsg.intent.target, - gameID: this.id, - }); - return; - } - - // Don't allow lobby creator to kick themselves - if (authenticatedClientID === clientMsg.intent.target) { - this.log.warn(`Cannot kick yourself`, { - clientID: authenticatedClientID, - }); - return; - } - - // Log and execute the kick - this.log.info(`Lobby creator initiated kick of player`, { - creatorID: authenticatedClientID, + // Handle kick_player intent via WebSocket + case "kick_player": { + const authenticatedClientID = client.clientID; + + // Check if the authenticated client is the lobby creator + if (authenticatedClientID !== this.LobbyCreatorID) { + this.log.warn(`Only lobby creator can kick players`, { + clientID: authenticatedClientID, + creatorID: this.LobbyCreatorID, target: clientMsg.intent.target, gameID: this.id, - kickMethod: "websocket", }); - - this.kickClient(clientMsg.intent.target); return; } - default: { - this.addIntent(clientMsg.intent); - break; + + // Don't allow lobby creator to kick themselves + if (authenticatedClientID === clientMsg.intent.target) { + this.log.warn(`Cannot kick yourself`, { + clientID: authenticatedClientID, + }); + return; } - } - break; - } - case "ping": { - this.lastPingUpdate = Date.now(); - client.lastPing = Date.now(); - client.ws.send(JSON.stringify({ type: "ping" })); - break; - } - case "hash": { - client.hashes.set(clientMsg.turnNumber, clientMsg.hash); - break; - } - case "join": { - this.log.info( - "Client requested re-join/sync via existing connection", - { - clientID: client.clientID, - lastTurn: clientMsg.lastTurn, - }, - ); - this.sendStartGameMsg(client.ws, clientMsg.lastTurn); - break; - } - case "winner": { - if ( - this.outOfSyncClients.has(client.clientID) || - this.kickedClients.has(client.clientID) || - this.winner !== null - ) { + + // Log and execute the kick + this.log.info(`Lobby creator initiated kick of player`, { + creatorID: authenticatedClientID, + target: clientMsg.intent.target, + gameID: this.id, + kickMethod: "websocket", + }); + + this.kickClient(clientMsg.intent.target); return; } - this.winner = clientMsg; - this.archiveGame().catch((err) => - this.log.error("Failed to archive game", { error: err }), - ); - break; + default: { + this.addIntent(clientMsg.intent); + break; + } } - default: { - this.log.warn( - `Unknown message type: ${(clientMsg as any).type}`, - { - clientID: client.clientID, - }, - ); - break; + break; + } + case "ping": { + this.lastPingUpdate = Date.now(); + client.lastPing = Date.now(); + client.ws.send(JSON.stringify({ type: "ping" })); + break; + } + case "hash": { + client.hashes.set(clientMsg.turnNumber, clientMsg.hash); + break; + } + case "join": { + this.log.info( + "Client requested re-join/sync via existing connection", + { + clientID: client.clientID, + lastTurn: clientMsg.lastTurn, + }, + ); + this.sendStartGameMsg(client.ws, clientMsg.lastTurn); + break; + } + case "winner": { + if ( + this.outOfSyncClients.has(client.clientID) || + this.kickedClients.has(client.clientID) || + this.winner !== null + ) { + return; } + this.winner = clientMsg; + this.archiveGame().catch((err) => + this.log.error("Failed to archive game", { error: err }), + ); + break; } - } catch (error) { - this.log.info( - `error handline websocket request in game server: ${error}`, - { + default: { + this.log.warn(`Unknown message type: ${(clientMsg as any).type}`, { clientID: client.clientID, - }, - ); + }); + break; + } } - }), - ); + } catch (error) { + this.log.info( + `error handline websocket request in game server: ${error}`, + { + clientID: client.clientID, + }, + ); + } + }); client.ws.on("close", () => { this.log.info("client disconnected", { clientID: client.clientID, diff --git a/src/server/Gatekeeper.ts b/src/server/Gatekeeper.ts deleted file mode 100644 index ee47cbf50..000000000 --- a/src/server/Gatekeeper.ts +++ /dev/null @@ -1,160 +0,0 @@ -// src/server/Security.ts -import { NextFunction, Request, Response } from "express"; -import fs from "fs"; -import http from "http"; -import path from "path"; -import { fileURLToPath } from "url"; - -export enum LimiterType { - Get = "get", - Post = "post", - Put = "put", - WebSocket = "websocket", -} - -export interface Gatekeeper { - // The wrapper for request handlers with optional rate limiting - httpHandler: ( - limiterType: LimiterType, - fn: (req: Request, res: Response, next: NextFunction) => Promise, - ) => (req: Request, res: Response, next: NextFunction) => Promise; - - // The wrapper for WebSocket message handlers with rate limiting - wsHandler: ( - req: http.IncomingMessage | string, - fn: (message: string) => Promise, - ) => (message: string) => Promise; -} - -let gk: Gatekeeper | null = null; - -async function getGatekeeperCached(): Promise { - if (gk !== null) { - return gk; - } - return getGatekeeper().then((g) => { - gk = g; - return gk; - }); -} - -// Function to get the appropriate security middleware implementation -async function getGatekeeper(): Promise { - try { - // Get the current file's directory - const __filename = fileURLToPath(import.meta.url); - const __dirname = path.dirname(__filename); - - try { - // Check if the file exists before attempting to import it - const realMiddlewarePath = path.resolve( - __dirname, - "./gatekeeper/RealGatekeeper.js", - ); - const tsMiddlewarePath = path.resolve( - __dirname, - "./gatekeeper/RealGatekeeper.ts", - ); - - if ( - !fs.existsSync(realMiddlewarePath) && - !fs.existsSync(tsMiddlewarePath) - ) { - console.log("RealGatekeeper file not found, using NoOpGatekeeper"); - return new NoOpGatekeeper(); - } - - // Use dynamic import for ES modules - // Using a type assertion to avoid TypeScript errors for optional modules - const module = await import( - "./gatekeeper/RealGatekeeper.js" as string - ).catch(() => import("./gatekeeper/RealGatekeeper.js" as string)); - - if (!module || !module.RealGatekeeper) { - console.log( - "RealGatekeeper class not found in module, using NoOpGatekeeper", - ); - return new NoOpGatekeeper(); - } - - console.log("Successfully loaded real gatekeeper"); - return new module.RealGatekeeper(); - } catch (error) { - console.log("Failed to load real gatekeeper:", error); - return new NoOpGatekeeper(); - } - } catch (e) { - // Fall back to no-op if real implementation isn't available - console.log("using no-op gatekeeper", e); - return new NoOpGatekeeper(); - } -} - -export class GatekeeperWrapper implements Gatekeeper { - constructor(private getGK: () => Promise) {} - - httpHandler( - limiterType: LimiterType, - fn: (req: Request, res: Response, next: NextFunction) => Promise, - ) { - return async (req: Request, res: Response, next: NextFunction) => { - try { - const gk = await this.getGK(); - const handler = gk.httpHandler(limiterType, fn); - return handler(req, res, next); - } catch (error) { - next(error); - } - }; - } - - // Corrected implementation for WebSocket handler wrapper - wsHandler( - req: http.IncomingMessage | string, - fn: (message: string) => Promise, - ) { - return async (message: string) => { - try { - const gk = await this.getGK(); - const handler = gk.wsHandler(req, fn); - return handler(message); - } catch (error) { - console.error("WebSocket handler error:", error); - } - }; - } -} - -export class NoOpGatekeeper implements Gatekeeper { - // Simple pass-through with no rate limiting - httpHandler( - limiterType: LimiterType, - fn: (req: Request, res: Response, next: NextFunction) => Promise, - ) { - return async (req: Request, res: Response, next: NextFunction) => { - try { - await fn(req, res, next); - } catch (error) { - next(error); - } - }; - } - - // Corrected implementation for WebSocket handler wrapper - wsHandler( - req: http.IncomingMessage | string, - fn: (message: string) => Promise, - ) { - return async (message: string) => { - try { - await fn(message); - } catch (error) { - console.error("WebSocket handler error:", error); - } - }; - } -} - -export const gatekeeper: Gatekeeper = new GatekeeperWrapper(() => - getGatekeeperCached(), -); diff --git a/src/server/Master.ts b/src/server/Master.ts index a68f27ad8..94a1d1719 100644 --- a/src/server/Master.ts +++ b/src/server/Master.ts @@ -7,7 +7,6 @@ import { fileURLToPath } from "url"; import { getServerConfigFromServer } from "../core/configuration/ConfigLoader"; import { GameInfo, ID } from "../core/Schemas"; import { generateID } from "../core/Util"; -import { gatekeeper, LimiterType } from "./Gatekeeper"; import { logger } from "./Logger"; import { MapPlaylist } from "./MapPlaylist"; @@ -144,62 +143,53 @@ export async function startMaster() { }); } -app.get( - "/api/env", - gatekeeper.httpHandler(LimiterType.Get, async (req, res) => { - const envConfig = { - game_env: process.env.GAME_ENV, - }; - if (!envConfig.game_env) return res.sendStatus(500); - res.json(envConfig); - }), -); +app.get("/api/env", async (req, res) => { + const envConfig = { + game_env: process.env.GAME_ENV, + }; + if (!envConfig.game_env) return res.sendStatus(500); + res.json(envConfig); +}); // Add lobbies endpoint to list public games for this worker -app.get( - "/api/public_lobbies", - gatekeeper.httpHandler(LimiterType.Get, async (req, res) => { - res.send(publicLobbiesJsonStr); - }), -); +app.get("/api/public_lobbies", async (req, res) => { + res.send(publicLobbiesJsonStr); +}); -app.post( - "/api/kick_player/:gameID/:clientID", - gatekeeper.httpHandler(LimiterType.Post, async (req, res) => { - if (req.headers[config.adminHeader()] !== config.adminToken()) { - res.status(401).send("Unauthorized"); - return; - } +app.post("/api/kick_player/:gameID/:clientID", async (req, res) => { + if (req.headers[config.adminHeader()] !== config.adminToken()) { + res.status(401).send("Unauthorized"); + return; + } - const { gameID, clientID } = req.params; + const { gameID, clientID } = req.params; - if (!ID.safeParse(gameID).success || !ID.safeParse(clientID).success) { - res.sendStatus(400); - return; - } + if (!ID.safeParse(gameID).success || !ID.safeParse(clientID).success) { + res.sendStatus(400); + return; + } - try { - const response = await fetch( - `http://localhost:${config.workerPort(gameID)}/api/kick_player/${gameID}/${clientID}`, - { - method: "POST", - headers: { - [config.adminHeader()]: config.adminToken(), - }, + try { + const response = await fetch( + `http://localhost:${config.workerPort(gameID)}/api/kick_player/${gameID}/${clientID}`, + { + method: "POST", + headers: { + [config.adminHeader()]: config.adminToken(), }, - ); - - if (!response.ok) { - throw new Error(`Failed to kick player: ${response.statusText}`); - } + }, + ); - res.status(200).send("Player kicked successfully"); - } catch (error) { - log.error(`Error kicking player from game ${gameID}:`, error); - res.status(500).send("Failed to kick player"); + if (!response.ok) { + throw new Error(`Failed to kick player: ${response.statusText}`); } - }), -); + + res.status(200).send("Player kicked successfully"); + } catch (error) { + log.error(`Error kicking player from game ${gameID}:`, error); + res.status(500).send("Failed to kick player"); + } +}); async function fetchLobbies(): Promise { const fetchPromises: Promise[] = []; diff --git a/src/server/README.md b/src/server/README.md deleted file mode 100644 index 837c1c0b7..000000000 --- a/src/server/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Gatekeeper - -Security module for botting, rate limiting, fingerprinting, etc. diff --git a/src/server/Worker.ts b/src/server/Worker.ts index 69a712c32..2ffb25675 100644 --- a/src/server/Worker.ts +++ b/src/server/Worker.ts @@ -20,7 +20,6 @@ import { CreateGameInputSchema, GameInputSchema } from "../core/WorkerSchemas"; import { archive, readGameRecord } from "./Archive"; import { Client } from "./Client"; import { GameManager } from "./GameManager"; -import { gatekeeper, LimiterType } from "./Gatekeeper"; import { getUserMe, verifyClientToken } from "./jwt"; import { logger } from "./Logger"; import { rankingService } from "./RankingService"; @@ -90,431 +89,382 @@ export async function startWorker() { }), ); - app.post( - "/api/create_game/:id", - gatekeeper.httpHandler(LimiterType.Post, async (req, res) => { - const id = req.params.id; - const creatorClientID = (() => { - if (typeof req.query.creatorClientID !== "string") return undefined; + app.post("/api/create_game/:id", async (req, res) => { + const id = req.params.id; + const creatorClientID = (() => { + if (typeof req.query.creatorClientID !== "string") return undefined; - const trimmed = req.query.creatorClientID.trim(); - return ID.safeParse(trimmed).success ? trimmed : undefined; - })(); + const trimmed = req.query.creatorClientID.trim(); + return ID.safeParse(trimmed).success ? trimmed : undefined; + })(); - if (!id) { - log.warn(`cannot create game, id not found`); - return res.status(400).json({ error: "Game ID is required" }); - } - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const clientIP = req.ip || req.socket.remoteAddress || "unknown"; - const result = CreateGameInputSchema.safeParse(req.body); - if (!result.success) { - const error = z.prettifyError(result.error); - return res.status(400).json({ error }); - } + if (!id) { + log.warn(`cannot create game, id not found`); + return res.status(400).json({ error: "Game ID is required" }); + } + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const clientIP = req.ip || req.socket.remoteAddress || "unknown"; + const result = CreateGameInputSchema.safeParse(req.body); + if (!result.success) { + const error = z.prettifyError(result.error); + return res.status(400).json({ error }); + } - const gc = result.data; - if ( - gc?.gameType === GameType.Public && - req.headers[config.adminHeader()] !== config.adminToken() - ) { - log.warn( - `cannot create public game ${id}, ip ${ipAnonymize(clientIP)} incorrect admin token`, - ); - return res.status(401).send("Unauthorized"); - } + const gc = result.data; + if ( + gc?.gameType === GameType.Public && + req.headers[config.adminHeader()] !== config.adminToken() + ) { + log.warn( + `cannot create public game ${id}, ip ${ipAnonymize(clientIP)} incorrect admin token`, + ); + return res.status(401).send("Unauthorized"); + } - // Double-check this worker should host this game - const expectedWorkerId = config.workerIndex(id); - if (expectedWorkerId !== workerId) { - log.warn( - `This game ${id} should be on worker ${expectedWorkerId}, but this is worker ${workerId}`, - ); - return res.status(400).json({ error: "Worker, game id mismatch" }); - } + // Double-check this worker should host this game + const expectedWorkerId = config.workerIndex(id); + if (expectedWorkerId !== workerId) { + log.warn( + `This game ${id} should be on worker ${expectedWorkerId}, but this is worker ${workerId}`, + ); + return res.status(400).json({ error: "Worker, game id mismatch" }); + } - // Pass creatorClientID to createGame - const game = gm.createGame(id, gc, creatorClientID); + // Pass creatorClientID to createGame + const game = gm.createGame(id, gc, creatorClientID); - log.info( - `Worker ${workerId}: IP ${ipAnonymize(clientIP)} creating ${game.isPublic() ? "Public" : "Private"}${gc?.gameMode ? ` ${gc.gameMode}` : ""} game with id ${id}${creatorClientID ? `, creator: ${creatorClientID}` : ""}`, - ); - res.json(game.gameInfo()); - }), - ); + log.info( + `Worker ${workerId}: IP ${ipAnonymize(clientIP)} creating ${game.isPublic() ? "Public" : "Private"}${gc?.gameMode ? ` ${gc.gameMode}` : ""} game with id ${id}${creatorClientID ? `, creator: ${creatorClientID}` : ""}`, + ); + res.json(game.gameInfo()); + }); // Add other endpoints from your original server - app.post( - "/api/start_game/:id", - gatekeeper.httpHandler(LimiterType.Post, async (req, res) => { - log.info(`starting private lobby with id ${req.params.id}`); - const game = gm.game(req.params.id); - if (!game) { - return; - } - if (game.isPublic()) { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const clientIP = req.ip || req.socket.remoteAddress || "unknown"; - log.info( - `cannot start public game ${game.id}, game is public, ip: ${ipAnonymize(clientIP)}`, - ); - return; - } - game.start(); - res.status(200).json({ success: true }); - }), - ); - - app.put( - "/api/game/:id", - gatekeeper.httpHandler(LimiterType.Put, async (req, res) => { - const result = GameInputSchema.safeParse(req.body); - if (!result.success) { - const error = z.prettifyError(result.error); - return res.status(400).json({ error }); - } - const config = result.data; - // TODO: only update public game if from local host - const lobbyID = req.params.id; - if (config.gameType === GameType.Public) { - log.info(`cannot update game ${lobbyID} to public`); - return res.status(400).json({ error: "Cannot update public game" }); - } - const game = gm.game(lobbyID); - if (!game) { - return res.status(400).json({ error: "Game not found" }); - } - if (game.isPublic()) { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const clientIP = req.ip || req.socket.remoteAddress || "unknown"; - log.warn( - `cannot update public game ${game.id}, ip: ${ipAnonymize(clientIP)}`, - ); - return res.status(400).json({ error: "Cannot update public game" }); - } - if (game.hasStarted()) { - log.warn(`cannot update game ${game.id} after it has started`); - return res - .status(400) - .json({ error: "Cannot update game after it has started" }); - } - game.updateGameConfig(config); - res.status(200).json({ success: true }); - }), - ); + app.post("/api/start_game/:id", async (req, res) => { + log.info(`starting private lobby with id ${req.params.id}`); + const game = gm.game(req.params.id); + if (!game) { + return; + } + if (game.isPublic()) { + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const clientIP = req.ip || req.socket.remoteAddress || "unknown"; + log.info( + `cannot start public game ${game.id}, game is public, ip: ${ipAnonymize(clientIP)}`, + ); + return; + } + game.start(); + res.status(200).json({ success: true }); + }); - app.get( - "/api/game/:id/exists", - gatekeeper.httpHandler(LimiterType.Get, async (req, res) => { - const lobbyId = req.params.id; - res.json({ - exists: gm.game(lobbyId) !== null, - }); - }), - ); + app.put("/api/game/:id", async (req, res) => { + const result = GameInputSchema.safeParse(req.body); + if (!result.success) { + const error = z.prettifyError(result.error); + return res.status(400).json({ error }); + } + const config = result.data; + // TODO: only update public game if from local host + const lobbyID = req.params.id; + if (config.gameType === GameType.Public) { + log.info(`cannot update game ${lobbyID} to public`); + return res.status(400).json({ error: "Cannot update public game" }); + } + const game = gm.game(lobbyID); + if (!game) { + return res.status(400).json({ error: "Game not found" }); + } + if (game.isPublic()) { + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const clientIP = req.ip || req.socket.remoteAddress || "unknown"; + log.warn( + `cannot update public game ${game.id}, ip: ${ipAnonymize(clientIP)}`, + ); + return res.status(400).json({ error: "Cannot update public game" }); + } + if (game.hasStarted()) { + log.warn(`cannot update game ${game.id} after it has started`); + return res + .status(400) + .json({ error: "Cannot update game after it has started" }); + } + game.updateGameConfig(config); + res.status(200).json({ success: true }); + }); - app.get( - "/api/game/:id", - gatekeeper.httpHandler(LimiterType.Get, async (req, res) => { - const game = gm.game(req.params.id); - if (game === null) { - log.info(`lobby ${req.params.id} not found`); - return res.status(404).json({ error: "Game not found" }); - } - res.json(game.gameInfo()); - }), - ); + app.get("/api/game/:id/exists", async (req, res) => { + const lobbyId = req.params.id; + res.json({ + exists: gm.game(lobbyId) !== null, + }); + }); - app.post( - "/api/lobby/:id/messages", - gatekeeper.httpHandler(LimiterType.Post, async (req, res) => { - const lobbyId = req.params.id; - log.info(`Received lobby message POST for lobby ${lobbyId}`, { - body: req.body, - }); - const game = gm.game(lobbyId); + app.get("/api/game/:id", async (req, res) => { + const game = gm.game(req.params.id); + if (game === null) { + log.info(`lobby ${req.params.id} not found`); + return res.status(404).json({ error: "Game not found" }); + } + res.json(game.gameInfo()); + }); - if (!game) { - log.info(`lobby ${lobbyId} not found for message`); - return res.status(404).json({ error: "Game not found" }); - } + app.post("/api/lobby/:id/messages", async (req, res) => { + const lobbyId = req.params.id; + log.info(`Received lobby message POST for lobby ${lobbyId}`, { + body: req.body, + }); + const game = gm.game(lobbyId); - // Validate request body - const MessageSchema = z.object({ - clientID: ID, - username: z.string().min(1).max(50), - text: z.string().max(300), - }); + if (!game) { + log.info(`lobby ${lobbyId} not found for message`); + return res.status(404).json({ error: "Game not found" }); + } - const result = MessageSchema.safeParse(req.body); - if (!result.success) { - const error = z.prettifyError(result.error); - log.warn(`Invalid lobby message body`, { error }); - return res.status(400).json({ error }); - } + // Validate request body + const MessageSchema = z.object({ + clientID: ID, + username: z.string().min(1).max(50), + text: z.string().max(300), + }); - const { clientID, username, text } = result.data; + const result = MessageSchema.safeParse(req.body); + if (!result.success) { + const error = z.prettifyError(result.error); + log.warn(`Invalid lobby message body`, { error }); + return res.status(400).json({ error }); + } - // Add the message (GameServer will validate chat is enabled) - log.info(`Adding lobby message`, { lobbyId, clientID, username, text }); - game.addLobbyMessage(clientID, username, text); + const { clientID, username, text } = result.data; - res.status(200).json({ success: true }); - }), - ); + // Add the message (GameServer will validate chat is enabled) + log.info(`Adding lobby message`, { lobbyId, clientID, username, text }); + game.addLobbyMessage(clientID, username, text); - app.get( - "/api/archived_game/:id", - gatekeeper.httpHandler(LimiterType.Get, async (req, res) => { - const gameRecord = await readGameRecord(req.params.id); + res.status(200).json({ success: true }); + }); - if (!gameRecord) { - return res.status(404).json({ - success: false, - error: "Game not found", - exists: false, - }); - } + app.get("/api/archived_game/:id", async (req, res) => { + const gameRecord = await readGameRecord(req.params.id); - if ( - config.env() !== GameEnv.Dev && - gameRecord.gitCommit !== config.gitCommit() - ) { - log.warn( - `git commit mismatch for game ${req.params.id}, expected ${config.gitCommit()}, got ${gameRecord.gitCommit}`, - ); - return res.status(409).json({ - success: false, - error: "Version mismatch", - exists: true, - details: { - expectedCommit: config.gitCommit(), - actualCommit: gameRecord.gitCommit, - }, - }); - } + if (!gameRecord) { + return res.status(404).json({ + success: false, + error: "Game not found", + exists: false, + }); + } - return res.status(200).json({ - success: true, + if ( + config.env() !== GameEnv.Dev && + gameRecord.gitCommit !== config.gitCommit() + ) { + log.warn( + `git commit mismatch for game ${req.params.id}, expected ${config.gitCommit()}, got ${gameRecord.gitCommit}`, + ); + return res.status(409).json({ + success: false, + error: "Version mismatch", exists: true, - gameRecord: gameRecord, + details: { + expectedCommit: config.gitCommit(), + actualCommit: gameRecord.gitCommit, + }, }); - }), - ); + } - app.post( - "/api/archive_singleplayer_game", - gatekeeper.httpHandler(LimiterType.Post, async (req, res) => { - const result = GameRecordSchema.safeParse(req.body); - if (!result.success) { - const error = z.prettifyError(result.error); - log.info(error); - return res.status(400).json({ error }); - } + return res.status(200).json({ + success: true, + exists: true, + gameRecord: gameRecord, + }); + }); - const gameRecord: GameRecord = result.data; - archive(gameRecord); - res.json({ - success: true, - }); - }), - ); + app.post("/api/archive_singleplayer_game", async (req, res) => { + const result = GameRecordSchema.safeParse(req.body); + if (!result.success) { + const error = z.prettifyError(result.error); + log.info(error); + return res.status(400).json({ error }); + } - app.post( - "/api/kick_player/:gameID/:clientID", - gatekeeper.httpHandler(LimiterType.Post, async (req, res) => { - if (req.headers[config.adminHeader()] !== config.adminToken()) { - res.status(401).send("Unauthorized"); - return; - } + const gameRecord: GameRecord = result.data; + archive(gameRecord); + res.json({ + success: true, + }); + }); - const { gameID, clientID } = req.params; + app.post("/api/kick_player/:gameID/:clientID", async (req, res) => { + if (req.headers[config.adminHeader()] !== config.adminToken()) { + res.status(401).send("Unauthorized"); + return; + } - const game = gm.game(gameID); - if (!game) { - res.status(404).send("Game not found"); - return; - } + const { gameID, clientID } = req.params; - game.kickClient(clientID); - res.status(200).send("Player kicked successfully"); - }), - ); + const game = gm.game(gameID); + if (!game) { + res.status(404).send("Game not found"); + return; + } + + game.kickClient(clientID); + res.status(200).send("Player kicked successfully"); + }); // Rankings API endpoints - app.get( - "/api/rankings", - gatekeeper.httpHandler(LimiterType.Get, async (req, res) => { - const limit = Math.min(parseInt(req.query.limit as string) || 100, 500); - const leaderboard = await rankingService.getLeaderboard(limit); - res.json({ - leaderboard, - totalPlayers: rankingService.getTotalPlayers(), - }); - }), - ); + app.get("/api/rankings", async (req, res) => { + const limit = Math.min(parseInt(req.query.limit as string) || 100, 500); + const leaderboard = await rankingService.getLeaderboard(limit); + res.json({ + leaderboard, + totalPlayers: rankingService.getTotalPlayers(), + }); + }); - app.get( - "/api/rankings/player/:persistentID", - gatekeeper.httpHandler(LimiterType.Get, async (req, res) => { - const { persistentID } = req.params; - const ranking = rankingService.getPlayerRanking(persistentID); - if (!ranking) { - return res.status(404).json({ error: "Player not found" }); - } - const position = rankingService.getPlayerPosition(persistentID); - res.json({ - ranking, - position, - totalPlayers: rankingService.getTotalPlayers(), - }); - }), - ); + app.get("/api/rankings/player/:persistentID", async (req, res) => { + const { persistentID } = req.params; + const ranking = rankingService.getPlayerRanking(persistentID); + if (!ranking) { + return res.status(404).json({ error: "Player not found" }); + } + const position = rankingService.getPlayerPosition(persistentID); + res.json({ + ranking, + position, + totalPlayers: rankingService.getTotalPlayers(), + }); + }); - app.get( - "/api/rankings/clans", - gatekeeper.httpHandler(LimiterType.Get, async (req, res) => { - const limit = Math.min(parseInt(req.query.limit as string) || 100, 500); - const leaderboard = await rankingService.getClanLeaderboard(limit); - res.json({ - leaderboard, - totalClans: rankingService.getTotalClans(), - }); - }), - ); + app.get("/api/rankings/clans", async (req, res) => { + const limit = Math.min(parseInt(req.query.limit as string) || 100, 500); + const leaderboard = await rankingService.getClanLeaderboard(limit); + res.json({ + leaderboard, + totalClans: rankingService.getTotalClans(), + }); + }); - app.get( - "/api/rankings/clan/:clanTag", - gatekeeper.httpHandler(LimiterType.Get, async (req, res) => { - const { clanTag } = req.params; - const ranking = rankingService.getClanRanking(clanTag); - if (!ranking) { - return res.status(404).json({ error: "Clan not found" }); - } - const position = rankingService.getClanPosition(clanTag); - res.json({ - ranking, - position, - totalClans: rankingService.getTotalClans(), - }); - }), - ); + app.get("/api/rankings/clan/:clanTag", async (req, res) => { + const { clanTag } = req.params; + const ranking = rankingService.getClanRanking(clanTag); + if (!ranking) { + return res.status(404).json({ error: "Clan not found" }); + } + const position = rankingService.getClanPosition(clanTag); + res.json({ + ranking, + position, + totalClans: rankingService.getTotalClans(), + }); + }); - app.get( - "/api/rankings/hall-of-fame", - gatekeeper.httpHandler(LimiterType.Get, async (req, res) => { - const hallOfFame = rankingService.getHallOfFame(); - res.json({ hallOfFame }); - }), - ); + app.get("/api/rankings/hall-of-fame", async (req, res) => { + const hallOfFame = rankingService.getHallOfFame(); + res.json({ hallOfFame }); + }); // WebSocket handling wss.on("connection", (ws: WebSocket, req) => { - ws.on( - "message", - gatekeeper.wsHandler(req, async (message: string) => { - const forwarded = req.headers["x-forwarded-for"]; - const ip = Array.isArray(forwarded) - ? forwarded[0] - : // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - forwarded || req.socket.remoteAddress || "unknown"; - - try { - // Parse and handle client messages - const parsed = ClientMessageSchema.safeParse( - JSON.parse(message.toString()), + ws.on("message", async (message: string) => { + const forwarded = req.headers["x-forwarded-for"]; + const ip = Array.isArray(forwarded) + ? forwarded[0] + : // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + forwarded || req.socket.remoteAddress || "unknown"; + + try { + // Parse and handle client messages + const parsed = ClientMessageSchema.safeParse( + JSON.parse(message.toString()), + ); + if (!parsed.success) { + const error = z.prettifyError(parsed.error); + log.warn("Error parsing client message", error); + ws.send( + JSON.stringify({ + type: "error", + error: error.toString(), + } satisfies ServerErrorMessage), ); - if (!parsed.success) { - const error = z.prettifyError(parsed.error); - log.warn("Error parsing client message", error); - ws.send( - JSON.stringify({ - type: "error", - error: error.toString(), - } satisfies ServerErrorMessage), - ); - ws.close(1002, "ClientJoinMessageSchema"); - return; - } - const clientMsg = parsed.data; + ws.close(1002, "ClientJoinMessageSchema"); + return; + } + const clientMsg = parsed.data; + + if (clientMsg.type === "ping") { + // Ignore ping + return; + } else if (clientMsg.type !== "join") { + log.warn(`Invalid message before join: ${JSON.stringify(clientMsg)}`); + return; + } - if (clientMsg.type === "ping") { - // Ignore ping - return; - } else if (clientMsg.type !== "join") { - log.warn( - `Invalid message before join: ${JSON.stringify(clientMsg)}`, - ); - return; - } + // Verify this worker should handle this game + const expectedWorkerId = config.workerIndex(clientMsg.gameID); + if (expectedWorkerId !== workerId) { + log.warn( + `Worker mismatch: Game ${clientMsg.gameID} should be on worker ${expectedWorkerId}, but this is worker ${workerId}`, + ); + return; + } - // Verify this worker should handle this game - const expectedWorkerId = config.workerIndex(clientMsg.gameID); - if (expectedWorkerId !== workerId) { - log.warn( - `Worker mismatch: Game ${clientMsg.gameID} should be on worker ${expectedWorkerId}, but this is worker ${workerId}`, - ); - return; - } + const result = await verifyClientToken(clientMsg.token, config); + if (result === false) { + log.warn("Unauthorized: Invalid token"); + ws.close(1002, "Unauthorized"); + return; + } + const { persistentId, claims } = result; - const result = await verifyClientToken(clientMsg.token, config); + let roles: string[] | undefined; + + if (claims === null) { + // TODO: Verify that the persistendId is is not a registered player + } else { + // Verify token and get player permissions + const result = await getUserMe(clientMsg.token, config); if (result === false) { - log.warn("Unauthorized: Invalid token"); + log.warn("Unauthorized: Invalid session"); ws.close(1002, "Unauthorized"); return; } - const { persistentId, claims } = result; - - let roles: string[] | undefined; - - if (claims === null) { - // TODO: Verify that the persistendId is is not a registered player - } else { - // Verify token and get player permissions - const result = await getUserMe(clientMsg.token, config); - if (result === false) { - log.warn("Unauthorized: Invalid session"); - ws.close(1002, "Unauthorized"); - return; - } - roles = result.player.roles; - } + roles = result.player.roles; + } - // Create client and add to game - const client = new Client( - clientMsg.clientID, - persistentId, - claims, - roles, - ip, - clientMsg.username, - ws, - clientMsg.flag, - ); + // Create client and add to game + const client = new Client( + clientMsg.clientID, + persistentId, + claims, + roles, + ip, + clientMsg.username, + ws, + clientMsg.flag, + ); - const wasFound = gm.addClient( - client, - clientMsg.gameID, - clientMsg.lastTurn, - ); + const wasFound = gm.addClient( + client, + clientMsg.gameID, + clientMsg.lastTurn, + ); - if (!wasFound) { - log.info( - `game ${clientMsg.gameID} not found on worker ${workerId}`, - ); - // Handle game not found case - } - } catch (error) { - ws.close(1011, "Internal server error"); - log.warn( - `error handling websocket message for ${ipAnonymize(ip)}: ${error}`.substring( - 0, - 250, - ), - ); + if (!wasFound) { + log.info(`game ${clientMsg.gameID} not found on worker ${workerId}`); + // Handle game not found case } - }), - ); + } catch (error) { + ws.close(1011, "Internal server error"); + log.warn( + `error handling websocket message for ${ipAnonymize(ip)}: ${error}`.substring( + 0, + 250, + ), + ); + } + }); ws.on("error", (error: Error) => { if ((error as any).code === "WS_ERR_UNEXPECTED_RSV_1") { diff --git a/src/server/gatekeeper b/src/server/gatekeeper deleted file mode 160000 index f5f7e6362..000000000 --- a/src/server/gatekeeper +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f5f7e6362f54fc0d7d7b1d74e60a62f83fa8fb3f From deb21d28f9e7b64bce0170a5675e39071343af84 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 01:36:22 +0100 Subject: [PATCH 02/34] pseudorandom.ts minor fixes (#2046) in src/core/pseudorandom.ts a helper function of nextint is defined but never used. instead, this.rng is used. those are replaced. also, shuffleArray originally would self-shuffle at i=0 for the conditional being i>=0, fixed to 0. - [X] I have added screenshots for all UI updates - [X] I process any text displayed to the user through translateText() and I've added it to the en.json file - [X] I have added relevant tests to the test directory - [X] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced regression is found: jack_45183 --- src/core/PseudoRandom.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/PseudoRandom.ts b/src/core/PseudoRandom.ts index 156499e42..c34b4321e 100644 --- a/src/core/PseudoRandom.ts +++ b/src/core/PseudoRandom.ts @@ -36,7 +36,7 @@ export class PseudoRandom { if (arr.length === 0) { throw new Error("array must not be empty"); } - return arr[Math.floor(this.rng() * arr.length)]; + return arr[this.nextInt(0, arr.length)]; } /** @@ -64,14 +64,14 @@ export class PseudoRandom { // Returns true with probability 1/odds. chance(odds: number): boolean { - return Math.floor(this.rng() * odds) === 0; + return this.nextInt(0, odds) === 0; } // Returns a shuffled copy of the array using Fisher-Yates algorithm. shuffleArray(array: T[]): T[] { const result = [...array]; - for (let i = result.length - 1; i >= 0; i--) { - const j = Math.floor(this.rng() * (i + 1)); + for (let i = result.length - 1; i > 0; i--) { + const j = this.nextInt(0, i + 1); [result[i], result[j]] = [result[j], result[i]]; } return result; From c9132c5bbdc67cbb510507c1424a5477a6abfd3d Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 01:37:35 +0100 Subject: [PATCH 03/34] Player names are hidden when zoomed in too much (#2043) Player names are hidden, except small sized fonts, when zoomed in too much(near max), improving user experience by allowing users to see structures clearly without the obstruction of text - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file(no need) - [x] I have added relevant tests to the test directory(n/a) - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced [video](https://streamable.com/e/mlrfqo?) regression is found: _federalagent --- src/client/graphics/layers/NameLayer.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/client/graphics/layers/NameLayer.ts b/src/client/graphics/layers/NameLayer.ts index 138eecfa5..bd93f8a10 100644 --- a/src/client/graphics/layers/NameLayer.ts +++ b/src/client/graphics/layers/NameLayer.ts @@ -153,8 +153,14 @@ export class NameLayer implements Layer { const isOnScreen = render.location ? this.transformHandler.isOnScreen(render.location) : false; + const maxZoomScale = 17; - if (!this.isVisible || size < 7 || !isOnScreen) { + if ( + !this.isVisible || + size < 7 || + (this.transformHandler.scale > maxZoomScale && size > 100) || + !isOnScreen + ) { render.element.style.display = "none"; } else { render.element.style.display = "flex"; From e50ad979a02fa0f900138033bc0f81befdea6b7b Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 01:48:16 +0100 Subject: [PATCH 04/34] Add test for nation name length and fix names exceeding 27 chars (#2122) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added tests/NationNameLength.test.ts to enforce nation name length ≤27. Updated manifest.json files in resources/maps with shorter names to pass the test. This fix ensures that names will no longer be truncated Examples of country names that are too long and have their endings cut off スクリーンショット 2025-10-01 10 51 40 - Replaced overly long country names with shorter common forms: - "The Democratic Republic of the Congo" -> "DR Congo" - "Democratic Republic of the Congo" -> "DR Congo" - "Lao People's Democratic Republic" -> "Laos" - "Federated States of Micronesia" -> "Micronesia" - "People's Democratic Republic of Algeria" -> "Algeria" - "People's Republic of Algeria'" -> "Algeria" - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced regression is found: aotumuri --- resources/maps/Africa/Africa.json | 2 +- resources/maps/Europe/Europe.json | 2 +- .../GatewayToTheAtlantic.json | 2 +- resources/maps/Oceania/Oceania.json | 4 +- resources/maps/WorldMap/WorldMap.json | 2 +- tests/NationNameLength.test.ts | 55 +++++++++++++++++++ 6 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 tests/NationNameLength.test.ts diff --git a/resources/maps/Africa/Africa.json b/resources/maps/Africa/Africa.json index 0866bcc94..02ae426db 100644 --- a/resources/maps/Africa/Africa.json +++ b/resources/maps/Africa/Africa.json @@ -89,7 +89,7 @@ }, { "coordinates": [1094, 1093], - "name": "Democratic Republic of the Congo", + "name": "DR Congo", "strength": 2, "flag": "cd" }, diff --git a/resources/maps/Europe/Europe.json b/resources/maps/Europe/Europe.json index 33ff48987..931faa8d3 100644 --- a/resources/maps/Europe/Europe.json +++ b/resources/maps/Europe/Europe.json @@ -155,7 +155,7 @@ }, { "coordinates": [517, 1483], - "name": "People's Democratic Republic of Algeria", + "name": "Algeria", "strength": 1, "flag": "dz" }, diff --git a/resources/maps/GatewayToTheAtlantic/GatewayToTheAtlantic.json b/resources/maps/GatewayToTheAtlantic/GatewayToTheAtlantic.json index 0f90f7fb3..425aab631 100644 --- a/resources/maps/GatewayToTheAtlantic/GatewayToTheAtlantic.json +++ b/resources/maps/GatewayToTheAtlantic/GatewayToTheAtlantic.json @@ -71,7 +71,7 @@ }, { "coordinates": [1609, 1837], - "name": "People's Republic of Algeria'", + "name": "Algeria", "strength": 2, "flag": "dz" }, diff --git a/resources/maps/Oceania/Oceania.json b/resources/maps/Oceania/Oceania.json index 483bb6454..d534f21f0 100644 --- a/resources/maps/Oceania/Oceania.json +++ b/resources/maps/Oceania/Oceania.json @@ -71,7 +71,7 @@ }, { "coordinates": [143, 37], - "name": "Lao People's Democratic Republic", + "name": "Lao PDR", "strength": 1, "flag": "la" }, @@ -101,7 +101,7 @@ }, { "coordinates": [834, 215], - "name": "Federated States of Micronesia", + "name": "Micronesia", "strength": 1, "flag": "fm" }, diff --git a/resources/maps/WorldMap/WorldMap.json b/resources/maps/WorldMap/WorldMap.json index e195c7309..5b0e0dbdd 100644 --- a/resources/maps/WorldMap/WorldMap.json +++ b/resources/maps/WorldMap/WorldMap.json @@ -239,7 +239,7 @@ }, { "coordinates": [1074, 508], - "name": "The Democratic Republic of the Congo", + "name": "DR Congo", "strength": 1, "flag": "cd" }, diff --git a/tests/NationNameLength.test.ts b/tests/NationNameLength.test.ts new file mode 100644 index 000000000..5bfc4960b --- /dev/null +++ b/tests/NationNameLength.test.ts @@ -0,0 +1,55 @@ +import fs from "fs"; +import { globSync } from "glob"; +import path from "path"; + +type Nation = { + name?: string; +}; + +type Manifest = { + nations?: Nation[]; +}; + +describe("Map manifests: nation name length constraint", () => { + test("All nations' names must be ≤ 27 characters", () => { + const manifestPaths = globSync( + path.resolve(process.cwd(), "resources/maps/**/manifest.json"), + ); + + expect(manifestPaths.length).toBeGreaterThan(0); + + const violations: string[] = []; + + for (const manifestPath of manifestPaths) { + try { + const raw = fs.readFileSync(manifestPath, "utf8"); + const manifest = JSON.parse(raw) as Manifest; + + (manifest.nations ?? []).forEach((nation, idx) => { + const name = nation?.name; + if (typeof name !== "string") { + violations.push( + `${manifestPath} -> nations[${idx}].name is not a string`, + ); + return; + } + if (name.length > 27) { + violations.push( + `${manifestPath} -> nations[${idx}].name "${name}" has length ${name.length} (> 27)`, + ); + } + }); + } catch (err) { + violations.push( + `Failed to parse ${manifestPath}: ${(err as Error).message}`, + ); + } + } + + if (violations.length > 0) { + throw new Error( + "Nation name length violations:\n" + violations.join("\n"), + ); + } + }); +}); From 91fa6fbbf518a7bf2048d3d6f59a1e5412c01aa6 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 01:50:25 +0100 Subject: [PATCH 05/34] refactor: simplify manifest path resolution in nation name length test --- tests/NationNameLength.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/NationNameLength.test.ts b/tests/NationNameLength.test.ts index 5bfc4960b..66216125f 100644 --- a/tests/NationNameLength.test.ts +++ b/tests/NationNameLength.test.ts @@ -1,6 +1,5 @@ import fs from "fs"; import { globSync } from "glob"; -import path from "path"; type Nation = { name?: string; @@ -12,9 +11,10 @@ type Manifest = { describe("Map manifests: nation name length constraint", () => { test("All nations' names must be ≤ 27 characters", () => { - const manifestPaths = globSync( - path.resolve(process.cwd(), "resources/maps/**/manifest.json"), - ); + const manifestPaths = globSync("resources/maps/*/*.json", { + cwd: process.cwd(), + absolute: true, + }); expect(manifestPaths.length).toBeGreaterThan(0); From 506c1b82a64f16b3ca029c0806109203d5c851ac Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 01:53:24 +0100 Subject: [PATCH 06/34] feat: add spectate option and track win state in WinModal --- resources/lang/en.json | 1 + src/client/graphics/layers/WinModal.ts | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/resources/lang/en.json b/resources/lang/en.json index 76f768c9a..67fce0104 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -545,6 +545,7 @@ "other_won": "{player} has won!", "exit": "Exit Game", "keep": "Keep Playing", + "spectate": "Spectate", "wishlist": "Wishlist on Steam!", "save_replay": "Save Replay", "encoding_replay": "Encoding replay...", diff --git a/src/client/graphics/layers/WinModal.ts b/src/client/graphics/layers/WinModal.ts index e783a1dd1..68224fab8 100644 --- a/src/client/graphics/layers/WinModal.ts +++ b/src/client/graphics/layers/WinModal.ts @@ -36,6 +36,9 @@ export class WinModal extends LitElement implements Layer { @state() private showReplayOptions: boolean = false; + @state() + private isWin = false; + @state() private encodeError: string = ""; @@ -246,7 +249,9 @@ export class WinModal extends LitElement implements Layer { ${translateText("win_modal.exit")} @@ -343,10 +348,12 @@ export class WinModal extends LitElement implements Layer { this.eventBus.emit(new SendWinnerEvent(wu.winner, wu.allPlayersStats)); if (wu.winner[1] === this.game.myPlayer()?.team()) { this._title = translateText("win_modal.your_team"); + this.isWin = true; } else { this._title = translateText("win_modal.other_team", { team: wu.winner[1], }); + this.isWin = false; } this.show(); } else { @@ -363,10 +370,12 @@ export class WinModal extends LitElement implements Layer { winnerClient === this.game.myPlayer()?.clientID() ) { this._title = translateText("win_modal.you_won"); + this.isWin = true; } else { this._title = translateText("win_modal.other_won", { player: winner.name(), }); + this.isWin = false; } this.show(); } From 4704e6f46eb2d75bcbf9001bb890f95f050ea037 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 01:55:22 +0100 Subject: [PATCH 07/34] refactor: streamline SAM Launcher range calculation by removing localStorage dependency --- .../graphics/layers/RangeOverlayLayer.ts | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/client/graphics/layers/RangeOverlayLayer.ts b/src/client/graphics/layers/RangeOverlayLayer.ts index 6172bb2a8..97f4110f4 100644 --- a/src/client/graphics/layers/RangeOverlayLayer.ts +++ b/src/client/graphics/layers/RangeOverlayLayer.ts @@ -425,25 +425,13 @@ export class RangeOverlayLayer implements Layer { if (type === UnitType.DefensePost) return this.game.config().defensePostRange(); if (type === UnitType.SAMLauncher) { - // Get the selected build level from localStorage (same as BuildMenu) - let desiredLevel = 1; - try { - const raw = localStorage.getItem("buildSettings.levels"); - if (raw) { - const obj = JSON.parse(raw); - const val = obj?.[String(type)]; - if (typeof val === "number" && val >= 1) { - desiredLevel = Math.min(3, val); // SAM max level is 3 - } - } - } catch (_) { - // Fall back to level 1 - } - const base = this.game.config().defaultSamRange(); - if (desiredLevel <= 1) return base; + const myPlayer = this.game.myPlayer(); + if (!myPlayer) return base; + const lvl = playerMaxStructureTechLevel(myPlayer, UnitType.SAMLauncher); + if (lvl <= 1) return base; const bonus = this.game.config().samRangeUpgradePercent(); - const factor = Math.pow(1 + bonus, desiredLevel - 1); + const factor = Math.pow(1 + bonus, lvl - 1); return Math.round(base * factor); } if (type === UnitType.Airfield) { From 1977809c3b681c64d8fd1876ae1bfb3de9103177 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 01:59:30 +0100 Subject: [PATCH 08/34] refactor: remove unused player focus logic and clean up related methods --- src/client/ClientGameRunner.ts | 46 ------------------------- src/client/Main.ts | 6 ---- src/client/graphics/TransformHandler.ts | 1 - src/core/game/GameView.ts | 4 --- 4 files changed, 57 deletions(-) diff --git a/src/client/ClientGameRunner.ts b/src/client/ClientGameRunner.ts index fbd598873..18877630e 100644 --- a/src/client/ClientGameRunner.ts +++ b/src/client/ClientGameRunner.ts @@ -583,13 +583,6 @@ export class ClientGameRunner { } else if (this.canBoatAttack(actions, tile)) { this.sendBoatAttackIntent(tile); } - - const owner = this.gameView.owner(tile); - if (owner.isPlayer()) { - this.gameView.setFocusedPlayer(owner as PlayerView); - } else { - this.gameView.setFocusedPlayer(null); - } }); } @@ -695,45 +688,6 @@ export class ClientGameRunner { private onMouseMove(event: MouseMoveEvent) { this.lastMousePosition = { x: event.x, y: event.y }; - this.checkTileUnderCursor(); - } - - private checkTileUnderCursor() { - if (!this.lastMousePosition || !this.renderer.transformHandler) return; - - const cell = this.renderer.transformHandler.screenToWorldCoordinates( - this.lastMousePosition.x, - this.lastMousePosition.y, - ); - - if (!cell || !this.gameView.isValidCoord(cell.x, cell.y)) { - return; - } - - const tile = this.gameView.ref(cell.x, cell.y); - - if (this.gameView.isLand(tile)) { - const owner = this.gameView.owner(tile); - if (owner.isPlayer()) { - this.gameView.setFocusedPlayer(owner as PlayerView); - } else { - this.gameView.setFocusedPlayer(null); - } - } else { - const units = this.gameView - .nearbyUnits(tile, 50, [ - UnitType.Warship, - UnitType.TradeShip, - UnitType.TransportShip, - ]) - .sort((a, b) => a.distSquared - b.distSquared); - - if (units.length > 0) { - this.gameView.setFocusedPlayer(units[0].unit.owner() as PlayerView); - } else { - this.gameView.setFocusedPlayer(null); - } - } } private onConnectionCheck() { diff --git a/src/client/Main.ts b/src/client/Main.ts index 29f6598c2..03f4553c5 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -279,12 +279,6 @@ class Client { } }); - // const ctModal = document.querySelector("chat-modal") as ChatModal; - // ctModal instanceof ChatModal; - // document.getElementById("chat-button").addEventListener("click", () => { - // ctModal.open(); - // }); - const hlpModal = document.querySelector("help-modal") as HelpModal; hlpModal instanceof HelpModal; const helpButton = document.getElementById("help-button"); diff --git a/src/client/graphics/TransformHandler.ts b/src/client/graphics/TransformHandler.ts index 47b569d5a..a493b64fc 100644 --- a/src/client/graphics/TransformHandler.ts +++ b/src/client/graphics/TransformHandler.ts @@ -158,7 +158,6 @@ export class TransformHandler { } onGoToPlayer(event: GoToPlayerEvent) { - this.game.setFocusedPlayer(event.player); this.clearTarget(); const nameLocation = event.player.nameLocation(); if (!nameLocation) { diff --git a/src/core/game/GameView.ts b/src/core/game/GameView.ts index eb5547b2f..d24c41ecf 100644 --- a/src/core/game/GameView.ts +++ b/src/core/game/GameView.ts @@ -515,7 +515,6 @@ export class GameView implements GameMap { private updatedTiles: TileRef[] = []; private _myPlayer: PlayerView | null = null; - private _focusedPlayer: PlayerView | null = null; private _alliances: AllianceViewData[] = []; // Submarine periodic pings removed; ghosts are used instead private _submarineGhosts: Map< @@ -950,9 +949,6 @@ export class GameView implements GameMap { // TODO: renable when performance issues are fixed. return this.myPlayer(); } - setFocusedPlayer(player: PlayerView | null): void { - this._focusedPlayer = player; - } // isUnitPeriodicallyVisible removed with ping feature } From c6de46d649873909c38782ac0d59ca83fe225619 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:00:59 +0100 Subject: [PATCH 09/34] bugfix: check if modal is not null before checking if it contains isModalOpen --- src/client/Main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/Main.ts b/src/client/Main.ts index 03f4553c5..941f4d05a 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -562,7 +562,7 @@ class Client { }; if (modal?.close) { modal.close(); - } else if ("isModalOpen" in modal) { + } else if (modal && "isModalOpen" in modal) { modal.isModalOpen = false; } }); From 4742176d7dc9e24b1002268247b79b2aa4b115ee Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:03:14 +0100 Subject: [PATCH 10/34] refactor: rename canBoatAttack to canAutoBoat and simplify its logic --- src/client/ClientGameRunner.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/client/ClientGameRunner.ts b/src/client/ClientGameRunner.ts index 18877630e..715c8e2d8 100644 --- a/src/client/ClientGameRunner.ts +++ b/src/client/ClientGameRunner.ts @@ -580,7 +580,7 @@ export class ClientGameRunner { this.myPlayer.troops() * this.renderer.uiState.attackRatio, ), ); - } else if (this.canBoatAttack(actions, tile)) { + } else if (this.canAutoBoat(actions, tile)) { this.sendBoatAttackIntent(tile); } }); @@ -599,7 +599,7 @@ export class ClientGameRunner { } this.myPlayer.actions(tile).then((actions) => { - if (this.canBoatAttack(actions, tile)) { + if (this.canBoatAttack(actions) !== false) { this.sendBoatAttackIntent(tile); } }); @@ -647,7 +647,7 @@ export class ClientGameRunner { return this.gameView.ref(cell.x, cell.y); } - private canBoatAttack(actions: PlayerActions, tile: TileRef): boolean { + private canBoatAttack(actions: PlayerActions): false | TileRef { const bu = actions.buildableUnits.find( (bu) => bu.type === UnitType.TransportShip, ); @@ -655,7 +655,7 @@ export class ClientGameRunner { console.warn(`no transport ship buildable units`); return false; } - return bu.canBuild !== false && this.gameView.isLand(tile); + return bu.canBuild; } private sendBoatAttackIntent(tile: TileRef) { @@ -674,16 +674,20 @@ export class ClientGameRunner { }); } - private shouldBoat(tile: TileRef, src: TileRef) { + private canAutoBoat(actions: PlayerActions, tile: TileRef): boolean { + if (!this.gameView.isLand(tile)) return false; + + const canBuild = this.canBoatAttack(actions); + if (canBuild === false) return false; + // TODO: Global enable flag // TODO: Global limit autoboat to nearby shore flag // if (!enableAutoBoat) return false; // if (!limitAutoBoatNear) return true; - const distanceSquared = this.gameView.euclideanDistSquared(tile, src); + const distanceSquared = this.gameView.euclideanDistSquared(tile, canBuild); const limit = 100; const limitSquared = limit * limit; - if (distanceSquared > limitSquared) return false; - return true; + return distanceSquared < limitSquared; } private onMouseMove(event: MouseMoveEvent) { From d5ec1dc72f40aac77f877b7fd7bf479fc41c7782 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:05:17 +0100 Subject: [PATCH 11/34] refactor: update pathfinding logic to use path index for tile retrieval --- src/core/pathfinding/PathFinding.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/pathfinding/PathFinding.ts b/src/core/pathfinding/PathFinding.ts index 2f20f17d5..44c4f3f52 100644 --- a/src/core/pathfinding/PathFinding.ts +++ b/src/core/pathfinding/PathFinding.ts @@ -162,6 +162,7 @@ export class PathFinder { private curr: TileRef | null = null; private dst: TileRef | null = null; private path: TileRef[] | null = null; + private path_idx: number = 0; private aStar: AStar; private computeFinished = true; @@ -203,6 +204,7 @@ export class PathFinder { return { type: PathFindResultType.PathNotFound }; } if (this.game.manhattanDist(curr, dst) < dist) { + this.path = null; return { type: PathFindResultType.Completed, node: curr }; } @@ -211,11 +213,12 @@ export class PathFinder { this.curr = curr; this.dst = dst; this.path = null; + this.path_idx = 0; this.aStar = this.newAStar(curr, dst); this.computeFinished = false; return this.nextTile(curr, dst); } else { - const tile = this.path?.shift(); + const tile = this.path?.[this.path_idx++]; if (tile === undefined) { // Path exhausted unexpectedly. If already within step distance, report completion. if (this.game.manhattanDist(curr, dst) < dist) { @@ -225,6 +228,7 @@ export class PathFinder { this.curr = curr; this.dst = dst; this.path = null; + this.path_idx = 0; this.aStar = this.newAStar(curr, dst); this.computeFinished = false; return this.nextTile(curr, dst); @@ -237,8 +241,9 @@ export class PathFinder { case PathFindResultType.Completed: this.computeFinished = true; this.path = this.aStar.reconstructPath(); - // Remove the start tile - this.path.shift(); + + // exclude first tile + this.path_idx = 1; // If the reconstructed path is empty, fall back to completion or path-not-found handling. if (!this.path || this.path.length === 0) { if (this.game.manhattanDist(curr, dst) < dist) { From 71833c354a9fafbc133170d2bb1d79627d1aeeb3 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:06:55 +0100 Subject: [PATCH 12/34] Fix socket log (#2369) Fix null socket crashing the log - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced regression is found: Mr.Box --- src/client/Transport.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/Transport.ts b/src/client/Transport.ts index e7ce1a71c..cd9dbdf8e 100644 --- a/src/client/Transport.ts +++ b/src/client/Transport.ts @@ -853,7 +853,7 @@ export class Transport { } else { console.log( "WebSocket is not open. Current state:", - this.socket!.readyState, + this.socket?.readyState, ); console.log("attempting reconnect"); } From ef5580a99cd99f5ff6a2eb5c38430bb465f13e51 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:08:13 +0100 Subject: [PATCH 13/34] fix(replay): change text to 'replay speed' when watching a replay #2357 (#2365) Before, the condition was "if it's not singleplayer", but replays are counted as singleplayer game for some reason (will need to fix the underlying issue) so it wasn't robust enough Now the condition is based on are we in replay or not,. Related to issue https://github.com/openfrontio/OpenFrontIO/issues/2357 I cannot get to replay games locally for some reason (client just throws an error that it cannot load the lobby), so I made sure that the singleplayer text did not change (at least no regression) cf screenshot: Screenshot 2025-11-02 at 17 46 57 - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced regression is found: sorikairo --- src/client/graphics/layers/ReplayPanel.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/graphics/layers/ReplayPanel.ts b/src/client/graphics/layers/ReplayPanel.ts index da53f125a..2830fec26 100644 --- a/src/client/graphics/layers/ReplayPanel.ts +++ b/src/client/graphics/layers/ReplayPanel.ts @@ -81,9 +81,9 @@ export class ReplayPanel extends LitElement implements Layer { style="color: var(--ui-text-accent)" translate="no" > - ${this._isSinglePlayer - ? translateText("replay_panel.game_speed") - : translateText("replay_panel.replay_speed")} + ${this.game?.config()?.isReplay() + ? translateText("replay_panel.replay_speed") + : translateText("replay_panel.game_speed")}
${options.map( From 00ecbcbf6adbace25554633e28fe21046ba6ad5f Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:17:29 +0100 Subject: [PATCH 14/34] refactor: update ClusterTraversalState to use Uint32Array and simplify cluster calculation logic --- src/core/execution/PlayerExecution.ts | 119 +++++++++++++++++--------- 1 file changed, 78 insertions(+), 41 deletions(-) diff --git a/src/core/execution/PlayerExecution.ts b/src/core/execution/PlayerExecution.ts index df4708905..93319f4c5 100644 --- a/src/core/execution/PlayerExecution.ts +++ b/src/core/execution/PlayerExecution.ts @@ -18,8 +18,8 @@ import { calculateBoundingBox, getMode, inscribed, simpleHash } from "../Util"; // Traversal state for cluster calculation to avoid repeated allocations interface ClusterTraversalState { - visited: Uint8Array; - currentGen: number; + visited: Uint32Array; + gen: number; } // Per-game traversal state used by calculateClusters() to avoid per-player buffers. @@ -519,9 +519,13 @@ export class PlayerExecution implements Execution { } const firstTile = cluster.values().next().value; - const filter = (_, t: TileRef): boolean => - this.mg?.ownerID(t) === this.player?.smallID(); - const tiles = this.mg.bfs(firstTile, filter); + const tiles = this.floodFillWithGen( + this.bumpGeneration(), + this.traversalState().visited, + [firstTile], + (tile, cb) => this.mg.forEachNeighbor(tile, cb), + (tile) => this.mg.ownerID(tile) === this.player.smallID(), + ); if (this.player.numTilesOwned() === tiles.size) { const gold = this.player.gold(); @@ -586,54 +590,87 @@ export class PlayerExecution implements Execution { } private calculateClusters(): Set[] { - const border = this.player.borderTiles(); + const borderTiles = this.player.borderTiles(); + if (borderTiles.size === 0) return []; + + const state = this.traversalState(); + const currentGen = this.bumpGeneration(); + const visited = state.visited; + const clusters: Set[] = []; - // Get or create traversal state for this game instance + for (const startTile of borderTiles) { + if (visited[startTile] === currentGen) continue; + + const cluster = this.floodFillWithGen( + currentGen, + visited, + [startTile], + (tile, cb) => this.mg.forEachNeighborWithDiag(tile, cb), + (tile) => borderTiles.has(tile), + ); + clusters.push(cluster); + } + return clusters; + } + + private traversalState(): ClusterTraversalState { + const totalTiles = this.mg.width() * this.mg.height(); let state = traversalStates.get(this.mg); - if (!state) { + if (!state || state.visited.length < totalTiles) { state = { - visited: new Uint8Array(this.mg.width() * this.mg.height()), - currentGen: 1, + visited: new Uint32Array(totalTiles), + gen: 0, }; traversalStates.set(this.mg, state); } + return state; + } - // Increment generation instead of clearing the array - state.currentGen++; - if (state.currentGen === 255) { - // Wraparound: reset to 1 and clear array - state.currentGen = 1; + private bumpGeneration(): number { + const state = this.traversalState(); + state.gen++; + if (state.gen === 0xffffffff) { state.visited.fill(0); + state.gen = 1; } + return state.gen; + } - const currentGen = state.currentGen; - const visited = state.visited; - - for (const tile of border) { - if (visited[tile] === currentGen) { - continue; - } - - const cluster = new Set(); - const stack: TileRef[] = [tile]; - visited[tile] = currentGen; - - while (stack.length > 0) { - const curr = stack.pop(); - if (curr === undefined) throw new Error("curr is undefined"); - cluster.add(curr); - - this.mg.forEachNeighborWithDiag(curr, (neighbor) => { - if (border.has(neighbor) && visited[neighbor] !== currentGen) { - stack.push(neighbor); - visited[neighbor] = currentGen; - } - }); - } - clusters.push(cluster); + private floodFillWithGen( + currentGen: number, + visited: Uint32Array, + startTiles: TileRef[], + neighborFn: (tile: TileRef, callback: (neighbor: TileRef) => void) => void, + includeFn: (tile: TileRef) => boolean, + ): Set { + const result = new Set(); + const stack: TileRef[] = []; + + for (const start of startTiles) { + if (visited[start] === currentGen) continue; + if (!includeFn(start)) continue; + visited[start] = currentGen; + result.add(start); + stack.push(start); + } + + while (stack.length > 0) { + const tile = stack.pop()!; + neighborFn(tile, (neighbor) => { + if (visited[neighbor] === currentGen) { + return; + } + if (!includeFn(neighbor)) { + return; + } + visited[neighbor] = currentGen; + result.add(neighbor); + stack.push(neighbor); + }); } - return clusters; + + return result; } owner(): Player { From 758ec301ebc781c894a050a435e8cf4ab38ebaf2 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:19:21 +0100 Subject: [PATCH 15/34] refactor: optimize cluster selection logic to find the largest cluster in a single scan --- src/core/execution/PlayerExecution.ts | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/core/execution/PlayerExecution.ts b/src/core/execution/PlayerExecution.ts index 93319f4c5..f88c5880f 100644 --- a/src/core/execution/PlayerExecution.ts +++ b/src/core/execution/PlayerExecution.ts @@ -402,16 +402,29 @@ export class PlayerExecution implements Execution { } const clusters = this.calculateClusters(); - clusters.sort((a, b) => b.size - a.size); + if (clusters.length === 0) return; + + // Find the largest cluster with a single linear scan (O(n)). + let largestIndex = 0; + let largestSize = clusters[0].size; + for (let i = 1; i < clusters.length; i++) { + const size = clusters[i].size; + if (size > largestSize) { + largestSize = size; + largestIndex = i; + } + } - const main = clusters.shift(); - if (main === undefined) throw new Error("No clusters"); - const surroundedBy = this.surroundedBySamePlayer(main); + const largestCluster = clusters[largestIndex]; + const surroundedBy = this.surroundedBySamePlayer(largestCluster); if (surroundedBy && !this.player.isFriendly(surroundedBy)) { - this.removeCluster(main); + this.removeCluster(largestCluster); } - for (const cluster of clusters) { + // Process remaining clusters + for (let i = 0; i < clusters.length; i++) { + if (i === largestIndex) continue; + const cluster = clusters[i]; if (this.isSurrounded(cluster)) { const surroundingPlayer = this.getCapturingPlayer(cluster); if (surroundingPlayer) { From 97f0a5d74fc04884915dcba850d350d91ed0585a Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:22:36 +0100 Subject: [PATCH 16/34] fix: ensure canvas context is created with alpha set to false and set alpha channel to fully opaque --- src/client/graphics/layers/TerrainLayer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/graphics/layers/TerrainLayer.ts b/src/client/graphics/layers/TerrainLayer.ts index a61ef2f4d..992b54267 100644 --- a/src/client/graphics/layers/TerrainLayer.ts +++ b/src/client/graphics/layers/TerrainLayer.ts @@ -33,7 +33,7 @@ export class TerrainLayer implements Layer { this.canvas.width = this.game.width(); this.canvas.height = this.game.height(); - const context = this.canvas.getContext("2d"); + const context = this.canvas.getContext("2d", { alpha: false }); if (context === null) throw new Error("2d context not supported"); this.context = context; @@ -56,7 +56,7 @@ export class TerrainLayer implements Layer { this.imageData.data[offset] = terrainColor.rgba.r; this.imageData.data[offset + 1] = terrainColor.rgba.g; this.imageData.data[offset + 2] = terrainColor.rgba.b; - this.imageData.data[offset + 3] = (terrainColor.rgba.a * 255) | 0; + this.imageData.data[offset + 3] = 255; }); } From 8b9b567391046c404ab7c1fb66d845aade3ecd7b Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:23:21 +0100 Subject: [PATCH 17/34] fix: create 2D canvas context with alpha set to false --- src/client/graphics/GameRenderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/graphics/GameRenderer.ts b/src/client/graphics/GameRenderer.ts index 34c8047d7..c8d46fdfe 100644 --- a/src/client/graphics/GameRenderer.ts +++ b/src/client/graphics/GameRenderer.ts @@ -348,7 +348,7 @@ export class GameRenderer { public uiState: UIState, private layers: Layer[], ) { - const context = canvas.getContext("2d"); + const context = canvas.getContext("2d", { alpha: false }); if (context === null) throw new Error("2d context not supported"); this.context = context; } From 80199d58a5cb125bf0b04f1a5ed023091a70f5a8 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:36:04 +0100 Subject: [PATCH 18/34] feat: implement WebSocket support for lobby updates and fallback polling --- src/client/LobbySocket.ts | 177 +++++++++++++++++++++++++++++++ src/client/PublicLobby.ts | 60 ++++------- src/server/Master.ts | 67 +++++++++++- tests/client/LobbySocket.test.ts | 116 ++++++++++++++++++++ webpack.config.js | 7 ++ 5 files changed, 380 insertions(+), 47 deletions(-) create mode 100644 src/client/LobbySocket.ts create mode 100644 tests/client/LobbySocket.test.ts diff --git a/src/client/LobbySocket.ts b/src/client/LobbySocket.ts new file mode 100644 index 000000000..f398da054 --- /dev/null +++ b/src/client/LobbySocket.ts @@ -0,0 +1,177 @@ +import { GameInfo } from "../core/Schemas"; + +type LobbyUpdateHandler = (lobbies: GameInfo[]) => void; + +interface LobbySocketOptions { + reconnectDelay?: number; + maxWsAttempts?: number; + pollIntervalMs?: number; +} + +export class PublicLobbySocket { + private ws: WebSocket | null = null; + private wsReconnectTimeout: number | null = null; + private fallbackPollInterval: number | null = null; + private wsConnectionAttempts = 0; + private wsAttemptCounted = false; + + private readonly reconnectDelay: number; + private readonly maxWsAttempts: number; + private readonly pollIntervalMs: number; + private readonly onLobbiesUpdate: LobbyUpdateHandler; + + constructor( + onLobbiesUpdate: LobbyUpdateHandler, + options?: LobbySocketOptions, + ) { + this.onLobbiesUpdate = onLobbiesUpdate; + this.reconnectDelay = options?.reconnectDelay ?? 3000; + this.maxWsAttempts = options?.maxWsAttempts ?? 3; + this.pollIntervalMs = options?.pollIntervalMs ?? 1000; + } + + start() { + this.wsConnectionAttempts = 0; + this.connectWebSocket(); + } + + stop() { + this.disconnectWebSocket(); + this.stopFallbackPolling(); + } + + private connectWebSocket() { + try { + // Clean up existing WebSocket before creating a new one + if (this.ws) { + this.ws.close(); + this.ws = null; + } + + const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"; + const wsUrl = `${protocol}//${window.location.host}/lobbies`; + + this.ws = new WebSocket(wsUrl); + this.wsAttemptCounted = false; + + this.ws.addEventListener("open", () => this.handleOpen()); + this.ws.addEventListener("message", (event) => this.handleMessage(event)); + this.ws.addEventListener("close", () => this.handleClose()); + this.ws.addEventListener("error", (error) => this.handleError(error)); + } catch (error) { + this.handleConnectError(error); + } + } + + private handleOpen() { + console.log("WebSocket connected: lobby updating"); + this.wsConnectionAttempts = 0; + if (this.wsReconnectTimeout !== null) { + clearTimeout(this.wsReconnectTimeout); + this.wsReconnectTimeout = null; + } + this.stopFallbackPolling(); + } + + private handleMessage(event: MessageEvent) { + try { + const message = JSON.parse(event.data as string); + if (message.type === "lobbies_update") { + this.onLobbiesUpdate(message.data?.lobbies ?? []); + } + } catch (error) { + console.error("Error parsing WebSocket message:", error); + if (this.ws && this.ws.readyState === WebSocket.OPEN) { + try { + this.ws.close(); + } catch (closeError) { + console.error( + "Error closing WebSocket after parse failure:", + closeError, + ); + } + } + } + } + + private handleClose() { + console.log("WebSocket disconnected, attempting to reconnect..."); + if (!this.wsAttemptCounted) { + this.wsAttemptCounted = true; + this.wsConnectionAttempts++; + } + if (this.wsConnectionAttempts >= this.maxWsAttempts) { + console.log( + "Max WebSocket attempts reached, falling back to HTTP polling", + ); + this.startFallbackPolling(); + } else { + this.scheduleReconnect(); + } + } + + private handleError(error: Event) { + console.error("WebSocket error:", error); + } + + private handleConnectError(error: unknown) { + console.error("Error connecting WebSocket:", error); + if (!this.wsAttemptCounted) { + this.wsAttemptCounted = true; + this.wsConnectionAttempts++; + } + if (this.wsConnectionAttempts >= this.maxWsAttempts) { + this.startFallbackPolling(); + } else { + this.scheduleReconnect(); + } + } + + private scheduleReconnect() { + if (this.wsReconnectTimeout !== null) return; + this.wsReconnectTimeout = window.setTimeout(() => { + this.wsReconnectTimeout = null; + this.connectWebSocket(); + }, this.reconnectDelay); + } + + private disconnectWebSocket() { + if (this.ws) { + this.ws.close(); + this.ws = null; + } + if (this.wsReconnectTimeout !== null) { + clearTimeout(this.wsReconnectTimeout); + this.wsReconnectTimeout = null; + } + } + + private startFallbackPolling() { + if (this.fallbackPollInterval !== null) return; + console.log("Starting HTTP fallback polling"); + this.fetchLobbiesHTTP(); + this.fallbackPollInterval = window.setInterval(() => { + this.fetchLobbiesHTTP(); + }, this.pollIntervalMs); + } + + private stopFallbackPolling() { + if (this.fallbackPollInterval !== null) { + clearInterval(this.fallbackPollInterval); + this.fallbackPollInterval = null; + } + } + + private async fetchLobbiesHTTP() { + try { + const response = await fetch(`/api/public_lobbies`); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + this.onLobbiesUpdate(data.lobbies as GameInfo[]); + } catch (error) { + console.error("Error fetching lobbies via HTTP:", error); + } + } +} diff --git a/src/client/PublicLobby.ts b/src/client/PublicLobby.ts index 6b064b1d9..f60b99421 100644 --- a/src/client/PublicLobby.ts +++ b/src/client/PublicLobby.ts @@ -4,6 +4,7 @@ import { translateText } from "../client/Utils"; import { GameMode } from "../core/game/Game"; import { GameID, GameInfo } from "../core/Schemas"; import { generateID } from "../core/Util"; +import { PublicLobbySocket } from "./LobbySocket"; import { JoinLobbyEvent } from "./Main"; import { getMapsImage } from "./utilities/Maps"; @@ -12,10 +13,12 @@ export class PublicLobby extends LitElement { @state() private lobbies: GameInfo[] = []; @state() public isLobbyHighlighted: boolean = false; @state() private isButtonDebounced: boolean = false; - private lobbiesInterval: number | null = null; private currLobby: GameInfo | null = null; private debounceDelay: number = 750; private lobbyIDToStart = new Map(); + private lobbySocket = new PublicLobbySocket((lobbies) => + this.handleLobbiesUpdate(lobbies), + ); createRenderRoot() { return this; @@ -23,56 +26,29 @@ export class PublicLobby extends LitElement { connectedCallback() { super.connectedCallback(); - this.fetchAndUpdateLobbies(); - this.lobbiesInterval = window.setInterval( - () => this.fetchAndUpdateLobbies(), - 1000, - ); + this.lobbySocket.start(); } disconnectedCallback() { super.disconnectedCallback(); - if (this.lobbiesInterval !== null) { - clearInterval(this.lobbiesInterval); - this.lobbiesInterval = null; - } - } - - private async fetchAndUpdateLobbies(): Promise { - try { - this.lobbies = await this.fetchLobbies(); - this.lobbies.forEach((l) => { - // Store the start time on first fetch because endpoint is cached, causing - // the time to appear irregular. - if (!this.lobbyIDToStart.has(l.gameID)) { - const msUntilStart = l.msUntilStart ?? 0; - this.lobbyIDToStart.set(l.gameID, msUntilStart + Date.now()); - } - }); - } catch (error) { - console.error("Error fetching lobbies:", error); - } + this.lobbySocket.stop(); } - async fetchLobbies(): Promise { - try { - const response = await fetch(`/api/public_lobbies`); - if (!response.ok) - throw new Error(`HTTP error! status: ${response.status}`); - const data = await response.json(); - return data.lobbies; - } catch (error) { - console.error("Error fetching lobbies:", error); - throw error; - } + private handleLobbiesUpdate(lobbies: GameInfo[]) { + this.lobbies = lobbies; + this.lobbies.forEach((l) => { + if (!this.lobbyIDToStart.has(l.gameID)) { + const msUntilStart = l.msUntilStart ?? 0; + this.lobbyIDToStart.set(l.gameID, msUntilStart + Date.now()); + } + }); + this.requestUpdate(); } public stop() { - if (this.lobbiesInterval !== null) { - this.isLobbyHighlighted = false; - clearInterval(this.lobbiesInterval); - this.lobbiesInterval = null; - } + this.lobbySocket.stop(); + this.isLobbyHighlighted = false; + this.currLobby = null; } render() { diff --git a/src/server/Master.ts b/src/server/Master.ts index 94a1d1719..810d1bb9b 100644 --- a/src/server/Master.ts +++ b/src/server/Master.ts @@ -4,6 +4,7 @@ import rateLimit from "express-rate-limit"; import http from "http"; import path from "path"; import { fileURLToPath } from "url"; +import { WebSocket, WebSocketServer } from "ws"; import { getServerConfigFromServer } from "../core/configuration/ConfigLoader"; import { GameInfo, ID } from "../core/Schemas"; import { generateID } from "../core/Util"; @@ -60,9 +61,32 @@ app.use( }), ); -let publicLobbiesJsonStr = ""; +let publicLobbiesData: { lobbies: GameInfo[] } = { lobbies: [] }; const publicLobbyIDs: Set = new Set(); +const connectedClients: Set = new Set(); + +// Broadcast lobbies to all connected clients +function broadcastLobbies() { + const message = JSON.stringify({ + type: "lobbies_update", + data: publicLobbiesData, + }); + + const clientsToRemove: WebSocket[] = []; + + connectedClients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) { + client.send(message); + } else { + clientsToRemove.push(client); + } + }); + + clientsToRemove.forEach((client) => { + connectedClients.delete(client); + }); +} // Start the master process export async function startMaster() { @@ -75,6 +99,37 @@ export async function startMaster() { log.info(`Primary ${process.pid} is running`); log.info(`Setting up ${config.numWorkers()} workers...`); + // Setup WebSocket server for clients + const wss = new WebSocketServer({ server, path: "/lobbies" }); + + wss.on("connection", (ws: WebSocket) => { + connectedClients.add(ws); + + // Send current lobbies immediately (always send, even if empty) + ws.send( + JSON.stringify({ type: "lobbies_update", data: publicLobbiesData }), + ); + + ws.on("close", () => { + connectedClients.delete(ws); + }); + + ws.on("error", (error) => { + log.error(`WebSocket error:`, error); + connectedClients.delete(ws); + try { + if ( + ws.readyState === WebSocket.OPEN || + ws.readyState === WebSocket.CONNECTING + ) { + ws.close(1011, "WebSocket internal error"); + } + } catch (closeError) { + log.error("Error while closing WebSocket after error:", closeError); + } + }); + }); + // Fork workers for (let i = 0; i < config.numWorkers(); i++) { const worker = cluster.fork({ @@ -153,7 +208,7 @@ app.get("/api/env", async (req, res) => { // Add lobbies endpoint to list public games for this worker app.get("/api/public_lobbies", async (req, res) => { - res.send(publicLobbiesJsonStr); + res.json(publicLobbiesData); }); app.post("/api/kick_player/:gameID/:clientID", async (req, res) => { @@ -255,10 +310,12 @@ async function fetchLobbies(): Promise { } }); - // Update the JSON string - publicLobbiesJsonStr = JSON.stringify({ + // Update the lobbies data + publicLobbiesData = { lobbies: lobbyInfos, - }); + }; + + broadcastLobbies(); return publicLobbyIDs.size; } diff --git a/tests/client/LobbySocket.test.ts b/tests/client/LobbySocket.test.ts new file mode 100644 index 000000000..890f63e11 --- /dev/null +++ b/tests/client/LobbySocket.test.ts @@ -0,0 +1,116 @@ +/** + * @jest-environment jsdom + */ +import { PublicLobbySocket } from "../../src/client/LobbySocket"; + +class MockWebSocket extends EventTarget { + static instances: MockWebSocket[] = []; + static readonly OPEN = 1; + static readonly CLOSED = 3; + + readonly url: string; + readyState = MockWebSocket.OPEN; + + constructor(url: string) { + super(); + this.url = url; + MockWebSocket.instances.push(this); + } + + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions, + ): void { + super.addEventListener(type, listener, options); + } + + close(code?: number, _reason?: string) { + this.readyState = MockWebSocket.CLOSED; + this.dispatchEvent(new Event("close")); + } + + send(_data: unknown) {} +} + +describe("PublicLobbySocket", () => { + const originalWebSocket = globalThis.WebSocket; + const originalFetch = globalThis.fetch; + + beforeEach(() => { + MockWebSocket.instances = []; + // @ts-expect-error assign test mock + globalThis.WebSocket = MockWebSocket; + }); + + afterEach(() => { + globalThis.WebSocket = originalWebSocket; + globalThis.fetch = originalFetch; + jest.useRealTimers(); + }); + + it("delivers lobby updates from websocket messages", () => { + const updates: unknown[][] = []; + const socket = new PublicLobbySocket((lobbies) => updates.push(lobbies)); + + socket.start(); + const ws = MockWebSocket.instances.at(-1); + expect(ws?.url).toContain("/lobbies"); + + ws?.dispatchEvent( + new MessageEvent("message", { + data: JSON.stringify({ + type: "lobbies_update", + data: { + lobbies: [ + { + gameID: "g1", + numClients: 1, + gameConfig: { + maxPlayers: 2, + gameMode: 0, + gameMap: "Earth", + }, + }, + ], + }, + }), + }), + ); + + expect(updates).toHaveLength(1); + expect((updates[0][0] as { gameID: string }).gameID).toBe("g1"); + + socket.stop(); + }); + + it("falls back to HTTP polling after max websocket attempts", async () => { + jest.useFakeTimers(); + + const fetchMock = jest.fn().mockResolvedValue({ + ok: true, + json: async () => ({ lobbies: [] }), + }); + + globalThis.fetch = fetchMock as unknown as typeof fetch; + + const socket = new PublicLobbySocket(() => {}, { + maxWsAttempts: 1, + reconnectDelay: 0, + pollIntervalMs: 50, + }); + + socket.start(); + const ws = MockWebSocket.instances.at(-1); + ws?.dispatchEvent(new Event("close")); + + await Promise.resolve(); + expect(fetchMock).toHaveBeenCalledTimes(1); + + jest.advanceTimersByTime(60); + await Promise.resolve(); + expect(fetchMock).toHaveBeenCalledTimes(2); + + socket.stop(); + }); +}); diff --git a/webpack.config.js b/webpack.config.js index 71129604a..8be4eea5d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -180,6 +180,13 @@ export default async (env, argv) => { changeOrigin: true, logLevel: "debug", }, + { + context: ["/lobbies"], + target: "ws://localhost:3000", + ws: true, + changeOrigin: true, + logLevel: "debug", + }, // Worker WebSocket proxies - using direct paths without /socket suffix { context: ["/w0"], From 33aaa1c828549e453e633521d7e2b187863fb578 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:42:19 +0100 Subject: [PATCH 19/34] feat: implement game configuration update via WebSocket and event handling --- src/client/HostLobbyModal.ts | 53 ++++++++++++++++++------------------ src/client/Main.ts | 19 ++++++++++++- src/client/Transport.ts | 17 ++++++++++++ src/core/Schemas.ts | 12 +++++++- src/server/GameServer.ts | 49 +++++++++++++++++++++++++++++++++ src/server/Worker.ts | 37 +------------------------ 6 files changed, 122 insertions(+), 65 deletions(-) diff --git a/src/client/HostLobbyModal.ts b/src/client/HostLobbyModal.ts index b5c3a0a47..000cf09c5 100644 --- a/src/client/HostLobbyModal.ts +++ b/src/client/HostLobbyModal.ts @@ -1555,7 +1555,6 @@ export class HostLobbyModal extends LitElement { } private async putGameConfig() { - const config = await getServerConfigFromClient(); const assignmentsPayload = this.gameMode === GameMode.Team ? this.sanitizeAssignmentsForPayload( @@ -1563,33 +1562,33 @@ export class HostLobbyModal extends LitElement { this.computeTeamCount(), ) : {}; - const response = await fetch( - `${window.location.origin}/${config.workerPath(this.lobbyId)}/api/game/${this.lobbyId}`, - { - method: "PUT", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - gameMap: this.selectedMap, - difficulty: this.selectedDifficulty, - disableNPCs: this.disableNPCs, - bots: this.bots, - infiniteGold: this.infiniteGold, - infiniteTroops: this.infiniteTroops, - instantBuild: this.instantBuild, - instantResearchHumanOnly: this.instantResearchHumanOnly, - researchAllTechs: this.researchAllTechs, - gameMode: this.gameMode, - disabledUnits: this.disabledUnits, - playerTeams: this.teamCount, - playerTeamAssignments: assignmentsPayload, - peaceTimerDurationMinutes: this.selectedPeaceTimerDuration, - startingGold: this.startingGold, - goldMultiplier: this.goldMultiplier, - chatEnabled: this.chatEnabled, - } satisfies Partial), - }, + this.dispatchEvent( + new CustomEvent("update-game-config", { + detail: { + config: { + gameMap: this.selectedMap, + difficulty: this.selectedDifficulty, + disableNPCs: this.disableNPCs, + bots: this.bots, + infiniteGold: this.infiniteGold, + infiniteTroops: this.infiniteTroops, + instantBuild: this.instantBuild, + instantResearchHumanOnly: this.instantResearchHumanOnly, + researchAllTechs: this.researchAllTechs, + gameMode: this.gameMode, + disabledUnits: this.disabledUnits, + playerTeams: this.teamCount, + playerTeamAssignments: assignmentsPayload, + peaceTimerDurationMinutes: this.selectedPeaceTimerDuration, + startingGold: this.startingGold, + goldMultiplier: this.goldMultiplier, + chatEnabled: this.chatEnabled, + } satisfies Partial, + }, + bubbles: true, + composed: true, + }), ); - return response; } private toggleUnit(unit: UnitType, checked: boolean): void { diff --git a/src/client/Main.ts b/src/client/Main.ts index 941f4d05a..c3b85e876 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -24,7 +24,10 @@ import { PublicLobby } from "./PublicLobby"; import { RankingsModal } from "./RankingsModal"; import { SinglePlayerModal } from "./SinglePlayerModal"; import "./SoundButton"; -import { SendKickPlayerIntentEvent } from "./Transport"; +import { + SendKickPlayerIntentEvent, + SendUpdateGameConfigIntentEvent, +} from "./Transport"; import { UserSettingModal } from "./UserSettingModal"; import "./UsernameInput"; import { UsernameInput } from "./UsernameInput"; @@ -67,6 +70,7 @@ declare global { interface DocumentEventMap { "join-lobby": CustomEvent; "kick-player": CustomEvent; + "update-game-config": CustomEvent; } } @@ -266,6 +270,10 @@ class Client { document.addEventListener("join-lobby", this.handleJoinLobby.bind(this)); document.addEventListener("leave-lobby", this.handleLeaveLobby.bind(this)); document.addEventListener("kick-player", this.handleKickPlayer.bind(this)); + document.addEventListener( + "update-game-config", + this.handleUpdateGameConfig.bind(this), + ); const spModal = document.querySelector( "single-player-modal", @@ -626,6 +634,15 @@ class Client { this.eventBus.emit(new SendKickPlayerIntentEvent(target)); } } + + private handleUpdateGameConfig(event: CustomEvent) { + const { config } = event.detail; + + // Forward to eventBus if available + if (this.eventBus) { + this.eventBus.emit(new SendUpdateGameConfigIntentEvent(config)); + } + } } // Initialize the client when the DOM is loaded diff --git a/src/client/Transport.ts b/src/client/Transport.ts index cd9dbdf8e..333de32a1 100644 --- a/src/client/Transport.ts +++ b/src/client/Transport.ts @@ -19,6 +19,7 @@ import { ClientMessage, ClientPingMessage, ClientSendWinnerMessage, + GameConfig, Intent, ServerMessage, ServerMessageSchema, @@ -258,6 +259,10 @@ export class SendKickPlayerIntentEvent implements GameEvent { constructor(public readonly target: string) {} } +export class SendUpdateGameConfigIntentEvent implements GameEvent { + constructor(public readonly config: Partial) {} +} + export class SendLobbyNotificationEvent implements GameEvent { constructor( public readonly currentPlayers: number, @@ -393,6 +398,10 @@ export class Transport { this.eventBus.on(SendKickPlayerIntentEvent, (e) => this.onSendKickPlayerIntent(e), ); + + this.eventBus.on(SendUpdateGameConfigIntentEvent, (e) => + this.onSendUpdateGameConfigIntent(e), + ); // unit upgrade intent removed } @@ -944,6 +953,14 @@ export class Transport { }); } + private onSendUpdateGameConfigIntent(event: SendUpdateGameConfigIntentEvent) { + this.sendIntent({ + type: "update_game_config", + clientID: this.lobbyConfig.clientID, + config: event.config, + }); + } + private onSendParatrooperAttackIntent( event: SendParatrooperAttackIntentEvent, ) { diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index d74f28525..dfd287fd9 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -61,7 +61,8 @@ export type Intent = | SetAutoBombingIntent | KickPlayerIntent | UpgradeStructureIntent - | UpgradeBomberIntent; + | UpgradeBomberIntent + | UpdateGameConfigIntent; export type AttackIntent = z.infer; export type CancelAttackIntent = z.infer; @@ -111,6 +112,9 @@ export type MarkDisconnectedIntent = z.infer< typeof MarkDisconnectedIntentSchema >; export type KickPlayerIntent = z.infer; +export type UpdateGameConfigIntent = z.infer< + typeof UpdateGameConfigIntentSchema +>; export type UpgradeStructureIntent = z.infer< typeof UpgradeStructureIntentSchema >; @@ -524,6 +528,11 @@ export const KickPlayerIntentSchema = BaseIntentSchema.extend({ target: ID, }); +export const UpdateGameConfigIntentSchema = BaseIntentSchema.extend({ + type: z.literal("update_game_config"), + config: GameConfigSchema.partial(), +}); + const IntentSchema = z.discriminatedUnion("type", [ AttackIntentSchema, CancelAttackIntentSchema, @@ -560,6 +569,7 @@ const IntentSchema = z.discriminatedUnion("type", [ QuickChatIntentSchema, SetAutoBombingIntentSchema, KickPlayerIntentSchema, + UpdateGameConfigIntentSchema, ]); // diff --git a/src/server/GameServer.ts b/src/server/GameServer.ts index 25e57eb89..3437a8ce8 100644 --- a/src/server/GameServer.ts +++ b/src/server/GameServer.ts @@ -330,6 +330,55 @@ export class GameServer { this.kickClient(clientMsg.intent.target); return; } + case "update_game_config": { + // Only lobby creator can update config + if (client.clientID !== this.LobbyCreatorID) { + this.log.warn(`Only lobby creator can update game config`, { + clientID: client.clientID, + creatorID: this.LobbyCreatorID, + gameID: this.id, + }); + return; + } + + if (this.isPublic()) { + this.log.warn(`Cannot update public game via WebSocket`, { + gameID: this.id, + clientID: client.clientID, + }); + return; + } + + if (this.hasStarted()) { + this.log.warn( + `Cannot update game config after it has started`, + { + gameID: this.id, + clientID: client.clientID, + }, + ); + return; + } + + if (clientMsg.intent.config.gameType === GameType.Public) { + this.log.warn(`Cannot update game to public via WebSocket`, { + gameID: this.id, + clientID: client.clientID, + }); + return; + } + + this.log.info( + `Lobby creator updated game config via WebSocket`, + { + creatorID: client.clientID, + gameID: this.id, + }, + ); + + this.updateGameConfig(clientMsg.intent.config); + return; + } default: { this.addIntent(clientMsg.intent); break; diff --git a/src/server/Worker.ts b/src/server/Worker.ts index 2ffb25675..da386bd27 100644 --- a/src/server/Worker.ts +++ b/src/server/Worker.ts @@ -16,7 +16,7 @@ import { ID, ServerErrorMessage, } from "../core/Schemas"; -import { CreateGameInputSchema, GameInputSchema } from "../core/WorkerSchemas"; +import { CreateGameInputSchema } from "../core/WorkerSchemas"; import { archive, readGameRecord } from "./Archive"; import { Client } from "./Client"; import { GameManager } from "./GameManager"; @@ -158,41 +158,6 @@ export async function startWorker() { res.status(200).json({ success: true }); }); - app.put("/api/game/:id", async (req, res) => { - const result = GameInputSchema.safeParse(req.body); - if (!result.success) { - const error = z.prettifyError(result.error); - return res.status(400).json({ error }); - } - const config = result.data; - // TODO: only update public game if from local host - const lobbyID = req.params.id; - if (config.gameType === GameType.Public) { - log.info(`cannot update game ${lobbyID} to public`); - return res.status(400).json({ error: "Cannot update public game" }); - } - const game = gm.game(lobbyID); - if (!game) { - return res.status(400).json({ error: "Game not found" }); - } - if (game.isPublic()) { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const clientIP = req.ip || req.socket.remoteAddress || "unknown"; - log.warn( - `cannot update public game ${game.id}, ip: ${ipAnonymize(clientIP)}`, - ); - return res.status(400).json({ error: "Cannot update public game" }); - } - if (game.hasStarted()) { - log.warn(`cannot update game ${game.id} after it has started`); - return res - .status(400) - .json({ error: "Cannot update game after it has started" }); - } - game.updateGameConfig(config); - res.status(200).json({ success: true }); - }); - app.get("/api/game/:id/exists", async (req, res) => { const lobbyId = req.params.id; res.json({ From 11e0aed262c916ffe592500b6841882e1f571f86 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 02:47:02 +0100 Subject: [PATCH 20/34] fix: possibility for negative values in gold and troop donation (#2810) Previously, the zod schemas for troop and gold donation allowed for negative values which could open the game up to vulnerabilities through undefined behavior in the future. We mitigate these vulnerabilities but adding `.nonnegative` to the `DonateGoldIntentSchema` and `DonateTroopIntentShcema` respectively. Today, code exists to prevent this deeper in the codebase, but we should also prevent this earlier if possible during intent validation. - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced regression is found: haticus --- src/core/Schemas.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index dfd287fd9..e6496cdcf 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -395,13 +395,13 @@ export const EmbargoIntentSchema = BaseIntentSchema.extend({ export const DonateGoldIntentSchema = BaseIntentSchema.extend({ type: z.literal("donate_gold"), recipient: ID, - gold: z.bigint().nullable(), + gold: z.number().nonnegative().nullable(), }); export const DonateTroopIntentSchema = BaseIntentSchema.extend({ type: z.literal("donate_troops"), recipient: ID, - troops: z.number().nullable(), + troops: z.number().nonnegative().nullable(), }); export const TargetTroopRatioIntentSchema = BaseIntentSchema.extend({ From 65970278f2e5f42cea73c93eaaca909837613812 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 03:24:07 +0100 Subject: [PATCH 21/34] feat: Add Pathfinding Playground Server and Benchmarking Utilities - Implemented a new server for pathfinding playground with API routes for maps and pathfinding. - Added utility functions for benchmarking pathfinding performance. - Created a comprehensive test map manifest and associated binary files for testing. - Enhanced setup utility to support binary map formats and legacy PNG formats. - Introduced performance tests for A* pathfinding with various scenarios. --- eslint.config.js | 1 + .../assets/test_maps/world/image.png | Bin 0 -> 539892 bytes .../assets/test_maps/world/info.json | 310 ++++ src/client/Transport.ts | 2 +- src/core/Schemas.ts | 1 + src/core/configuration/Config.ts | 4 +- src/core/configuration/DefaultConfig.ts | 17 +- src/core/execution/ExecutionManager.ts | 6 +- src/core/execution/SubmarineExecution.ts | 6 +- src/core/execution/TradeManagerExecution.ts | 6 +- src/core/execution/TradeShipExecution.ts | 188 ++ src/core/execution/TransportShipExecution.ts | 17 +- src/core/execution/WarshipExecution.ts | 78 +- src/core/game/Game.ts | 6 +- src/core/game/GameImpl.ts | 12 + src/core/game/PlayerImpl.ts | 2 +- src/core/pathfinding/PathFinder.ts | 43 + src/core/pathfinding/PathFinding.ts | 39 +- .../pathfinding/adapters/MiniAStarAdapter.ts | 66 + .../pathfinding/adapters/NavMeshAdapter.ts | 99 ++ src/core/pathfinding/navmesh/FastAStar.ts | 202 +++ .../pathfinding/navmesh/FastAStarAdapter.ts | 120 ++ src/core/pathfinding/navmesh/FastBFS.ts | 118 ++ src/core/pathfinding/navmesh/GatewayGraph.ts | 587 ++++++ src/core/pathfinding/navmesh/NavMesh.ts | 819 +++++++++ .../pathfinding/navmesh/WaterComponents.ts | 200 +++ .../executions/TradeShipExecution.test.ts | 125 ++ tests/core/pathfinding/PathFinder.test.ts | 332 ++++ tests/core/pathfinding/utils.ts | 135 ++ tests/pathfinding/README.md | 152 ++ tests/pathfinding/benchmark/generate.ts | 310 ++++ tests/pathfinding/benchmark/run.ts | 287 +++ .../benchmark/scenarios/default.ts | 55 + .../scenarios/synthetic/giantworldmap.ts | 1207 +++++++++++++ tests/pathfinding/playground/README.md | 25 + tests/pathfinding/playground/api/maps.ts | 224 +++ .../pathfinding/playground/api/pathfinding.ts | 157 ++ tests/pathfinding/playground/public/client.js | 1569 +++++++++++++++++ .../pathfinding/playground/public/index.html | 315 ++++ .../pathfinding/playground/public/styles.css | 795 +++++++++ tests/pathfinding/playground/server.ts | 269 +++ tests/pathfinding/utils.ts | 225 +++ tests/perf/AstarPerf.ts | 29 + tests/testdata/maps/world/manifest.json | 325 ++++ tests/testdata/maps/world/map.bin | 1 + tests/testdata/maps/world/map16x.bin | 1 + tests/testdata/maps/world/map4x.bin | 1 + tests/testdata/maps/world/thumbnail.webp | Bin 0 -> 10250 bytes tests/util/Setup.ts | 36 +- tests/util/TestConfig.ts | 4 + 50 files changed, 9418 insertions(+), 110 deletions(-) create mode 100644 map-generator/assets/test_maps/world/image.png create mode 100644 map-generator/assets/test_maps/world/info.json create mode 100644 src/core/execution/TradeShipExecution.ts create mode 100644 src/core/pathfinding/PathFinder.ts create mode 100644 src/core/pathfinding/adapters/MiniAStarAdapter.ts create mode 100644 src/core/pathfinding/adapters/NavMeshAdapter.ts create mode 100644 src/core/pathfinding/navmesh/FastAStar.ts create mode 100644 src/core/pathfinding/navmesh/FastAStarAdapter.ts create mode 100644 src/core/pathfinding/navmesh/FastBFS.ts create mode 100644 src/core/pathfinding/navmesh/GatewayGraph.ts create mode 100644 src/core/pathfinding/navmesh/NavMesh.ts create mode 100644 src/core/pathfinding/navmesh/WaterComponents.ts create mode 100644 tests/core/executions/TradeShipExecution.test.ts create mode 100644 tests/core/pathfinding/PathFinder.test.ts create mode 100644 tests/core/pathfinding/utils.ts create mode 100644 tests/pathfinding/README.md create mode 100644 tests/pathfinding/benchmark/generate.ts create mode 100644 tests/pathfinding/benchmark/run.ts create mode 100644 tests/pathfinding/benchmark/scenarios/default.ts create mode 100644 tests/pathfinding/benchmark/scenarios/synthetic/giantworldmap.ts create mode 100644 tests/pathfinding/playground/README.md create mode 100644 tests/pathfinding/playground/api/maps.ts create mode 100644 tests/pathfinding/playground/api/pathfinding.ts create mode 100644 tests/pathfinding/playground/public/client.js create mode 100644 tests/pathfinding/playground/public/index.html create mode 100644 tests/pathfinding/playground/public/styles.css create mode 100644 tests/pathfinding/playground/server.ts create mode 100644 tests/pathfinding/utils.ts create mode 100644 tests/perf/AstarPerf.ts create mode 100644 tests/testdata/maps/world/manifest.json create mode 100644 tests/testdata/maps/world/map.bin create mode 100644 tests/testdata/maps/world/map16x.bin create mode 100644 tests/testdata/maps/world/map4x.bin create mode 100644 tests/testdata/maps/world/thumbnail.webp diff --git a/eslint.config.js b/eslint.config.js index 4e3ac8acd..3f23b53fe 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -13,6 +13,7 @@ const gitignorePath = path.resolve(__dirname, ".gitignore"); /** @type {import('eslint').Linter.Config[]} */ export default [ includeIgnoreFile(gitignorePath), + { ignores: ["src/server/gatekeeper/**", "tests/pathfinding/playground/**"] }, { files: ["**/*.{js,mjs,cjs,ts}"] }, { languageOptions: { globals: { ...globals.browser, ...globals.node } } }, pluginJs.configs.recommended, diff --git a/map-generator/assets/test_maps/world/image.png b/map-generator/assets/test_maps/world/image.png new file mode 100644 index 0000000000000000000000000000000000000000..868b4dbf3b09a6021289ff39c016fc5d49f66a9c GIT binary patch literal 539892 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 d8Va4o?cB4JP;@9zkS=!29pfA1u zO>fd?d>V$Iap!NQ-`TpgdLeW&IyEpSlvT<;uo1VnA$@?r)_m5oqV{P%MK$@vB|Syx zWAo)RoZ|iJ6gfozMOz?)I_KJYCumf1_NDhMu0+t^dW!ZuTKcCCnDj}!1k?lGC{;^4hbiW5sZ)NC?vI6eLprDge!N3u>~7P0M?t5xP)bq8Q5C3ETd; zoB7UW>ln6k0FCO)z4?IV1|cQih}wp}011)zsEzIZAHbSisAsmuzf0;Y|eSZy~l0sk6yOmG(=wG9kh$WO_982g?8A)cd44@f6idE z_gBgWcffPeh;`jQqnJMpZ;c+9b{XMFru`=Yw6N;r`kp8gqbo`n#t1_PGrJ7|Y= z6QYLqrS*YNTmkdtxQ>vud$OD&>XxqJN_k7O80Sd#H9AvLw3v9NA<4d*#UEtn=Rfcn z-dh`=Vibp>e5@&KeNMT(P*l6!Z2&DYp*S&nR1r!`tf*>#xqhXPZ1^b*biNk`3XMNz ztr|r;^;^ zm8jgs1=a)wPaj!wS5_iNtoDDa9lA_>SyrDhcbHk7kPO43L=(?_kY8pqz0+2u(bO0} zAJ?F?{>Y)9QKqz{bwrPkfk5|8y;UK^DrBFBTA_3^t_VtU%cSf&qj)`2w#wBz%1Zsx zvIvoWEPf9&i%FPw@cN-9Fw>NBs<*pYL@jzGgbk%kxYX|9Q|mm|12=K90z$iMTUvwV zet7AGaKx%-?f;ippJf=WtebW;>UUQ*;HpmcjJqxP5=oQc5aX@%nJl~jAD)cNnu|4< z*_eNSZS5TzsF%(6ngL0EN=4DP31JWA;El^;jvFvyI4N0 z)gK>-Hu8eqW)m^HG~t@J7k>i+&=1hhMX7vLnu|s+{t7l*V7=FJ zy|^M~6l<8#vuVFXj^ZDz&n-*O9w7GoR;X!D1cZX;Ak@K70L0l(C2U^vZ|C*`%DsvE z+<>jXa}N#(J9;KzMZpbo1zG$#cv-*I5I7EnY3)e{&&ua421idRx=YfUz>FE6erCgQs7n3FgyqAWhLE2#(SN~=8hvo0H+nr2b{$HS zj}RV;OAi**hs9HSVZJL^U!WywP~?tjD!x{T97wL-2#F=zdawV5sCO~KfEqduNIcC1 z;~lBZ#0_WE!-QWQ-S!l06>{XsBvxqQpD#@gl%mARr&6)u`>y$enq=0dw4ZL%6|>uD zuC_kUwmvlwuC!1N1x9xUwAser#K3mXrBIEplQ$fZ-9hDXK0~=M{6+8U~@od`#zhRjOT`zRHK^DxvF3G zT9M7^w@YdJ(yAZtisMZ~`KVv#fhhCt=kTN4@bvxAT$XO$oxqT|y@7M=aKk_3sVQfU zIX_pj#P0ug)z_&Hs+@ljACy?u`TV*I7{3-=_{!fP{8=ApNeb>%_6RV-r(RVqdYkye z)-S(ME^M9?`0T4c5-S+a?0F2oU#dh%VQq?c{nbvp6M+n=cxTaMGGX<@!T}4FY#&g@3x7pr*U; z0v26PxalSJhea=4)0Jz?31~9mK1MydmnUqxPqn={GuIJ@UhQT3DMu&DbX%-~9RI%N|?Vvw8Wc z>~}f*|832&))F?0bh?sGcfE|Ey%(7nBIAz1`r@|Hi(8kin&9uL3pU+fr2efJ&=BH% zQ3sU!V%u{uqV{XC=8GSz{vE~5Lzr^yZH$>)sU0rFtNGf5F;BT^4J};{; z_rkZAp?ewp*fDF`AM=(mw=#nHn5~|sXIo$qZu9tGAnL_{BB$};#Ms2LRRxq{a3B(M zqjRmBO2nj9bh4GEWWSlUBoeaXQ}E)*24wd?c3B9p3N?l@ASZP&CrC5Mwdp$jhw3^q z=CZO)s48xaaGHZ9MD|8T5TN7B**2Q}4Ef*Sz^(auhRLdxo3GZZx||0rjXT zuEw5aH0CywD)H^mPA$6`m`n2%hF1`8}#cH?>;QydO%2o|5UdIFZ<{u*B6ss z)i^apN?bx3{Kxpk&~trjh8XCSFOh3-=k7*qy#B(g)C{BRD}C6{(^FPABbSyD>`g@i z>z!qJY>y$Kx>GXVROijjuX8Q4!HoQD@2YQlzs!CQ)`4^m*qzq0${YS+@FO!J?UiZW z=Wj31!+qheD(P;tO+D`%N1A5KbtA0!7Vk~6sdggQ70l`xnF;m;>p zKheF5-G6B~npM=>@2c-HC_oyA&i;EYdxm4vK4z~mJ#opP&aDusSVe&nv-4X2Y0z~i zwmq#rhhg=Tk$Qt7Kd04oiio zE5N~RUs6z4qV=1_Nl&oD{K)~cus23vwguv#c%K?JN3HX}>!W$i&}#*J9b(`vbxYXJ>pKZ z#w(bV(VlTD?r}kP{y4RoApw0qm5dt71$!Tu^q&gRhMRT9x^;JGrbmijT%Z;C^UQ>5 zH1*j^WlcD_*6md&MK%Nq>$4Uzd5*v-1HE>}F%NOw^RI&6!j-^6_?y)plKHTpsWxMe z@G^+s)O(0@EIQ7VqD=BhV3Y7V3dzgTO{yj5TIcNYaSGcf$D@z~t_aKu*KiMXv$PX4 z#2@dhlH6z3R{QhCpI?PPCp@2dG8Kjn)#Q7%ag0g#3`17hga1#}2hGQ>6IWuUfMTLB zWN6+}5G}fw&UbF1gI^hv1M|&u2B33qb4d5(YgnKLg7D%IBso!tOAR*T^(c{ASH#pd zj)~|mx|x4{WM*=ELd@QvIc0E@C($+K2N>QXIF^AG9MlGmn_Q*W1ZHPfGn zPFoBA5~*X9M4H$EEy8z0nEo%vmP_i_v@?QeB=I4a3h%zRA=YGy*xko^Zd5zhw?Yr` zX<7#o^J(j7qYf-@ural2NK^D^_}1Mwo&-EQ_?O-Y{OW`hl67h4o(VgRXC@o|s2aJi z(3$+!rSjz#XZ)YMbc6fDUzO~p9<7p0avJSP-9iiJc1tM_q3IxCs9KIG=T$c9YDq&8 znk}0`oIbiOWfnAYMbY*d2nG+l_xnsdr6jYx`>VaBEPK6n7PPgMPw@s$Mz~Ni3f}GVj4Wr@uapHVA?CVVS+t-!vp@|1j|| zN=qsFcZiRw-T3k@)Ql}m>1Te4(sEMf1y0V5&Xamnhr<61*TM^A-t98~^z@MFCxs|o z4ZY)fYBPi96L$~&iNreHCRGx1G%Z*!9FSOh#rE7$epxE@?agwH^EJI~p9joS4G)vU zcmJ#UTJ>e2oaXAI>t9=Z--A|3#eCD$!}ZV9Rrz&h4AaiG%kQO5G3`bt)azmT%RN=~ zXt&CBwENMIhhewR793e`1w0&{G$C-uRTTYkF+Poht50xE5=`e=C0!*H@ehZ(+*N%Yuq27`uRH@P8^Ck(z*7ZJjemNHSqD43paf`R8!zH#a2;h!Kgm4 zI+(}#FGdmGa}%>Qr*Z{D4;?9f&#zelGb)%3h?-Yh{I**H2kq{n)%*GjOdp(4o_O%H zsl0m8E;XMY1*TTu-k&$D;?QxA!%I6!&oBzpK4~SWM$vDXgqTMtI7Q2jUXqcan8L36 zr3hHd11I;d#%?MtS6VQ#N{A)ib2hTZKc-1XJ(b-}Jhh!;E@wtGOKGO=EAxL#u3|{j zI@2%r7s>})g)N^!`DijSp_GQa293;l^G_BVQL^;?DSX@~3#60C^S(v^C~{T4g?`#c z+DDuudM+SR`7f~bjlJ6sCHI#&$Z^#|5d5~XrY9~kqoNzi&;I~)`w+`WtBNR^Bv1D@ zfHmdYzLwRE7Rg42@9v3#3u~5c++1y;?I2eD<<@T7$SLtUfG>Fb)z)=B18dZxcLm2|PCFB6FF z>UQVVSqhUkR~AtJM)Hm=%PjmTh@#-;wEjK-V$&&&BuE};VUF^1VjM&)QS`$27XV8k zdYX$JGO%~sEB4DKJ%8{P9#d~oPzlBsifNp!Ve!|fHI>)E_UuAULER(5F32pcwOA@* z9U)&yTI0{u_auNdo!Xa<_FV%ouTh0AlCaJ>^(YPFAy(8W1qfDp#Ug~Y?Nd@|_Rgce zF3COY*9+EkXaUXOGi86}%kaP1`Qf_&L!Zrzm#la0$AE@O>8l2co5i2GJ{#uC!jIwp zV~JmNIHtu~5^q%uj2v+xa~G+4sboU=`_b86|MorVG_NQ-T7)_HQ(J_SIecW7WzT96 zqCqb=6a`aV?YX7gw*Y&L%VZV^r!a?1ShnW8$c@j$nwRzIR)#jAgf8&$8jda2{O-(x zeSPY*xy!CUA9$FR8b67Lal_6}PBH&bz3L+eYyOq4@wq!ul%+A*LPPk%rpi(` zLC!L@$DVe-N_zLR_Wt~Fd>APB;ZvONyvhFrg&FJ-ITgkQ=VP`H-XLy)0}ZJk*v_=Z zqwo4!-SN0cLPqAdqvIhzO?5SrFPRz-`DghJn;Ltd=b9BK)(-(MZ5;nk;|p^TsRkNF z^Z?y$_&0YuR|* zZreMF)m$HgKGyuc^8>uH2c)eI5lOeVT8gN}y-&Wm2b&9T=Q!ur_m*6^l%dM0V1|?+ z5(SV{kKrhaf$~spoDW1IIaE%}mW2SPpw~9O{jLZe4c$~vFJVnk(+{9H;?v5o_&fAB zLhn}a(&W-lVnofnr>K3*O;XEyx8e%WA$#{iqfffM&%0qF@n};JtDNtC3Z49G#Xd!H zj*0_z6edGO+BB7+8DJu@J!I)U?01pia#G{BQ}v2*k>a9a?1HMezvJtv66)()ia|~; z&0J%}V=|;Z%Y^fyBczFjKceDHdwkxNXAz@?TVvrxj7j9C%8seW;vD$=HqFg^Sdk=n z6~QSPK{!~fX;MF)KboA*9GkCXR*Y#nOy7fQW-u3{62jwZl4}xPR$mSbl`4Ux?`*m$ zY37?ujBOzvg-6f{h)yaid)2XfqN2Tl9ofEY0P9?>`Mmw97UB)XY*Yv%=|0IxLVGX-bKqw+8QVxiZpvFUU4cs|(VJD}Ug9Uu+R3Bva z-Wq$bGK-!QD!J86omA9(8=m83px$07IaHv3Gntub&TsjU5cE2*)UyK$+BnxdA!9uI zh7&yoOMD`kiA|h?ZMf@u@$2-L)1b3Xe9A%`Jk}pn#HOFwtT|0Ln}+@{&7ya>l!2z# zXVhMkCIp*uKA47B(J||u*23Hv#nYW--?#r}|5Pd0=;KeA2Rwuj+1~%CtR6|PJj2>@6JIEuVJ7z?7^Ynb0LXFRsNPAxwZdHb+P z`RnY3yn^O-YS=A}q|H<}?YTGR0WmFe2A%bDu6X0Dh%0ZX_PMKv&d$(+()vVyv#Ja+ z213sMR@)svIm#Z`Wz`?*ZS&|TjMLcOoRcGQt&d3m)~m^qx}&BVinOc3za6nulmzJ5 zSga79axXNRaO}}&C7LT>ZofUp{GKJOWMeQi&U#E~a)o#TG;xu8vb6oXbLFHU=9X<- z(Zs~Dd#aCRb1p}mzv%6IAAPJ;Ct=sYH;RA*`mETR<9L?4@^Siw+2_&!@m%luMd#WO zv%WOO-c28jK0KuHwi=MPWh2QLSTp^T4))u&iGN@d=zo=-Cj5OoCOo}uTn%WQA)`%Q zI=)i}VZ?pAqSA`PBhI5+-wqq!NK!QxTvDdaVU=>fojLXJ)2`0tIAfq4jDZI3N;6((kI)F&%`gs0PdS3Fm z?%mh;5GfX40R>^x%ii-oz@z0VIfuIqCF)@fO5Iu}iAx)YdQuJE4upq%GDs6z!4gz? z_ja1j5rcyl%JsT^#{UuiyeD;WW+5(Xv#JFZm%52*y7<{Ud#Q;8MbtXe+}Kw#OzSZs zdlpE6Fh>@Fnh3V8SM@d}hLf71#yytFn+=PJA1}L>=VbF*N48$zNcYPBll2Gpb>zG0hr32Doe$M zEk7F&cj-}Id@aUPIRDiA#KnihhG{C}St8I{e&>|?a9@LQxiibmC5*Q2xC9w7Iv;q# zA#OOmjl@+n&yaL;m;X~k?%(B=ZQmn-)4?6^!}nxaJr36jQKzn8K2Arj0j9O@8g4Zv zr&=aN!fVdvQRnQu+tcML;;WMpl!*7ZQoZ5RW04$R@3+puTc2aw)5eef%#_-N6l1g= zt)M$H2E)=4bjMI*;?tcS+LdxqR^N)VTFtcg*_m0QP1&#c`vH&j4j|WSSZk^0d_&jY z6G*=g(wD{5uKA6-@zdpKEedcBxtDtfF!@NL=0Hzz%iTs0+ zf8jUpWu5)nxEF3w4S})yjDOJ(S`z(j=f_WvT}fj=m9I#h%xN=M z4(`kE_`UvE zX6d=7h;qx4>cqyJi=PnFO$_iK!!MWc{(>5rwPrr_Gr-Gx2P@2-S|2EZ;{1> ziJi|x9$=@rCVAs(4^oPGeip7N&M!|t7Z{~+pTTaSqUQZPfNFd*x6cA%K0XH}g}(y3 z%y&*La~(X-FlZ>z>NE!;yD!Bb_6H_~YH@rOckI8qS-a4?Nw8 zcY?9TqcY^5l2Oy&O8DuqJk8abX~QsiGu0)`T(Q6ia(W#0+?w z%59U^3B$5NS(FS&sTl*as>I%6=-e^)E*?6W11g#`?fkB|o+4B#O>_2;3E@WUPfqPCNZyV-V9508ud$BK3JJ|es~1tZ7tHCy7CbFD+Dx0pD$7xL+10(w&XX@ zd)OHG#A|3CmmNut>~eHzNu`=%&p@4Inf;0l2S%zdo3nJ93FkQNWdK>iXVDeNT6O+i z)+2vcc8#5Z_vgYvwtdvcD3-bwr0fN<4271jQ7)zpzLf_Phumk ztN4aObqX`X5})whWjV#Ltge*#< zX3SaEpi3A1Sa3Ibl}nh5B0OQ%9%3~rcQ_fi>}v{#Wk+J_j&NTM8cLO24fp|O>wrO0 z37rG5afXqNhdYcT78V2liE)CCSx%C|X^<&`cY$-vv}{nrYR!RlSxwd<#jk!TXVa4R8)C@siQ15z{>D+ax`>k{SY59(zuE7TBJ?uIA^w}O+>@Ekb$V@;~7wBLC z5Mn($^v4UEJf){lgoo^K?A;`&fgUThnevtYs32I~(79w?y+63^5v*e?r@(w)Mu(}G z>Ao-B=ZQKso{QWyLz@DT-D|d}Ml5$@X?5PpUCQd%qmfq^td{~TdTrvz_4@8o#5yl6 zkGm|qvr|DnAR6brY?M-e5>qXs}V(88Qx9?FDdBV|Ej9p zKAr0ZSViB+W>0h&dh6yru_*>}dCQTKJX2E2D%=z4f`pwR4T93^{BsaXu%?Ws9Td2` zWF~6Z&(kY`eDMrvw;JB9$DsQ7Ky*f{rvc~h5hu&Zm7HbmOq7--Y>@=m*+=>}dP+9k z>6>A0B;t<%nt_kt#!=?KTzQM@65eX*aCwiSWqJMSt~h1V8<0URgz9#lk=Ox4)Te*) z`~%~{e+q5{R>}ze_6(^y8+nq&c&+$AgLBYaidp($`fSUho7{15_EX2Mv4gY&L(=1+ zS;J|_Sn&Ds!8z>%st{&66r$jhI(JVu0NoE<*y2{@(Tb{5-BC z)eXzR1ug``=Xg}ye&yinfw%wfxdk^-Wa^r-L(AMUlg(y?0kqu|W1M0?(wg^2(pUbn z%5GuT zD$reyDat$K!%D!U>!NlS;p;AQ4>q1#zQ7nR%LE!*aBo7aho43A&5nLE%|`4A++W=w z@L@Dq-e}iSX5m>i{n39zv};}R;HJ-t1e*P=8y#gfgaPO!O57gAGx+@-=|F^}#MGxS5Z3kr~fdt_|YyHI)x0)%!ktp642_)}` zpB>HGaN9WRWC%vwwBzKiCNBKlNDTq50?O0>=C8^x48;9JeIq=n)$iJ6IDfJ_*+!3f z|D4BJ$dluCo@2@9UWWe%9WtUIWxGFD1RL^Sr-#Ix!h|gM_VNgyp`3AvnkO?1*KJxf=NRs3gr$CoshJ^G-L@nLf|+Mg zIU!5Cry+@8&_vF9=Ub*ovvF?n`!#BM0R)!&j?)&6bs6TZ?!$&vf|FKqNp*66F?0NQ#`e#Ii$D)WZPDsYv5zpy z>Xy=LS+9{{_|KUHZR*#Xk=^O0>#Hlj5Ai-iOx7nJtQ*$7D6b&^0c+-($i0%(8>ljb zhpO#8YZ9bA95>{g35<4Txtm;~fO;#!X?#G>ZQ13*gC4T%6#jvt zgm#L*-a28B;wx89;DbVH&bIjxOe*H2bpkFa;(*rLDWIry>H^|1DLJWmrfAB=R) zh@P~iovD~?K{}7-=|qMNq^n!e;;1?+vKS9g!yyg!QT;YqlLF@SnuXawMubMEadXDL z#pDLHoxjC!Jw7gvZN+xPCg8MSA=4RvtmR00!R=I4)3IX?Ygu@z!8~&K8}SMd84Z9f zpTXxXPF`*KanEzPuy%4rx-DD16AoV~!PrNI`uZr{>Tc-|FJ$7*;11zraW*&^oIVEC z<8r#^ZiV((396sp|`ogHer^eh!ouvV%F39QHX(a*S8s*TwOYFoY5m7KfNDjmS~6cFa^ z4XHNcGBdKi6B3O@3Onzu8Z4z=UUTkxyT6sy<+x>Qi*MVBq6a3E!@a^J6y^6TXh&A$ zsO&tuz%bAJ0q~?Hs=7^J^5@j$hn{8HUx%@ZWNZ*by@=sOdjJmLxa{|*_wf}Fo=G_ zD{Q3Xzf98~>LCq5lyWot(d9lJ-C@yn*#JyzbKGk|gV$@WtINA|*Jj?lK|hp5GbNKV z8?#w}sP64G%c=Vs!zkXy-CC&om=Qah+KuOrZd{!lw1AsfSmw}W*S8@w9T3r+>MA3&>4 zL=0z`YXqK1aGtFQC!`o>IcqH06Or|>++?-ExY zkGrbH2C;t03&MGw37lE-8OFN{+*TpYvCc?74k?{N99bJ=%WPBfTZT$%IpI@7#Cw>4 zt;w0bn+t_~yD+;8Fzdx09cU2R6$Sc3Csl-_>;%N))Jh9jnKQNf53_(bA^L3-e+f$D zLyF9NEh=Q-lN}tH;^itaDw!njxwWssKDE|s@ zg5VohY7Ug!T<8x{`{Xw`J9O}(wZ+WmU+B-_Z=Xi(y(@FEQ|2L&b^8?S;gy~$AY@&N zI{jlXYG1Eb&p#mOqs|52I`Ee%&6lQY4_eg%=Y7s;bpCC%6uzL1`RJeZ+hOPJb#wUk z^L^AFjj&|-HFgHxZrcN5*W#=q`RkaLxIa$I3izZqL3g!haLmpkJwf|M^TkHS_p3#$ zgDyopkWBQMWDsq5_4wbER(GE#HUFw|W<~LiuNK>vX7%cr?m-w)SK#b--ca*p0F+zZSr5 z1Z9wYTf#LGUpuDwcsNb45QhE>^WLo@GLYQpRNM(wpIM(aJ^ti@H&$mWc-p9pu8m}z z;2Y}4p1)_mp|JIHd??-wdXMoBW9Dw-A&KR(?@}4V%?x|sjCMD)nt3EUFTB6y-In%< zo1~kT!r{J~e$Tl3p&tMH8vQHr_E?s=@QJuUI9M(;)8x*zTxOV#ecrAE8lf{IY5x-w zIRCVANtK0bjfEc`r8S`nV?M-j20L9D1XI#0xS!$=$FA)k^h`;!WN&6}Oi~zWW8QRF z3MMOBOt#rte%zsr9$=)DY_oTGAT+z#7_(z9VrIyv`;-nRr^@hCT82q4kQ3ed60DT@ zWyJ;}-8R_W@LG92uF%~_6CdbCJ-=+keLOjI zEkOg?-rpBvvvKm-A(8tzq|q!^X30-$wguxiAoR-Sn``l;#A z{_ms)K6X_-(89q8Iaz*Wu+T-NQv_VVzt*@_?EoqWuk6{fj#hhg3Xi44r!b4Tw%=^`fRGL?dHzxQ`slMvnCK^x?6By~hf~XP zlE6k)0Otqj5AwzIXw57^!y`~h0*EG6t2Dw$k$VDqUBF98@~!u2$*b;TA7bNks+s@` z7F~Ds5Y0R0U*!%WH z_wQ+(a>~jYC(V`0${JHMQ$rLgr>u_)HCFCgZfLlqxU;oexmA`spjnzJqT-SpWG=XZ zONzLbD5$8YAPNFL{=Uca4{#iCb6xj!o#**}onyLrbKSMg!y}|Zxpwtut>wgh0Y(qH zKe6lIi>$9n?^)aAi1IzQqbAX%ejat`eoUEBfLgHgXejl-f1z9l1&^Ur*y4!U^8RX? z#SLnHFt@QoG7vvohO-<8CUNs8>R}1OsCgf6BR5w1zuEQ_>&*xE0sMG`W(h5iyP@Z>Z_wTXaI**7F8#zz zx6qL!p9_dj&A+c7TcLd2nohA!KBuJ=xg6qk)Fum^tTQzi?fU|;_oa360T0ex)H&6i z+ctFfY6neVktQ;T%pb3Oa(@02usT)RnByJ<$TO%ftAX*#w;x1*3Fw~Rx)r_lV4PmT z?loJ&># zHk~xVbDB!$oZ8L}nYSf?%as?@Huo=(-h~+)Bf$@>l!894fj>bEQY>y@Zc?jc*-yTZ zBn`RHxh}uP#me)v=j9Jj!)hp4=*d6U_w}Pxr;`OY@nm|k02#k(mE!v!&53=7!48T| zsJB8oSkhByfE)cVyuzaOcd)XS-gXLMmgld8GeKxyImy(WZd!jlh*?E%Z)xrlOZ0;~ zyb`$N75wq$X~{@klLp-aF-8r+Cel5B$`>XUz;ud(WyyNV81Ib$7r{{Y4th;#Bl>1l zY_kB=d`l7-PlqyN27WY;TzAJtS@{_Rue3i3Y;j4Ofn~%FDt#184Cwx=7ns&e-cCl= z#oj69#wVCkDhe6?Y4J&Yko*)2p>;(L_a8Lj(l!g!govE7D755x=5TF$A6Z`DusjEP z_Z=OjP0Am4b8#o{B|Cb~??!8n`h$+l(1rtS5hWG-lX1aE0g@3=RJ;MGFmscBA|tND ziRjXDyF`|Hz^fxW?Tjo6rZRC_r#$UM-T;@L6>ss7U%Z5ZR`dvKeC7{-%wcEW>jdGq z(}}Mkyt@-`up>{yDy_HOp1-GF4tVxLFHBd(yK@`89>O&lvFp91y~r_x{e{Plz&zQn zqXCx{`RxIPEeedZCQ$5YMI7h0-sUmCVx`xg+^5bAgyR%Dr%i&7yC0QrzXTNjBLq76 zl~@?iVlGR}W+aErV(8&7$oo5e2X)!q8XJd#~}d8nV}{Qah*vd0x~CdN3&vUjtFL5Kcn(f*zgf*bUP^-{|eD zw7$$PV%v*DI%ja_jg{{K(udZcwrEGQ zn~g5l1y_LQ^Mj^~1_FaS%O4kSz{>D`lrvAb_e?~=p*ACl3`&e z^dqf019-k)IW_W32J9NE8~M!Q?jj+>snN>@H4--BRMTgsYU!gpoDfy87??hsRNdm< zpVk4#?Fz)cKrAGJ8EIuLl?X@ldyty%mY+_2|JyecM0D}(YxY1*qf|)!lJDy1UHbRn%{TL z^;*t~#(M=8+Xgc+_dozT^0b9}H%~FqoDRDjaiGAxGgs-!w~NWkXD{xZJ^Nu4Vm!~W zwh%v!nGevxr=%zaKCIbi&+cy3(Jlg@3iqyR^KGoiXZnwfHj`yn17z3o7uyfME%l6W zR-O5a6w-0-3_v^Aq00pSRSS7^0=C#3(^-Cow_h~Vw77Mm0^FkV*JM|VeAWBEU*3uP zk}dvI98F!TEN%D0^;qK^DP3)rUwvj>y2{+y=<4qGrpl3CeJ6*E1+mXo?qIGUb0>Fi z*Q5^7#GnpQs#&|F>$)QQKcZDrzA0~T37tG&oWQad^|FdY|KGzXL zfC9XZaJyS+%-j6yUXQ_>m&*ZUmJj;>H6}l1g zRM^rd1M4>ZE(ED&=3n*gN|S~U+~d$qXTUzRLuSo~oTS}cK|QL;ZGctP6SH(Jqstrx83R*>M~)SbH>aQ_QF+WT{8-LxiZ)yS zG;iCAyt6gB6&qp+vkubGES#J*lIU&4oMQwgDzL+Viq3j2ikaEn1OF??{lChC$j_Wb zT|6g{dweKx=?PA4Im~aevpn<$ZkIG8l&`R-bfx|txpY;(m#7nN)kWz41 zXK?~bL_}YqYNY$h&b@ng{q>U{hkOv*9efjC^t)~_B|3G`42MmfsxY+L=nmoN{|aD~ z?k;Di3#G{~#U<9CKs*~Ap|kR2Hr-v|ky54*^ekqo!REkUDdTq`4JyY{z#?_3$Fcmz zOf_Io59sB&cOByjtTSrBvNNmGvS;U+!K(-R_ursKn&NJ>!;vcNKbwFvAaOesNY~~n z9}T-(cM7Ime7@W;WvVAVyr3|ovvVUTMf}>hyP?=K_|1iZmwegz{uncdxXh2r^^RBn zi#pN8ZRGvFFbum$^$Xw!3V@J{>Qgq2-_9{Hxv0xDVh%Dt<$P|})A>S&LgT60??Rhf;l(;Mox|85y?N+(%o6%q+TS5z8W)omo_6J$=5BjNZv*LJ1G)$^x%(x&ws5)Oyej8ZuU2Tda)WT?76&C`+@xrWHx{tO14#RCEM0 z!-V$ug)iIN6uLW~J^EK{pO5->0dTOcw#(XKn`^jsxLetwC4p_kE}yCT1&ufEXjk+!^{o2<0Id2TpyI=we~ zbdNA;^=?+Ap7u5J(rMC}Uf4xTzrR*XOMlo}m8gVQzky8+e#!|OqH*6@lVpC|Qlbs+ zI>a~G?6nDSk{Pz=9s3To?}9p*ztC zl&VBF(lWPhBglWbWLECR`;@4IXq*cVH;p#NeS?AfAXGuSZzy1hgoM`e9xy_aM^aa^w-=^+=*{Z^j;$}0mn}~f@K_Sh&@Ox$u zafTV;r}L=9PnRG$?Dc&CdUJ4E{gZf_<9T>cv~+XuXcNyw0=&?qpZf(|>i3AJ>3h4&MvRnO0maENTiImEBq& zM=(Op?8r6!d(Xr3apgW8b~vvqYisZ2iEz$6g5$MLIm{Jn>irRYy5ia8vshS zR25OsP<^4Q^)=Dkh(2YV8h=~BlxJ?vg&65{=k&ppdRMqHQ!nZ3$+)fK@EqcT!{*eU zzPTQ7t$OIS!ZfXSPf!I|uKwp%>$H^CbZYU^D~Q(sra@RB4OUz=mP(JLx>q0=--eZK z3#`IfqdxBw-aj!`CQ5F34Hij)Jlh6$tMe1?$Mmx=MY)+@)JrjRKv#xe^~&}L53r?Z zxi8`fKKLoYgsXgR3~1$>&EG!rDTXL(2;4^H_*xZxK$p>|6NX>j0FZ&q;OwQLsHkVP z7{ani?Kr38iN4uNC+*c{=cuyyjMI&fHCCr+X>%^Q2v@$anv@?%-ZFu(4vj9T>AOcD zf=Y+9h8lV@$MgW=OzFLJOm#Z3xu!hp@hB$t-K2u#sQ7-7>3@Q=JjPdyL1n>0Ss{VC zplU7Do}GD)6ZvfZJ>01rCx7LoHT5_`$o2f)7`~D}iWJ{XA#%FaAOT0(s&+YzO(*PB zwg)Vk-cXYutQKkUlOOT;4!PCJH7QWEn{+w-^;^Ut;vY4$`j4y~-Wu3li7^z4k80o? z5}b~nf4*mjy)9)5o|j64xxEP($bZ792At}v3h>?h6)w+xNrRq?$kv@)_(w}9ZMVL% zi{nrOd~0KFNZFGEuoN^gPZs;>sjuc;=-}5*<)btd#20P0dA{O8>ad!gMg3g)K4JSy zeG837v-j0WrhV>}zLgQI2jv`F%b6srI^odKkCY!%PDWqPnhPR7ABvY(>{RoDWM*Ug z@;20zaf`N`o{1f7P9aX_{laXs<0OrqEG)#MK9O+Mo#wMOOT>IL4Ge}%-5hzd7Y8y5 z=O<>wpK?~?RTK1;XQeF0M^f3SGsXXm*M>ZRhKee4K`#n9ma?lRTj2+_7n^6!Z35Vv zzo%3Hz@=v@qx~BcWr|xpRIN&A<(l%XCxg8uY~Pcl#&@3QYEqh@p+mpkB43!70HZ=? z0Rms^acCLS^Yf%ULw=FEaS7Xc28%)+WDuT78wPK~zp?|Bb9b&8-=FRQQ%pl~q(~Qd zbT4fG$=*)QcQ%&6wK!O+Dhbqt%5m!A|4LZW03bSzO2#1FVGI`bA5rWi_doa-tMK8v z64X__bi9^M!%zWCZ@mKcY_r8Ut_q3vh=CKbRDhpKDF-!7;9%UW!%t*oSFEZiv+sE6ZL^)R7@}x_~N+gx*AI;o5GAmT;9IE24gME-XsYO_Y%}(m{9d|)Y3-B-W@0L_ zl(=<1*=)3obX_+4V6e?m_Vk3{S-Y9U;}8Nlpxl!b?zrWK-GUd{}7V zr&R6oLJ(~v*6_H=jKATsAaJi_?rOG0v1$tWI#%*o8Pzl$k0bfwwk#XU zk4YKk1CJw@yQ?g2vx&6+Y%w-#wA)I4)J=zF5IXaBXHgc%k!n(J0X44#v-&Em38ba- z!RWOS?RTMOvmc$hbpD3=SOhEzihRa&uIPg;Bf@@|QN6E`5bSqI^!ZR7-&Z`T0+0)M zyaVohM#%aHjOjFSSxgKiV#_E^F{S+GP?zQHq7eQQn<)}Ie)szK@ZeL|-8FXyga6g( zNHFR+l-+uXd}>y;s?`Q&4t$Z4zK<M(5n{XjKXr^b%ysPMh4c%4Rr~w=(Hj z$}_$-#xrYrq3Ng7668^8KNoBNbOKMi?<>Mdl8Q}v2OEt&&=#S*Hc@#LE6Z%KD65Ov zIio7jMhc$#=m_U}8hdq44_#-}WccqjDfOnX<*#WFl`af#*Wf^M@M7q=(K1J2_}-)| zGz0#*jT9EUhxndi;)4g^j<)qp_m6}4M|^l6411lnd2$;;Mqmxg?m5W8b;}vbTD7Xp z{%O?ARIx0DpQE+v8k^3QW&T1LT5L`0%f)ZQ!w%bS(!bH9u z48DV8Ca-7Lw|jtcAodhk7?q z{Tgo3HM&AzGn)CY+CD5;G14YJCSvZ7YQnbyGa&o5oiI}E(dI%xbZs`|^~5^^Gug(C zy&FAHOGiuJ!zu9@s0*16Jnom2A6do*&2VfwN<$WwGj z%gV^JN^r}E`l?>u4WAk?p*`2jUOry`(+Y;w2_Ey1JjMIKl%{gRY?OUTRUTlG>%)Ll zN>?u~SQ>OysSU+;qs}3{ONrpdpuT(T*-2?0V)V~!Z8UNcks!DftPV2zA$pq)9B=YB zUI60QguZ5Xy|SoLB;V1X$-ps)wdp&VA@eF?Lru@42egd^<-4X!N%Q>$S_Fg99@PxEzh|BphSAn|4y4j{Pr9%WCZ%b^e?V@RV7E zYyyyQorhVV+hXXtgaA%1$&^lrt#YcwRe?A_JF2)m&o7h?+Pq;GbUwM@iczUB-(DU4 z4Lh%=cU5p*Pkph{H2A|n>XYlr0jW-gi98a*clu!H$bHL8s{Pq!M`{CD_aK>4a|}o+ z58anJ;<1mOI*Y&gE5^5DYTRC*M)RpIG{~<86F%QWo1ZFB@1jnKiS!LCERd*)Er`B6< zSZ?^jhykp#g!?oNTsW8Sx)9hW?1Sb23Pu?*y;(fLZb@sA0hl7H);OxxC>zl5P2CDo zu!s$=n{D+zBkEwj4Fvb>BuSe}){x^uWmi#}yL3LRl(;g07iFO5 zr_Z<1M#npk+0Ootb9>{}{Ul}ahW2B`j%_l|p2ElNc-4wLBeS?Y&w{QLpBg!k>s(=d zHG3bp>d+}2%@Lva;uGQUC7L;1Uf&~7_)Wd8jdRjG_?9S9kdEVYs8Up^8_OH<0ZCm3 z8jat~@sz0f_v=*?%&Wgr&TPdLV+SvRfAbh?)#_a)w*st0uksc5pw3&&5$zj79kOHN zGxFqlHPT*1<9wz=u7`k4-nbmQ!*ZC`*U8fp2OzY9J1cZmV>7~MSH9!d+h)%8W>-gh zzsD0Xz7;Pm<|K8!T>%QuB1szY-?FO>m?XSj6jzZQB+fi zF(da+yE;=^&4-o^L=U=6sjM$c!+$i)J#k;rfXX8|^0(o7$?i#^27yiT!7#84N<#`+#u(TtRb0rTmU$ zx)J*mFM~W+?-I(s>x<6LcvW+3R!I*!sq;?y(A5*s;m!t=@MSfE+T=!?xm^C0v8m_2 z9?q>aDIia{2~xN^@3Mn-s$!s z{Uu&JS8VA^v$!K}iL3;(*tJ4@6agtcfR#-8B}E^HY&JVYey9TcNVb~9l&=?$esYuc zAULIAvGViyn789AN~UIFTTIHF{-#RAy)El`Xhz(CT&N;bd3$=|2n{Mc%gmF1v z7*)US@+aM4v)MBTdCDDmVmy%PzMe6y{3COupCpPa6w&8!<&t7B16Iw9PLc%8kz1i6 zu{HCp3N)-VHY7}QARf8I6sHWKD$Tb7vH`wE;#Jor@;xx;tl*)ZXT?fi2iJ$#v!jx8 zJw8a3&Bz)!0U%ybLwj|dWweqW^bm*~(4!%#U>hr)vNaNP$kBMAd_nk-*;p~DDM`K4 z1-pPEZ6sI6I9W1>-AkJA1EVzKHaISIK*Nn7O!t(amLXhp;!1n5n?Yq%>wosN;^&;h ziN$%oEvec+jl`n2!~Hy;dJOefC9G=EI!eJ+DBTrx$;%;2jQ}F-6Aj;mkL0FOhI_ND z1=qk?F|5;uqAIwRYeKOZ%OEX?xJC_sk}{Na$2Qsx-Mw}@0skgWb+Z*B-5}9)S5kcJ zZyozz#LGY*&+L5r2)*i_@nhOTRgPyvbKAU^6lr{1ebM#S3n(}XjND^b_xnxvS#rjl zQv^A;0Oxv+^#ba3=>v^iD_mK5^&}XQdw&i_o>I%t5cU*(DE*n*16`dHtM4gX?gbEtgzVLT^8QwYNmD}Qp{#no49{yxWxHp>1rGQ&B%gQ?Hc^a zXq&&5y>uHIT0MAcZ8z=fMyGWyS)k#$ zrzE=xl^-`27racP2a3s(!5PwHR6v73r1+)7CZ6se)4B6w@gb6>mb17)0uOPbqJG5> z?I^jzu639ts>pCK^d+q1tItLy{=stLq8s;OR0ZqstD?gn^rA=b4)*$c!fTb- z`cnK0wY4mjY)B=a_d-@DR}S%O?n;1c75FKU-f_^{a3-JwyUVyCg>iunIT9n^xQ82( zBqG)Wlm6c!5S4E-^&G?+=Q%_b0EmcI^?h_ceR-)jy|P1ub4B-+^IjEA=FnSba~x;+GJ*)Z@f(!Bte4hLC}bdm48QNmK`S{G#Y9|cabZq zx5|U8@50SrcN=f)IsH!XGTdr2iTYiXynYMvpzF0-v+xbUYi0e9xB*UTH{+WbT- z05{c0vSjEJ)owTGYSum-ZzU6$|6op@I^KmhL%uFeLpOK_yN}IEU)mE$4|QJMRARln zdbMQcQ#H7@gCI)S**l6&t)`i*Ems7NO{CyaD|TDc>_TM|j-F-`r0--!J)?NV5LDik zdT`)f3X}B-4N|FE)J9$bt#|FLJ4#p(I8It}>zoj6u8}($)%tlZ!QlEG>cK#KRfn1j zW$w+TE>4b7+{)jfW=U(}qmF>knIbLic0(M{3%u?QXLS_}p{9@EF@h65-JW9KLg(!? zW}!TbdoUY=1V|2adJ4A1#6@mhd@W~1w8knPASZgHGCGQPJ*I(d&9qBe$a=KllSNwCTv_OUPrcvki+S28x^U!}?CE zPGDCa2-0&f8I}9qJh+bd#59xlIpyj}Pk0Tf2vgA&Uz^QHtY5R5x^A@9x@IjW4a0II z&^))inZJFX(9NlGs7{bub(MGY zpeH~Vz4yYFnKlsC?6H2Sq4g69d^JRMF@V64ML!&Nl4&Dy)|@djH^DO%pvVqD?5mWT z@Q5ElaS?U28H$tupmQNi3ibk_Qs5H>csDuYDUDt@N0_Eujw31md@$7YGT>gP{fH7o zzE7A=N+;a^FS*yDcB{T^@IK?;Rmza}5B7k@{|SLGAN)b3algg{!1;Aw#t=P&p0#8T zOOA$e9o9>u#*=8`P`h-kxOL;ND$4_z!lfvfOSH5hp<^^mx&Z7kpe2D}r}{)|&TFuCwF zC=n(v9NF9xZS^~7{x1%)<(Zxg>TEG%7m^&4J!%CJW=@_ZY+V*kJ(;cdWG`6PX2B2f zuRB0M9d@+`ur{lplc8-Yp(FZfr_(VgneA0i?!>It#Tq_N&#ImhPE*L2Nxe=w&)3@bF&oOdVAGMr~$nKYsjfSQ9wRt9l`W1DG(`c5mW zJ6MEr`#7pzh8J~Bb3M_5`>0@YjP+#($C^c)aDwI4-BI2g!M^R&VANeRt5Xe? z*m`;8%-#0suy0)bF*g0!6Y)>Aw@aCe+;-r7e{5KmMw>wz( z5jZzJsA4WMx3_Vcc?=-ill!>DS;+k0?_|3b&~fUF1uOH)b#ve74v+FTtb}B%XI)nz zxgrJqI;G>AWeeKnW5!ub(;ATSjIHLPN*lz;c3;JHT^GFYt25Qhp5O@z;BWknTspVb$Q?rjnF&Z22uEVzF@@=34?J zaABGhYeqW_nn|@a8u_SLi8Lq?3}o)4e|?jx>C;Wun;5+S^2%Eau=n3IId0CQTAiIE zT#TZ&bYt-Xnq_BUb=@gOU;AzI*4vcSOv#Xv>%eIR;%G^HOc$-&G$Y02_pEHK#IN7` zw}qa;uMM7}>?dYtbbvo$^=gErUaAtua$;#T{C>kg7fUbEG+-Y$>%%BlvdFLHui;K` zJ>ujqr()m+`vFUXo?sj_Xr8=gR=DHb8XJ>{=o$*T|jWE4@fEH!<(@RW2 z4^l{`6*@r=5$-w+wF&5!@1}HkF9Cc3`)vDmt%uVak>(n3UUE13J}?RGX_hgZ4hJJ& zD}}(0Stqi<&^s;lQ89tP!-!} z=(!rhG2^~js!XNNClqsa0?^6ZWaeP7%34W8j{xr^i0A2ezJT1+8vUA)#YptRa{RgD z)f@GkLCz^Xe;Wat81s@s3W`^>rC`yQ7~Kk!dEzevmo3oU#2u*&xn#z<91FazrftUaVSC1YuSh2T4UA z$YiAd_;tme?USY3+IiYfhYzGs0^G_PlwRda9+f?x2!#gBY1VJXU1icz@X|oG6mqYx zfH+MqJVA?ZJj>On*vEpIAp3^@8Cv)qbN*VqRaE~@$=pY^;LhGF`kal`R|W6+OVkk| z3>3`Mn`A9tFO{pz{!x9hV*Pr-1`J!c)6`Ejdcp%Dl;DeiGFJVm~9*= zt}eH{rN;3s@d`GBhQS%p9RlUznl@o^`TQ%-$l_K;6w1=92hO>wztmb+6#C>F&#mAyEa|&! z!2QdbAFNHwySA0r!2{hUwFsc3L4}iPH7CCLWWg&^Z)uer(;B|g6WX(wOA_Ty);2DD z@-kfJ!3&e7&eA7@nTsCL9ck&Dzc|hg`)j?OMaq9OON@AjOIB)^xL$WJI;!jQabkG_T%3Qlf(z&aAWX))WSNYT*Y|B3w@%6LN6PHBOtL7N~Sp5(>5RWjF5|*mB%f;T{d0IJNPy_8`k0 zR8vOs&|!i-u;1Uj_C0yE&(a_4Dp-D(9znTWyQ}K^P#=L84*3078JgMrgDU*)!B=e5 z`YleX-4Up_Z~D{N+al2sLhE`l@YMe5C}(~xy^2f-kzcY5*rp1WnQn4&35~#-4#JW2 z@t3RT5vGB2EnWx$0L+W74g$I!hIjqHm{v%Y$vU)xFa+xdujDfcFDPB{qL&s@_9a&Y7d{;yIR^i`d1Z z*(6hv@L@2xUo)o8d}}<67CK&Ult(`FVG#v10CZ?5ijR>8vGDtguC}JV6U@R4B(VVi9gf(0e{JOCHi_!0K9k?ChCycFH z2{#2SNbLUrqRm$HW&W}7Z@%qG*XS!!iECZoB}fFLyB?iHl7DZi_p3vsno~wbRY$H+ z*9V(anU+2qe?AzP4csBl5N0NXJ7>F}#k?|by{5X_ zJFl)N20iG0Qr~!_?`(Jd zKa$GgNd(Z-lxS~+n@%lC*^jD$2#=x-wj9CJa7k~4NGr`e7QDIQ!Ec6ASuGyma!=fdEIKGKM5kB2OE1D|L%f5(_ zMm^{u{0^yg>4hVkGaohjT+=7)k+h)3_JHVj?C?J$W-nK-b*%3l9-G*;CH^8l&6- zWqftdGV1k^axj&){CU`>$jZA3j(+F~o)!*u`Gbdh!E5od6WGK#RsC#MNFy;29*|Tu zc!M_q7SJqaa$+$-ykJK7wcNhI zcUc)=TI3r|3{adeR(C6t7#vf# zh>@^5?mTmbV8yj_3IXEwl;1-Ib5OTK&Y}vd;9Dhdl|IvTX#0|0qBDyf$^yqoUzu;s z_I|DXHy)uvh<5}Ien>r3Uke5QTzugGuHS#2z0s<)FkX9pofWDZ$lLlKrob+CM9iuW zKkR`Iu@VmPIuUTq&M;ns0K1d*RhcM#?rm6VbQYn{Y)vD)CIAa15s61Z5fy66y@I@8 z>f4=c7r3n>R5S|i6O$7n_|+HIbhLj%=PUjO41mo%~om!j^DQ{7ABP5Dg#z3L)6(ZEGfl!@z=Mt=JmVu#vdd2blBm0>95G z9PZ==g0Vw)%3|Z0A|=x!5XtI8`tyv+fSFhB>$iX>7$+re^7TlIRjZ*1m^Z?t`x6x%^Bkf~*OZ%c!Up%?P$SKT+MjdjwcB>QFvsKJ=m1CJ)v=p-s6=4Yl(y z(;MF3x6#1)(eT}=LAz!wr}+gRR<+SWa1L)YS(tUXu^*f_cD&fgW~OL^lp{S$%G6)9 zUQ*3MVpb0=cUZCD!T5(pL%2JeCa>WX)+I*txq9~sm57T}%XxBGx6L?JM1j0O$YUBr zA#pPWRUNAT65#8HHn?t}`}4X#4mK`$2@C6kj)N6B;_VPS`>NH`ZLuucb{gR3j@Qyie9V=cGbBYF%Vk4n-!ea`iy55wY77Cn!M6NvUKWshE1ew3(VS5$8Te3k43T6`YhxC@>9B=-K`YYZ2S zUQ~IjRQw$K*ewKKwZ_%S+U)--yBhV-s@y5s6>i+;+8ziy>%vcOi*N;fONGS=`{v!0 z4Pr4J@0EQ}!MsBrIWfH!KgsW@LGT0;_Xc~YG}cMCbzF<}D$M{q_w$evDEya9+TF|} zxDr0&XDfCJSH36^%Pn`*ljNKHUA=LaFxdd)1EziCYQ&ISwL5OlfWLG%hIF_EhHt%1 zt#UVY$ype*p$26*)xNVvOL{VUTmY^C`)1Ej3Gtk(<d~2acZqbu<|;aO<)(W~$0t&i*X%6mLdlc03zAk8Y2U1u@rtz( zGKdj5ow7JZ*QE;gGE~FS7$08NDW&t95IbIg#=K-k6_jo+{f`N zOR&0HfFT+q@W_z_*oKhTMz>>tiJ;-hhkBr2*X6n#>p2zw-$}>+cSkdS=b0jSnE%m! z{?B1mM*`}~6@Y=HvG>uw02C`1cJR=z*bO{(74Wx8=BvNj;e81+1{~?rS;7W1Bh0Hj zi_z^UNUG_oJeX=8Ri2Sw8`uN?-q8MO6g8(lTDF?Mcq1=9J!w3o+Ev%WcVZQm%<)Ke z6=<8JKr`0T?1^D&&ZdzwYkkZ^>4%*{j9h&d^==J7!(*b|TkAGyTZi0N>?%d6)tv8) zdz&wnr+$Yk3@Mf1!Vr5{*F)w{5E|!q|FDkIWSAizVZdE5igiPkgY3_U?%Irwzo8an zEU$Cm(RPL`L0+k<5)n1x%p{DA@b2=x;IZr0Y?sLgJ$aU9{I=9xM9t%BjbW8Vqpt91 z7SKVpCx)|*PygD}6bBv$HECPRE6O>p`wQHWcENU%M}?qe{^OcjVe_E~`fW`~uX;we z7IYze&I@kB3|X;K6tef@h8A5l%a+EimQ>6%>TN9)zGQle=yLJFW0O`F`prGz41PE5 zQDKg({$A@p(W}KvGYb!a9htG2K1MHA|B&>0oGJ8m$XU0Ph#!mD@qz$8fQFU!%5?cO z>=c^D)0GU+gyI#;76z5C$~9CYlwIaa=($w+b|!}P6}~vENl%RoabG8t55=;#IYg17 z3tWrhz8s+MaxS^6cF@H50v9>)m`*;eQc*>x=$}L%&^+&Xj^2;g{#|2y=~QJ~$N7`R zxNETf(hC|qHJEH_)W>drqj(&QpE8bu{BW?e1btJ6gZh9OJud^KYR!p$)`%}uK`4km zd9b;JYUHE6aVpgCn_|Y3s6zg!_#H&8hZuqUopNwx$0UtqP*C`FRcVeytZUh>pU4MeIcm3(p-?8GiB-~*B?i%(k!8;_GwH=0@ z^n9m@*?@ZzgN0Il_*!2=l`-ZVE5Updv3KqxWYI432<8S1Dg$~}Z9D|T2q|~YL zsb_gz)xgf0J35T$c|kP)er@a<(ByU5(GGAff&WJ6)+L_E(*DLbKOh?3WieA1*=a-= z`doL3QD7EpuqpmU9b38b9LKS}iX5@natSJ5OMFEuFx!qYHk0 zW?ZEz8OelG6*2^Kn^Ie3&}Awhhix)BLvAR`9It^T+`lvm)cS%WEnf%M({d&_af2Rk zH}JBPd%RRTW#x*#(Z%YjAwygjbnU+`Ood5}Npg_GsPBA@XV86tX8$LZB(2Gz#|@OK z;$6KJ@6mB>11aDf-h|g)Alw8wq?JfcCyuO+HMA(TW+(@ny**8Z80S*Z>`y|!KoD~+578Mn!>dZ`Wtu5tdVAX@`@E!AhI*X zuZJv0v!<-w@S$G!Q@XqJ$Z^9g0)X14yJBOf2+39aa`xngFMO(p&iEFUidWo~>!nHl z@b+v1NQw2;*R`zduZd&!Ag9p}WYb7?)q@%$d~e%aFX`v2XXBq7AN6Jn_H3AdufbNM zGf8)oRpLX-UlqpwP=k1if9yguSrar%Y_C%H?U|i9A~QQ)Yj)q@=O-_!!ahP$_$wQy z(X8zxRsGORycja0`;L_9lfg4#9>EQTrMIeBhXcId4rmj*-imW;+Dy_Q3gQtobmS1t z)8vM%IJ!)yjp$T$(a^3jW^L|L+*+PSkxo=)dcw{EYFSEiNh z^xO_PjDA{RWK_TKZD4#o`rCl}5|U!sjr^kVD8?70I556hujK*v##OcrDUmMVhj{%( z`^S`qM)A?mTWWB|wp&)0uMwQf8<>wE#Hd!Ek$we>lu+-C zYL6#0Ckw7rsCCLG%LLG;d_XC5M0^P~CDYviVKK+IZrjPk2d!SP6M3i=D<4b`jF7GM z2XMZ0N7Yem@zvt4;*+5hH_h*-*vrY}`F9N#U(zb`3kXBYgohj~*Lz8<0JXrHZU=UA zhnAEqS^qC1v$tU|i_HDpv6ff}9?zqF70_4%wS&mFCf5K|!Q`+D3A+8~#lUp%VGV7< zxQYE6`X@L2rd~x?(ZI*Z(+j6(Yx9g*OOqR^ihb;I9ARG-t*wPWk1VrdUhkv&2ipA zJ)(x6a6&-6G{l-(`-8Aic{SB+4#lA!zAG7B{1LAXwP3|mm~OWIh2{dHoc5hmi5g8` z2!>+GvIk6*H#4&`5aG5tlId)?&~69uhf%xPChtS2I0kI&Qu6 zCZc!HXWef7wn6RE*XdzPMZ&X<-+HBR> z@72!bs@BfxH2OztGizXG)PSOoaO$)?U^Tb|3I>6)tXHd4h-kK6W{2WA&@juG&ugPT zj$G0nrjaL#1@&p8dI;r9=cNzkDh#SQ$J2+J5Uz-m$bPy>X3h}kOIps_o@q~hnQT86 zyzU1`3a(o?r05x$+p1XWQ$LbR7@HHU?a<<1hiCv-=M|DrrzU(Q+K)>PdkH{W50QMq z1d)q^HVW!@5OPzT+&K`QZ|N0Y4@sJD>Qsr);R3#KQx{hUELY>{0IR5t3=F^S%k#^T zWTvC3DUCi|+?GY#76HRwIO#lgP9RzaD5zK7koG*YqY$PCj35x(g@-zra@%g=?^EMS-cOYL&)oazsoe^UMVt%TmXOAo+3 zoPaZM;d*{q{|o!$>`rZ@&=;|xHUpmHXr?O ziY|y}t@JF8Ynm}0IERjWM*o5gp?mf0R8%+!|9Hh4_B{^n2RQ|319ypKm|C z^vcHa%FyQ*CDFvcFB<3srp^{DUn}gTpCxQ}lZWnGSkIux0*5c@;)1%yspxL!I=;j>7)!4f9`no7=Pbu@yCJ(=h&IN-CA|^QfTpQ|fv8GOa}>?`rN&;-P0VRH;tN^pO48y1x zI4hcah3U~5BH&}~D^cxtI)W`%d0#QAHLaO9N}qwPRl!{V&qg4lH7y30-j};q*jnS( z7eU)NtxfikrNi<<`eW1iyQsn2fRsf{{2aZN7XB#`uj)btZz;-`?8}cse zMq{5lC^*TwXKz)sz+|^=r&jZdKh|)OTowrn zoakcR=`$3IFILSYCL5PrWw&tx8bzpy^mW@8*Bs~KVeW(JJ?f3>I!Z-fYT_BLd6fZ30=lB}QYpy(G$)888XU>PxgizhOEY5ZG0v{R2m)lW--x4?z zr*esN4;3aJ?MyU11l2^$#T{Xa{o>#d8x@_ET9viB7*awe>WAu}n~0Xv*YS${HZ;Ul zwO%~l(4~o66&F=uY}Qgan95-OY&aQ9mrl3;cT;Albd9{SiE_VYQedZnLc4$mVFpKafUokX4newym zr^nk9WP2eu4g1cWyJ4g!d?Dz^l1frHh_XzR80sxO2j7fG0fXrgyt}19jo5niRf|+M z{Pp%~*Z(HsVC}peJa>E9vX}C92*9dsZa{vI=^1zpM)i#?v%4DC62ECXLPi_Ce;!pI@6K6q>$+3B zXYi6g27g)AxG#o(W=W#e2is`QGs9fdF(uemcKCUjk}@#j$XIal%=5g==jo_5K>+i- zIY3cvAnw|lHJ?Z^1zWku7Hgf?gt3Yry@5)KArH0Mc)ZC37bB|VI6vz?rrWy=wO?!2 z9_rbrO-2oF>L~Ww8YM{PEv#N}*&(IdQMbog3ZION;N6PYW+_V9#?2*{n24i0=0X^A z^N~5^t0h)krFWPBP@Kcx6>GI-7KAlaLX<+IDYdCw*0M-ZwAK`){%s<~F(DD(%cvE11|^yi+-|G8L2Kz20{!&| z1Fwx!m;H;0row6u{?NH2Es`BBtQ%bv^l6BZU&5rB6iF)sg~&B6<)5p5#+MO`m#ch6 zD#g7i0UX(gTSjd-gZS9war$CFakjnFcY{Fx-BMs(o=!VsxjsvC#c&%5#Hp*u-q-iPn~7{?^dhmYIST4L4pzWZgiA zsL5uN@4PAT%7pqeK}6)#Q&tdk%Li7|+hHkeu$jxws+U!Ok`8h5O)j;GiH8B9QD(1& z<0VarT(BYAOngjRn=HRJydtALcq%b3s4*fE1D znggP+DKqhVua)P4zXiQJTo=5?^vJ?5CN6%;l4Vo}jumZggMS6@03jb6f4ukr)wDc94{DOn%6{Ue z=;oK3l^)1I?2@zpwm(_wiut;&2|WOJww;NA+xX&Q*G;nqrrkTLPk zBY!)G!b5G@)(c<-t@TyP#nZ0=s@v?qOaqmsESj z$-{-yMn}Y;1mlO5s~An*v_j6Jp7AQt`A|kEeUt`Dx0K2ws@_~PuW{IqPXVPw+Da9t;9nlQQs(~l_YCbZfW?~; zKwM^DO1mOWR^G2oqK5ie**7#M@IB{I2l(0;;Sac@Ri@5J9hvAq@+!DXTg7CR*ILs? z+yUh-2MS*yoD%Jb-;K7(7^nW?5kJ{C;; z-gTGo7R%UtwN*iB89M#rxQplv|7GVQ#Ad&k5pa|k~ylEZ&QTgmNjbS$O2^Tya1!Y%bxJXg>0JWbwXQ2B?+p389D@4I=3z#PucNb#scuX z5BysqQ(QpG-RD};C&*sRB5(+g@HvG1;tebtUF4+T#K8_ANSeURS(#%mU{Q`t@fy{a znSM4yl}NrU=gX&5)3 zpi%7@RbO#pA*M)M1IDwV!r3X^@1h?(O4n#@%8kkza0#}rJ#QYb`Gdgd43H#Exlxar z3DX$S7ugq=&4TFRW5$yfljI0xNor&qV294tMkIMTVfuEC>h^Wg2T38CZcGM&1T3-?$Y(kZzl*DSOUu7r2q=+OL`&@M0Wqb zaPGe9PvcxuvjWFUucSx)qC5B@VuWVd9;Lr0J3n2r!^HUye~8Q6*QM1$A^DR@nk;(n zK#lSsCpiw`XOAOoAZd3NAfAlej_X}P16^wKLs+_P+ps1%csZWQ@_Lr11tzZfKgOB4 z_Gb9k5`R$6RB-}chA5bk5*(o|=Z-#nik6}9`t1xf*tiebZpeEiZJH?@ZACsJ(xVIjb3M7Z9Ag5 z;&VAEvPH6$)B6@^Cnqu>;##;V16&_Yy!9tZu%8DgAHpN{o+SHm(@W(I%(FH zZ+}YgeqnJbgN$gJv}iQR$zLhWtlZHC?WvCmSb?){SB*zG9SC`-EAIGj#_}_bnFE+* zFh9HveaPSvWmMetV${{40q1E0Mfl6tD+WpyTT$%Nr*} zT@E2RcukAU79XRJJh4&v{u>0Zt1tH(@6K-?7KrUVTbs%Icpu1GA^77{Woq71gOvfU zdv3HXoDx`E93U}l4R~syp8C`n-;t-rkC+u$gfz_horwwg$nr~{k1*ncEUX?Vnwvvk zn;|81X;|tEm}zv^=1mo3_d2<4%eV|=a-&)kXH`-r$HTvY&;ezjt+|3Hvw z;!rn6judb7KE!#++(XRBiM>|^30DIUkih}l)|dbBP$aU`cn>S+=TG*;+5Fq(TN05| zt+-0a=&&J0e`Wm`*dF?2PpB^r0N2PMzqg?x`)$VkB%{3sFE_LOwPM7*n1|>20eOwh za`Iw{V98U{*9z;l1%I+~kn_?!99{w+j(>10XWW3ME+d?w0{>1Zu8}BeCbX%NFm>l% z#K7)`b&@B6kQ~=Hd+S%+!6?XguY2zF%J31EcZ$OF|H}xO!?}-u2--B zbJzcqQNq#6n>i76?7)scWUroFgv&nbX_~Ej!7d-qW9FZipk`qU^;-MR?9|EEgn51) z6fhbhYzGD_Vy0vejRfU|-u+7+P%*o1UwcmK(i-f0uI!~*Xxj^ceJ%!gCr^AgMT!3- zvCq3>_>{TtV7zF7iP!#bB03S3Z2Uhy$8R`X@CIMdIyyTOO+SOAnPcUH+70<2=fNu1 zm*$>qOIz;p!4{LT6b)}DAe(2Dv!|Z76y#uc@Vwh(Q&mMx*wO_EL_ytP5UCrL*<;@w zt~&IV&2Xn&G&AuARLhV2f8%b%f7%gpf(lBCF*8Dk6OG359MDu6MDC93iZ1|tpQ zXw$c2^Ywvq6|Q~;A*4Ke@vf!a*bkeljc8hZhuaS;S9FcR_7mVwqj`7M;Uw*Wtqs8= z0PmV5kL)CNf&G`a-+wD=Hdc4QE;?pBLX%RbgG3(JE)9O*KnjUr`^N`#d~&MoSo5i_ zsR!bjn$g1yf;F3f*?`2vSP#pR^sMlX1Pc%9E3oAI6Bhwji~$Kc^$5uSyLDs!7Hm(h z-1@Fuzojr&Y}PBfb@?(^_q=A5F~dg7SA+{IDN z!}M?M1{=yLyT9mqBXVMDbW5sAz(%gl8kMd$8RN3AH6H&8$H^{G@vADT&xyf@_cnfMS0fU z-ufa#KfW=37E!p16r8oAMo_Dj_^95os?7{HQzRmKpD#969_w7af*84t94g(8+-E%4 z(W2h6=qd%Pn(47Upfz?X8vzsC=h=iIJUig>V$9QBn%lYc3fNUxVd9$eX##JZvM^hv z(t`(yD0khcx6S;!+``OasGJWN`{D8Wtw$AZQ9Pg?!SAZ?qNVe{whd!Z-fqm-XQci4 zdk#Tx`3smM}( zfs0-i*oSIAWy`wC?)S!JQ@Xb?q8JsP62{CKNoCFD_Dvq=I>oNMGRJq)lWm-62KP&X zap*%g9BylYdd@^(Q#WpvuE4;9!qeTL{^El7L=kL5ZE!o)K*^(oub8c#w7w*I)kGWVP7LSBl(DCF|v z1HQjW-yEPAT|FLpXW(huUH_HCSq=_=H$;c3y=ECRWft=1p$Y5bMzV8Nj*KYw2W8!$ z&h_eBX(pamvJ=I+9#rk4SL~?!jN81!=yqz6$IG z03%Iy=wyk949pDWU9*=Rb)SmAri>^0uF8I{(Jj&`cLG^}=I1Jm68}#66qyzsKi&3o zzD*@B)#M)n;5+;5kt6mY&e4O!GXH?-Z|FJRIzp9`+^}5YsN83U9W28D*TqG;A;Mn& z4Ft=b$n*n`Jy9P;jGTu;2fUz9cE8FzgB)gu8d^@SPiHu0BLY%`tqC&^>8z%mTl?pq zTmlv??$|6;@^FI4oEl$c;w;&b(xA)!#sph_DOS8A3>utl0quh2L`-2Hoq;d-_-n`d zd+Wf*hGg&P$J&PBljaqf7pf@y@4g~uF@b2$?Aq+ui~q;%&xtzSA=eVuUM-BYTbs0{ zQrwkt(l~~6OP39U*$-`+g+qyt-mNL3Kl(a>gdc-OGW^BYY}ZADlIwW~)Ot_-;W}u{ z`%~~Z0CVf9@}Aii)}fm83TJ z1eLn8V9mumMR{RMsCLaL1+~(%$Pquf+j6c!S*hy(td?Ltma4JNK0#y9#kJ8asncr{ zk5wk7MPQ||={yCTsDcl>ELRKbA6%3;XMOvJ9yQM#D@4&t*Vn$eBVR?3OMm(1d9p$H zO;?UOrg;r)fOFFt)Xu#{-X50Q`yC@V^eeBb8x}#A^X3=#uUBm>7UQBEow%!zmG!g& z3-tQ2{5?I?F@oe4eUBT$&6VIbH?y;Cs=)#80AGV}WR?|sf;Wt;g=f>lj)aEf5?O5V z4pkQ^gtw!1!gWwd_=r1GZ@@2Mc`F!)iu@G3;2>BotW@Y%eA~fT!?i(iciOnuvraoN zXtg!!c0I6PVRGiOyj}Ruyc*b5HF%T#-Re;O{ua<=h~&upIMQ$Hm*o_G8vhX8Wo6t2 zU>(AIu(_>VU4{^-c#V;;mg_*b#p+|y%um#f!vg^N46bAqY_W1dKUyNe}^ zoVfwNHx9Ds5=thXlI1`H`dNp23?#DMi-qpMuiM0TqlXO&fa|3+AE=HzQmEAbr=uTl zQ{2e;anZw!9!oj!aIQ(H!gi;}i(esC&EFCC3zkdDNBPb;40x-{Pia7L94*Uej;fWv zi~S4)M*VF$rZu8|-&jR`-G~#+d^5}Q2p{2XUk_Uv(+c&gV)6$1Z`jtvLH`Rh#*D^I zK04+v)AwzzoMiqkC%qtm)=uTtFyDU=;j&-s_IKwsVVN1gP+v-6zsBB+?JbQbOLQsb z1>MdTlO(A|E3o@Mhiya8k5HDzlRXJT z_g-GLwoLx?RIB|+WWG<+t93lR7h-+{3^ z7+FOzVFp+KdVDXR>IMjo{%d8K(8ZP39n)F2kGC(#o(Mc){9Esww(bkXFIJNWb|IJ3 z9U~OWq5kc&S^F&95{KfZHvQzYf&i00!O6XEJaRQ7v=jEE;12f)Qa0>h_E1Ns$+_1C zd&`rXE@zKXga3qV^oN~TD0>T7xxJgc3nGMLg!7H&xlRO5dQqc%NKQjxzdU=V-na5` zg_|b*d5K`}fwnw5zK~ylX9p>H9sJkvNC{)UyR#) zJelH$5$yN-1Xg2P;8Ws2N70aTPZGb(c8FXdaD{u6NT*UbcB`>&!c-kc!H~>>rWTBQ z2xU(c<|TkW#DMPnR=3zTH`py6nBP9e!m%cNEdsVuXO3Yxn=zxXRzXPev-C5}v1-_q zNymKDNUD>|8b9SVJcoNg+RnUA{x{@g^ZdJvQsXN0$71gKI!gw}A)|ES7`crwdZ$Ls zZvFwPZpDst_<6%tztXJuC1cA0-jq{0&(y4|Tr;_+z_(p|RxUQ0Umi!sECPw1@X+EF6x2z+y#J z9g4PDI+N=lM)pjk6p2Cyy4p=&y9w`1t>+UKY&)7AJAd(jUJC$y3ziSBMw?YcD`rmC zg3^MbA+rC*(f~2E%6i4;uofpafsca&her!m5HZN9#>Xz1I+I~ADlOJJ7a^mFFA$t@ zf2wfy-H$1#20X=hVIJ(}yztg#t4(G0rl4kW)r%u*!%s#CioGRzPkU*(w;eoHCf;0Y zmh?7onE7Qj;;Zgtn`v!_9EQDGFlm=O={9NW_jk~)CGbZLYnJji zYp&v?*MpjZ<)!r06C-iWbi~?lY;(ge;H{@fWg1Gv^C92;5LA!D=5NjMCs>j06)&C9 zs=N^jYu;I__dChF_sK6H!$FTM0pfvTz3oB${;qSCr~%IJG}7}WZvYNRjuPZTUpJz< z%Ni5&WQAH+t89I{w$IPLudiD~x(B{4&LS~la*6CPf|1=0*mn5SONg$I1u~NrgUN;K2r#DS_xMfx<=JwH@9p3M8h0Ec^irI)_`lLX=d~>i(MsVzzjhLCn9Ub%C z{L?BInmhOFfWakC5r)r?6wa_HA-HCMHFq;9`%^x{#mV-T+*YX1e;L{J{!UZX-p>uN5FVG){YJAF{WypSlW-wMU7PFFN=SSCFPN zu{7wwePf{kK@yZmvS>C39`XQtMh|6(o?QC7)@Qkw$Y_hsZmV{uI3XU^y#pzq*~Zv^ zJau*l;rgavZ3gx`-b}D@#TAJ}i8JCYZb;aD7|_^KftHBscM_fkhOf~8(`ZM~%5bMc zx1s~{3IzI337mcr?{-4ir&;_rh` zC5`g|g=^ zD&KQcDpNj;0!ur&fsS-I5;pp4rzk8oa`nqC#MqW^`F@Ry-yD-%xMetBn1zwLDu-_T z-aS^?*tNOS09%Vs8vli?WMN{!GmZ5#2kJp{!80$OYuAwW39e;PqLx705nkU5)vkvA zSqUM7Yi<1y=}HQ=RLcF50(u~hRfecJvRtX|f|3$6=o*fi6;$xRE zeGI|bgvRsLj*ZNh|8_1Fg^s+nYh_-lkyO9hXuoDy?Q~W%rJvq&#tuJGEu;YwlR^h* z>!*BCk;|(Q--eAeE=aQpqOKdlXrq?;-doD7o}@Vv|J}hLMhrSjY3k0eDU~t0^BL4h zI{3R`&%g02X4P&t^IAhz?w4BVxDIYfzti%?Kk#7x82|=EoR=Pa2&08{DL+EEynJJc z_)4*-MyYu?=uefdjKp_Z%XHYlY;UREI997+$%>2ClX3RwPlIiG_wiD?m<|BYxN9og!| zglT^*;+lCDS+DdB26UrcStOOWEB?@q*2S6khRBOC??_Q%jHUDJ(6$=+mtyD1z(qqc zdYqi^iD1koVcFWUo*)s7GxW*IGm*O zr1-^T1W3JMCwUs9yS=$dwsNCUcu|U?oeT%L_;KZx6FZyl%1Uf-6tlBg!1%Egbfl(D zu}Y+9m7q93(xlB!2vxrg(!GOZ4`^O!4;GD|<{VN#L;I$zxawSn`h9J#(`-KhHJZBs9 z8oB^CNPp#xQn@-kUIDW@h2*ClODd{C^A`v9fesQ%YLYa8TXj?2ta?^l%WTwtFD_TyZgsq+p8CeGEz0-E*aL%I#7{W*M!T>n=jpWCH6#F z;mtwO;oPAc_uWlu&ULq;zGrn$e9?}a(Q5>betbm-%Z6ThXFNPJQKohdpzX@ci!KrI zw=WG9X@e8C4!YMr!4=$ZzW4`{zu7*~qtB9QZOXtOvfKjUn-&j-j-Iz%ZV1jN@Xl70 ztX*7vLs4`7*j!)xnDImXvqqFhzrFIEhraTei>xLP+PWCbOzU|0KM-~C6iEI>FXnE{ z5LmL`io$3>GrA&l2D>&bn3IxiNfBPKAS5Lo4HsWqMSSlf0L_fE8Hh38L-~TsuHZtU zfa}!lq_d(XgJf|j#-vNC94rGnL`sgX?Xbgr*pxadsf!w(-5xean5q8FFj^#awLHnO z%gFM{?ek5U61%Om%YFimLulfa;6N!}+vo(Z_L7OtSoOXRPBa8D-z4)rf;V3^q1Cp{ zXcsNmElq3O8%3hknOrtKij!;3l zZJ^5j2ZF{9Dz!>Q8#$C6U>W2elO!+Wh$l%s9hx?$E!klC5QEz z-bQRCln$?0P6_yA5TkMIORK|2^vr=^)?xjZ){Z9(F7(SxlDWlL{-D4S@f5PRJDXUtPnwN=z1dmfo9tJda5Df~ z;G`hf{h15RDIH2BhHIF3(+w%Z4LJH(C2)ZBYMAqc_HFAPnzj%CtCNm(DsykD;c>Tx z{=L)S`?(V)vz&-B7S$7*0UHO ztrjNW*WO5X&Wb6+r-D9Llid(^I#?(;+!M4>soF+-J9S!`mAX9juRUYrh+o6}_tmNf8HZD262g|h#d%NgC&cTeY#qnqLtlr?2(RTC&Uv+P|b29Ij*K=Au z!<}@srC#42Y(9`%sA|kn-FxScq7I%ZuE|7&`R}srSZ6rrZzi(UeJgYH-s?U2@ z83-OYcSLPcEn&CD{4CfKTCT)@%dSZ~1JXR}K3EhN;$+F9!4-|zj($fmBS`Z*_@^L+0k?kphd6&{gnFmZ#NrNP{F}n z;G~LL9VdBOOeD5`dvYY(3urjgD}73$rqymPoZNwib@!XSI*^|S2^cQbu#whtB39oU zYw8wuM1x}kPc1?IJa44~>xbA3#jH{Xw`m~VS)7v1p|4@EGUe)xV;>y&jl*a8r*C$q z&ihMmrymCf$>j>W2f=qT5b6Hmefr(Eur-wZ;nDI1U01TVBB;(6b82d&FS~cYpBeP4 zpJkEcQL_3e=a$JsO>Hcp9oimuLi$H;vj(A{Anv{Eka@Ax`2O(&($gCF_dbsfhR)<8 z-(4{e{-a;>#)6~RrX=5ab=pzi-Lor9XUv6nTeFBVI^p8?k8;^6MN(@t>26qGJ^Co_ zj)k~i@RYo+zX)hQke+@zw(mwrq-RHc|EKBiCq9<*-5sr3ftM*5YmYeN_vu3i86c|` zR^9?;nOO=-zypTcs)uqGPD#2#YQV@!wKqTMLbw@rHU})fU2I`Lw87Y5V;2fCSZB6l z;E+SomzA!fouX7Zs<#e*Nx8nZ;FG@Q1Gv26lg@hS8?tb!>4L9j-xWlzZce2vA2m01 z`pUElxA0TFsEHE4?_5CUnxQj{zUg;rmLB>W#d=qf`8&KV{o7W*w%2xkg zy%51Wi8-z0s^qNr7WX_Y!hi?%+KVqZK=YDZonzt}GM3q^OX!)H)OG`<` z{iVZfFK0FyhcIdgh7R_XwKs!Sgg2u#YRC+hQP+U_xyDRim3eHd%2}P6+?U?2agV+= znH^8PZmUemAg{KpcC$F{f^?b2C?s=WM5yy-nvyW?oO%%S;kc_$3~0c(RJ5K0(r{2k zf`E9_(KdBe?J z5aTBddPGB4`&uBFv$-=or~Q=DC?ZZ;KK8$mMUzWzudCwiB6VLmFrUT=t_rA(sNSfm zX^mF3ZkL$0qy3J-RH?(VHvQL-Sa8awMPYO7dix3dxFq5io3u@x0a<$&x%V5^5Rw3O zofR}jcV{0in%N!fknw~7hGEJBi3wXbk-+i59;WYyxrl%*qY6A&{IiQ-Cw{g9EQSVT z>DSh45GQ_BQI1o&NH_n^Xy9SBE%gAsHqRs*&$AA@IR@Me{*B_s7VOjz&aNdV_Oe?N zC1g@?hpDkyp zz}*L|!+M3!Igy`|UtgcOgm1(Xj^)t`;vbq2?E10m)Xlkl#uSW25zQt>NfjcF7sXS_ zj9NMFgUnYwNHZI7YZ5pVA`u)yhS3(RlxLMk6-~;W)h^?O{xDwU!8=EN16MW@ zM+Q%CXltVv0&AR#Jm3t?Bt7NmtiGA8JKy_L^HAU0l;=lae}Sp<%liuoL{Bg(Q93Q$ zxu)_(tUNNpg0lEe?M_T;r9y_w+)e2UQgj6mP!9;+4Nru7{fHy(V17P0$|dJ1cC!Ne zR%0S+SBMp$(Q@CdpW0W*OH@_tKWv)<<~ghk&(|ltLwsK_p3#KwblV_EB!23b#^C${ ztr~pN*Qo|35@LMtKZB>-OG`TW?I?QZUue*IJjfM~U3|31+1Sh2lA2hauC)sr zG}T+0F}=i<9+S#Hx%mh06Zh`opZO73ifNj08W%U1I`GXn##Gx1CsR<8@KKnEvEDUc zI^H{cUt}SfdBl1d+4gt#93eg_qM1qh=+8= zqXV0s82PScA-VhYIdf)mPTGp`$hG7dyHa~o6BhC%vUGR!YqW+Yy7`yn54>~(;v+^;YHpS7j9lLwB4G3#Pg2pGs$x>ps zX|0&uy1eAdvVQCjEnL;cVt->>G#|*4&@yHITEavtx^}hFi<%CMx@72qw{rThKmfExSmxvTC4Tt3s|+`0$(|a3pc^esT5S(J}Hb9Q{;jccBy(_c_B8T8^txe z#q8Zw{Y6BBP+Zub{0iv#$HPBub-)HW*PQYjq6Z-!O{&bnGqOFV{4-qgHoN|*`D9_9 zo5eg>#Ubgwm`GQm+y7y=DfdCR<`24?fi80YiM)?o?m>qPNk}}qT=L%OIYF{yjKHvq zm+pF0CNCDKnK6~!A(aQ&Hp=CPr8No`zVHNiy_a+QF<5y_51m)8GV?TEDS`bR9^5Br zHy)j6(ozI&9R%-N?28MNR-HZx>lYRs# zi%xkFE6M2(IWZWRWrFR4YB0M#E?h4VkiB4D6q#5FLCdUj4Ptn;8$UHX9>|a0h-ep^ zJuPx}$Ts5vixls~`zoq2k|t}ZFM6dO?~@%$0QNv+KCqiHbi`A!?vLdMq~i%oGlAR5 z8_~+1;UkqtVI52D6mAKnNQ#uokf{P7L4sm+he)3}fd<6BuC}~m$eE2a*W$7H!CmTo z-3QE7C5^Ht!v(e$PA90z^5}uhh5lc*s0-&Kr0Zx5>MfXBXuP%>8Q{t5L#WC|ALR!% z1yi}cZqOyd%lEnOt0Fxv>b^Hd*K;<0W|1H@!a=iHZSX~dp~me(kq2v{=eci4qGZlH z=%w@+f_H)(y-=Xlx{wwRFLU*v@Ay9a3)nfr0tdJuzW;)pIB*GHN*o3Q_xGF0p7*bI zO6&*PkXWx19TGQ}xdXhhnj{MC9$=Msn_$x>56uzRgT_H=6VKjKu#psNj-l!=R~b2e zt~}uWqC6vI_oNwwqN}Nu!_$60#q7H3688N}gTegh$LKvI59~iZElgIwB7FZ3TF{Ib7s$tBdH5f?Dv*Uku_!m z8+-cs*Ye~!+_&X8IV=F6v3TCbAL>~9q6=aFpvXM1OVtEHwV`10YtJeZh(pe|m#|&K za4+`=0II7Bw34x)RZ$J}oU%0J-Ppa!E(Mx`rf7u0DNFIa^)EK7H7OkOb8p zrP5BbeC3k$Ut~LWtf`TY$u0nv{GA7;E1qChWTCq&GWZO(b=+)%ld;^?Pj67)Lt)cI zBPL6p#e9GMKM~=INa{MSe7;4Aua-HS-}5d_q;FxA(qs?SH42ffu2$==I!a$7ndnVl zthH_>8UTV|cLna|=V=l0_%ka;1`eax|<^itp4upAzsbCfCuQxAyU!&d$v*aF6>H7o> zddw{{u%9&=9l)L#Pub9#f3mY{M^}lPCUd0TeSJL~J5~sm~Utw9uC%+kaw^%jfLEDBq1iOh1UOL{3bsq%T@=_Mpfe$60m zeOHbzve&1|d$pp);B*6JUmMOCrb|PIq2}pM^Z+6?;qMBdlfX>Qysv9_(c}`a_v@`J zSCwL=6?o%j#8(z)RKWg8>}|?ub_nBKe3xN-pxM%a&(HA?6H%1QF;Ii z;ML)=ogJbA9cSZ2;kMG$n-D-=w0w{h-?4NCrHnp_aOA@~{JFvmOKfj=dEu*)S1a+M z4ncpaLmQ6N2HWr;=75#^iiT78rA~ATFmc32v*j68Z&(4klG` z+>MxAPM^}rXojSq8h(mS#aq2P{7bBK;8q@${0u)7^J zu++;GXqe;&z@I!7PjkeW)# z6_if4j;lei_TMC^3B%=|J2kv2tI}vK*-UixTkh+H-`|YSA*laQLk4v5i4oBe?fkrw z^+voA?f}$gkTjG&OO#Os-J6yd>xCZn$mq(rRVq)D?NUjtR4kp|(H_08>cbE_I>-0Y zzs2Q)tdfgRa_GpnYar?fJrJ7CI(TZs+tsgQs4}1-zd-O2)8L}puuWr8X0tG-mwpB- ztXEc)s8y8~8|6u|4q<_<#+C)Jz@=%=O^a8y@io#T7S3)Pwl*bLsIdXkTPyjd8M~6;SKKThO`NW#-%7b#g1ZZ}17788>Gy@6zD%Q}8my z?+-ZXyd+Lq@G+($3p@KAk-i5`kkOnm#p05!WpIGK^O3O-TpBLZ?;m&+SCGJGqf0xZ zGog5?w@S6}f#owvKS*Lmj9ld|{>2Un>?bh;CGzi^EKSVTJXfLUIY85$=ffU2--w66 zt^umTi#Z>?OFM*wZnA06PXtZS-)K=8MM82WHnUo1qyf(YBF+)tn+9QfW)x>|n-pWf{4NC6o_5F~9)G7X6-gZ0J%rr2XsO{4p z>}I{St6<>sX&4unmNopj#)l~u~1ykfBj1lT^WrkPYV3dpe83S)qBB68oAu0$ETtX3-3miGa zw74DX;Nl3Qj|O$RioTro5_`JTjbc#J0ihh(2Ngz{srLzPbI~Z(DtI+}0|gjq*gk?L zMdFC-uNjOM(6{^WS^{QtB@{dIsagBm0Yf$vr0*{qzU$bRVdI1rrw)ospzuR(&g6^z z1&RWXKf_PP&l${@YZcG^nitf%?v5{UdXiZh*d83Z%K{h8u+!<rUoDJX4$8#=X%^PE`ugCf zfPsbmgqQZ+P?PBk>bz+Uer-A;|AQIw_=i8P{@qA$ANwIj_5Ap`*My$jnF~I}%TIkH zXLFg!`znLm<}dONik%#O-rw?WsF5(L3B`FeSV4*Ac_6#?x{VJ5$@VGDW9{}Y?EOy2 zEcJUl+GpP41GT4IdqlQY$1`yDWX%}+$V2UFq?Q`>HQA3R#Yf@>eC)FbB=Hj~;ZS*=y{x7nsjt*%KldH+ zMn;v_2tAG0YhRo=XYUr%v>YDNvTL@Vvgy}2zfn2iMeo>bN*>nsOYk<^9|88?y@7am zD^I%9+sqFrski@fF^)edJWIM=lEb^P$}&kZO|<-pYdM(%iaD;#3Yy|1!UGywO5xPK z0sqyrd~Z2x$^UM2o?~ORoXGgG)amoO9p4yKEL+}o2e)3?9xq}kMTydTTRMMHqg}h+ z%~b_}Z^&7B(=A@^{q%?Es(Yb!h+4IX+(w72=wZ7<7oqu8zca#l^UyI9tDf0ne zL3kmJa=4C$P@Tt3j7kQ)6&fhpm-o-hgGP#-S3IxLCo}xosZswUzfR&DC|~mJTy!#N zL)9^Yey|(ld0p(-Vim6bKbGFaEy=Wh|DSToX)2vQPMWz;(-bwOrsl3tSvftK)Z>)p zM&*L$mK$y?l~a~WSe8o&l$KVe=7Oduw7HN98Y!Y8DJpJ=?6UuOzQ^xB;5hDs>%Q*y zdA?t-I!Nmdf>NG*jP8NHf;nWRl(mxfzuT&EEQPPPTRxKLcLJ+c8qNjt5J1ov7L`}& zcBC3_#(h4ZS_Ed4cUZ*c?k02{4x@sXwF`y~|KeOy8T4+GD#8J<{p=Ta@mP9`f;=;q z`JHeiCVl)rx~QQVaX2SDm+l%$wzEiRhN$nS8;fg4zPtd-_l-@E&IC;2M-KH%zs8GVJea9L0N?9 z>^U#{g@ri*l~zq;@2-07a@`+VW6D1Nob+O6LGhtL`K4WzUDzKrUdJfP1ZdO{uwqCM zI#XiIy>|L8v}ISD-n|r<=nblPX~wyP4HaKA%k}EiOQ^l998#)K&btAuUYDS;*Jc$! zLP0c)Id#S(Vz-LbzY@^vgWL~D3bI&fCof(Z`RsMEFI#>pYx*Qz_87-K;1Pi@40Zm9 zFUxWqo509emH>x=PHB0@6FW~0UbEWwT>1gXYmIhz-Z{9lP)y6FJs=aS^p6#V`lqMH zXx_Xv2UzdA6w~$i5M_qWF`}XOGIxCGNg%7VH)M3oVi7Ge5yD}a_;<|oJ`>N%Z-=uc zbU%=8XR73%9lM+Mswz}xXVhk~s<=NrcxktpIZ^ii$ZJoEA*Y}n;orBry>kA3ZOIqV zs0oLHJAonOK*uZITjsv0iHHu-dD~F*z2h;#D}jzj4^|<5Pivw6SjdU(!T3=uw|ivG z-UIYv;J1x3Gfkojw*Y3}nNG@5v)a4_o~5czGW_kWw$+B^0>>Yqgu7=Y(=pb0oP-&b zW7h-W_}T-FW}34N{H0TOH)HCw{C}qz2jesq)63NwQQ?OwDiJGe1(d)kKas!s-<+;MtD*4QnzuLti~N@$Y0+)%V+;Osi@@g=mR zH)B_kH@(XBcyi61Yj+s(jQ!ut491m5F=zL~9Rxxg`gpBDliNCgy38yS#d>6h%$NdR z2GKG)jbQBzqq4CDpjF2KtnF%nAEcv8DN-o+vxDh5HrQdg@u9Jjx^mQb<`K@xA4=-;b&GM2o92Tm=%~VaCE_tf zIro3HiDJjehn~yus#^2U5&&Fj3Gt-f72T{u6Z`{crhIoG{DlXfgW#Qk`8pE{)h2dd z>iOlV3)gX2RfKxe4DV#8n01#0qc|dz8(ToZkMkx!f9}p|Pqk;^7)4tHUGH9ok z)GtV~Z{D?@1AIch7kIIas6U8oM~2<0L}?;4gN4xW1vgMf(YjX}Wp5|?XWgDsXS!Br z1)$NvZFPRlbN}Vn1}>Gi&1oKE6Vx%ni#b!HpKHh89MgY0C&HHPS5}&7xD8^rt>s&n zf5M*e+3E_c%RIVAm0kx;&(-{|=Y7HDy7ZNu(?k=`JqV_;lGbS7q`}Nm4Btc(?~k}m z;A%KtWqev<$MQac@jd)o=RdJqJYqP(a_RB3_imDoBQme1%hK0C>0aeN$SXS@8z(n(yYHNMFbz5#iNkq0Lc6)VkfgX|t znh6_w8YgR}cEyA;TJ@Wm%Rmq0KF16pZ%1w=*{yW^IB$5J1dwi~tMakv@KHXH>Aeuw zz&@beSyVxmW6FaT`QSIw++I6n(w^!uQS%(~3o)=gCphDAmZZ%nd{_^*Rs^30LXnc# zTF)F=$S3jsEC?OfEm6j))O@wNQ~iQKsVNGpPT16Sn*f?r^R4QgFYij$Uer;F35*pL z_%s3iBPf3G=G%)#&DCCjB`Dy57*~L(h@mGq+38qz7mw1bcD(&~Kpbc&8KEhIFe671 zd8oGp)3av`1EEKp2lHz*DejfMM>G9Pe3ffgCW60Aj1}*ZFy*h4abLkmXDJny{58^y z0Bsgs&V$sA<~Fr8l)XhIKXn@_Va_YxiBfLT#NpA7Oz)+9E83f z`6H++%6h23K4Uu&pHT+JMdWD|7U{fRBl~5I1U1E;=4{usj{@%NH2c@p{PsI5^~yj0 zq&;t$58MzqHBylc(w+~_U9oi-1b>LUv$=bFv_*a}He~3LcTYlPv#@b|E++f?w}qQm zs?Q!azB8}JiD(eFhK2f3 zn`~UV{z1%88x6bK#dL3Z$2pe2Vb?Z&dvE}nG(E}lyanRMhRk_}+Lte-PUj0c3hA32 zD6@OnBd<(@-wFenlF`xzfl$1cwwOFDxeyi=USVER6FcFQDQxn$SesuR`Boc;YhLp= zZUiGwU{O^o@zo8cxe>BF;1TD5hV3z$`}4CAV}ur>NtE#OcWei)Dh@SU(XqM~M z(|%V+>xxNheUm37_o-Qn-p*2w1fm#$Gh00&*;JAYQ~jLjpt?gDFE`#mSVn$egy>hc zKwX2#ZTPvhru0nLvLwY{)!y0zBhZh4A&pIGLmi^D#LZIbAYYp>RPsqQHWljRvWU?( z50iz>!;=Vo)CKa{Uw^z=Lu4(qb(W(y2tQ7L6 zDqvcYsx3LVYx1&1O-nzWToaEK>j{$xE;O&rTCNyJHrHQX8f77tlU0+M@_dIOH}1rF z&KVfEXeoiX4kFZpe88VWynT@Hx_0_V#tRe|Dz~;ypYyHf;(<|<$%JjcJ zre&>(;~F$inwW;nq+v)}SIWwJthd9tP@bF9YB6|M>o{#+V2qOr!nI=kYtDJ0+cLxR zl-48IZu!N&?`KSPjYIAe&C#%4PSOy3{Kg<5g%cjBR{WdNvo=D2e+_8coa5`1(UUpf z4D{-0&f#a-DBn<)w-+^JZtCs=A2XeQ)X+V{d+LIh;R`)IrVft1pnLxNT6{Y4T8Xj$ z+yTSGQo^+dAXUKSjk=oeUxRw`yM;%VY`2`FH8SP}Oh7-#s$h17!mR)gm2?+AHO|0iYvc$k^Kfv+s{rMuME4FJ#ZTetA^@PM?C)Q$u z#~YgDZt4irOwIrWt0E{xh^z+QCs(At+jrAw z`7)NutT1eD9eWMxeky)AFx_tyxK!_iPj;{cnnXEb)JJ-j#WftuRcX^lXB7FW@~@UF zAZk-Vw_V|E5rN9ED_-8)niN1@E<+|*dnT#KS>A1gQgz>{#9MB;FWqiu*Z@ih)5Es9 zl}Nhs9Kvxj1I>iM9uxrtCYq&Zaf!{_NH?Di6dR4EALg$E>-SPt8Y7xqqf{3Dyxqyx{}-3!uCBz1G$wnr zj~TkoSiEziVYNmKQ5P~Eo$QMgFa7wj$C}fXeYa;Nn(MhsYJi0IXV=-gCHA-VW+#&K zOdb{J3B4nPv-Xb(Ntt7=##esStO=zHQP?2;`pQ-t5Lo>ZRu_`rJ$nI)tsQxp=RHn1 zaS$4=H@yxkW}Doc1nMI>a|dnXGJdbgbdJ<(8e42{*Erwuv^M{dFcKr9K884aK-tsX zIZ|MKHl-Z(Nk8;F59i zn4DA2fulVK1;iV;%P#x$g+SP!uHGI#yW422d114#88`gH@cjHErp%iIO!-K64t8Lh zL-+xgl#Iy}0La_~mTr4y;1Zu66Y1Sl@@&hb*~FBc3wBR5OrOryW#{L_7Hn6nOTh~JBTWOAk3MbSdrqE>)?J-VdLUk5c<>0+s<&7g+S=LS7 z&ZKVs@N8e;@BZY1pqjSOWOncBcwm&b{maj%RATuRrE!=2`9mIYKEh$-RvVO`}#pPnc_knTSc?~Xlr=Q?tfVW|NlO+yBnrYgLS5oy6=)Epi)`CfeA%ff& zpop#;*vfXj{98gBEv@-=i5?YwqGeU=@-U>=?{Iwl+On@3e;H=i_M1(!(UK+sfy!SGB#F_<7-3Ny~a7OkcfAL62*liID+^irWE}9fw1cZ=lu@|*{tx~AQ zdopu?xC;5?zOHy! zGgr!A$VO#e+f_3FGMD8yvD&8=7~9NxgWMC+CMVL8b&Jrf+`3B_S1`ikqVTaSpS}_l z&zf+Q(h*ZoLYrC|AYaNfJxH5AK%TaNj|!v`YMQ)Bl_!Wt0})Qu9A}QtG&FBL;)ET$ z=hKCb-1dPAO75!-_&c{u|GInsSKePE&i9YUhKX`ay+TiJO$m4ya&m09HxL`QQTCU1 zdGwvt_im%RMk8j*QmyiwRlPx_!LFTv5bJ6U<5Z*OLqDbOiu~-xTF*QvpwrtB3h1v% zU3bL(8SD(|(E+pRr7Ja%Q(4_g5%waAP<&B2haji>h7N=WtGUc z@#=Iw580R><4S;2g>1~5UrD3LLR7p1tueL%SS$BrT~iT%tq(6Hr7*2a;l}^}#ca5G z0-E|4TI4Qxv+|MYBL=;tpk2`wn)CW8u1+u!VuN3atbID~Ssp{azWkhq7wMHO=!ux9 zvzX+}T6v-@g*LGS7T_DS5NG|K24Sj>L^#$dJv5a3-;VRuc<(Hi`OaS^l7EDb3w+OU zaLENlS3NT2+&X`Yk>soN++!0yr1XL38p+h5TFt*9Fjf-hXOL&wlh#4;CGNC0R=Cfs zs&nip?CVL)Mpowx3@>?(@PU@XzY&gTuMkxEVWU*0v5X4I`mu6%iKlYB=G2j4V{NgB$2q%IRUY;kO?Q@km)%YL{Vcow4?FEV~* zA!Rt)=y~{AJ4fq7uITkF5&fZ{K$3c|McmgIjIcA3RT`t)#0Vg6(;u`6qBMOAtuB~t zFYx3Stvn{E7ZQ9N7%TKaPyCz#RB;j@T{Tz*&;E)k{tW3*vf{S}jq9b9;TTsQZr$Rk zn!C+xr*mg}>Z_=K)>p9;gcC@~V1bmHYFLq4pURv)_#VPzm&JjoqK6=B(xla-?Bh_0 zp3ATcn;?95EaBR>-fwqOyoE)d9rp!jFOuJEN(@dkP`viJ*gqyI8VJagR@cu^{W2R_ zy;>Rs_SKXi{0_{solKdcsfHfaP?CO|!{3Z4=(SZuja|2_qP-COjXu7`@j-Wy>~y?n zw~DBEi$gTGLC3QTDhE*9XxP{ta~SG@7AKx38dkK@5|&a|$IpzI42;n=E=#`~ulD{# zwolIiqoJhdX7bfVH)^q)^(~*e>6OY1`>&k<9Yn+ATmy@x?eEsv;1d%Yf?}slgNXO;LM^^n z7k7B2Jj-}e6TXw%q}mQQ=PrctyM`Lkn0n1)nn~_ysPFJY@`&r$a^JDkhoKp#H|o1# zGY6k(@<9qEsdnx>sNc-X?e9oKR?_3z*zb4Md@>B&x!k;QGcHlQ1?M143p9HN7YNK+ z95X**`ZOQ%31sbOq%fsbZLRK~o8Asd#2DK_+$p&WS<|OwCX*?xm}3bY$8-mU+4M^1 zNSlki;n!mU+5Gc2TB7w0P1(M>o#jMLbIBWNkl^DABUqn{iYq6Fbq_y_@kp1u zC7qyWU|p>kEaqkaXryeqN{X1A_q$*`Jo=_&PBOJydBB*nruq?m7QG!J(`%^eSO4+Z zj5k>X$O{~!*xmp_jdt6^hFsjyls1_W#m*9gV&4+t?zs>QsS$=q;Y68N z(SrO?E3Ojaru@}Ejg^hxev7W28xJ8Hc$IZ8L>G9&7a=ELpIvp1cSGVO`he>R!-9GY z4j&g*aYVlXY@w`{i&IsQpxGu%!;S+Ma2%ciY&;)KqHp8nZt^mZ(;&+`m1YU7d(QS! z3$T!QRm2^zWP)}p#-f*Cy&ItltZQs>z3dISrISUfA;Y`YjZ`>cOJm?`WM)O`aPG^* z=IAidbW9d(&*w&(bnUuGrg0uMcf6!y`!SB|yQpJmt8!##|LW8@I2m!SH3djqO*xDzDN zKGe+b&a@xIB^~VE6A4$NPF0OkD_npdDqB^5VEr-!o!P@;c}Mu@^#{^wuf{9E%SwMA z?0}P5%#EvKIQQN9DvGtQJ1NlqnSeWUWvrBoa2km;40$kA<;8tBSEU7Z2UiDQ>bT66 z8i%M|Nd6bm%25QnV{?KtKDZ9VP zIiRr!pSq#dHwKL(m-#IaN#|#|bpk>=c|$vQw3~!NQl2vjfBO(@RNH!2M2H`$59TW^ z2=3K56tt8wv_x>t5U82Zzhh~9uGn~;n)&E}b7S|6ch<4VM;>8r$Q?zMeLnEPwdV%~ z>D3yh+rL2TmhnEt2j(0AV3Ua&b%4dWnFT5S02=igmZjw0sg0fHwGye$3gnigGsU$F zeLFBV;y?51WP>%{qGe~Fl%z8kZ3JnYQRwm`*dG0UStWh6aeQKWd$PR^#W0^bdd5Zf zOgx;f@Jwl>`BeQxMfnZMdiB z*I(3s-EJG*&iJderZ;H*f~)CB_(JQdjf7!~F1 zMHy?o-_{|ya{r}dcjJG>Jrm+Vwa{l)yho-0CXQax8owL9nrPi$uLF~^y$RN3wx&mf zO&5FvMa%l2)csuJ<-C$Z&nlg&4Ac=NTLPC@h<&3+2@XjmA-$1TEF`2O&q|v^_WK)c z9sEW$b?@|-Ng-qleJ*{s1I1-<6zG~lmz-qZxhEKPv+al*A-y&$kzrQp`gH@!jGzA; zmB=kgh^e=IJ~kXEzMlHvW4peA7`l|#6DeXLkGH_bmg|vW2?aZtAOlH5HR|rQH#U*N zuXoz|TPB<->B_)SzF{VdAn6wFd&G(}ug?G^<2q7A;PZ8n@r}YSVKx7o@G|M$ICPX( zc^a;vHmD;Uxb+d|;Y4Z+n-|NIpx|7_lnZC3)%c6<*F$>t|6jC~cj!b*!i}CkTxQW< z;Np5Av|ya`u%^v8u;+5k@E*K|g@0Qg5k^}#ss3=mE}S*e*rc}Zn7*{+D%~i{Kybg{ z_7KrmaOOUBL129h^hI3fPDpHC%^Yz9!_nGz+MvQ(v5}YVr@*v@%{uN|TxH9fY$rq2 zi{!a1jZUxDBC10L3F@*}_{kgP_Fj(Hm(t|5yfQBSR2rP7qP5LhO(AG#jm`F>J%UhQ zdPvU*qUEz8@@PUZ`YR{V>xWG|{pz?^ptWqm^Xg*fbJ*uiF!;P%63AqP2J2TAPJU-L zdPOXO6=fZV6=q-0yLF0*)VErR`5@dE?QxfF)s@t9n7@Rjklw-KG98O=`n0GVaC%2o z6&+#Pq}|T5>dC*F&k;F{xpdAKqO{IgXG~9RNl+4E`G3Qim{9cM5#4mIbHu)HoaHyW zRe?qlet>5)Ds6C@-Qdd^c|nZne0J$k^w#QN4bJ-8I2dopHTMCfElcJOM-R!hKrD2( z75_UdS(*Nb)gZRWc0+%9jMay6Bce_Ir?LiDG`C7L*Y4vHN`DtpQ8nE!20Wy6p>eiz z$3fPp+kvUfS5qq$V^PEvM`Y?G`;tY~q3{@hI7?8png2R=vC`}es^}yTX04oASKszf zAN@+%ELPsBfc&l!FYdAr%n>lOn{6I;*sr=&TGZ#KxgY!3yR@O3pbSj(!=)Dr4oBn~ zSNW#cG{bAibs%>Z7PO>iV$T$H##u>Nkd+)V{7Sc|iXwy~x`KKIlC5)xx7EYHRXXXC z4%^MiVl%ZrC9DiDUe512CeNReJOQLQqzp;*@?z>;)6oZ2pzlBee{aU8>b`h;+UNjw zV!~h4U!0hfBIsP-qrmB6UFgf^VzbUm^c^%r#en5K?3PUO&`^HU`3J`c`NaZJq2-RE z;ho%vo2PN^`r#Zos8&gugXGjdsb5PEpF_F`JT*&`d+0vOVR*y6W0PNZ2ikwlc9rIR zp6GREiatPW0BQXt6hwGEViA%_W*v}4i0@e;`SeN*dASv;Vr#AwCYQ8+=~;q~xh95b z;F2-LLU#Z#$jSfD4JzvP`VP~Y4a5&h(~dj!u78zYD8F(X*?*&y{s&>hWa&yo&e;~l z+YgG7N#p$3zn*>o?$mY#*@y6(KRfRqF>*B=*M>DTWIS5uJQ|ctRzLShaZjgZFHGE6 zIEm?Q^=!1MGOBd`&D;h|{UL@Jccw;Lrz;$2p-BT4^(gzc;72@TJ+V^d+00w>yt1%D z77jL+_#t}97eQE{n@vbV5M}QFywEH}m#jTsj}|ZQ7GD$mk>jsZ>+?ww4L#CTid(2J zr3Jd_4y+x>HdfXi6FULpk`0&KmmVAKd^Y^lr}6nt`pD0rYUn!FOAq-75u7k~5=iP1 zIUWIuu~D>8Nyw7#zre{8Nw}dQnRsViPSG7TgtcUw(VnOMtAl;j0Me+lO3&Sj57%9I&z&dB zf)9_R)U#<3S-qEM^wH+%OZn8Xxs8BD-iJ5*&xAmzW--c>(C;c=qX>_?1->)Hc-EB% zV)igs_N840^s-Y|mCr!nHx%?G^rrwd9YBYsz0PXhxzr!*(TtKHn~70 za&=*jc7V#CL)L&G~-F)8G-r=0|B2e5)sXL3H%x;~&N9l1? zP3`F88%rRis3urPpVufU%n_AqJo+?)#yO!L9E&0pS_WNJvculs5?{)rJ-68bJgSy0 zVS1k&uvYsRrz9Xge8(mEqrNV`PanBKCcPBAeU}zfLTmQoU)n5gau!>~)FlX@CJWIF zT<^q|=%pp`nrfj5J{-TSz4#)A>@j`z1i?A5r>$6Or$uTvr0C%y zXZy5|`!4cV0Qz558!2G z4=bAo7O9){;^Y%*r2-#w0q@<>6%Yn_6+g_eC&yX+oi_GV6S4x6tWqb9I@m^m?sChu z@o}YpH0A z6X+CPvOpJ1*|TQT$=SK;X&|4NNLW?!64vvQ9VE-;wUV6_bq7dx*KyLn`#rK|d#l^t zY77n4!Wf$F%SlW;o;lW5@-+x~g>fmq@)q$Krl%NQOD7uLgp#FQKM!DO%Q3>Pzw6zq zOl;cH2hLDBZM&7}DOZMP&fAU6e5tiFp02-JynG>fw)YaC@wr`HSG~3Iq4DdIH|z*{ z=|F}&l~bVkQmlyBL+GA2nRC*w)h2!1I2gS(pZaVz`;f)Fk~o_mm!v0ELL3(Npl8eK z&rO`OuH-0w5>qBw_({IDXjO*#mFvR257zIc4(tMo*Y#m)G(V7?e+C>HGktTX{@zH% zg%0N2`{?C?oYr5x`j6+t2o=*lyM@~>4*j$1h9bx&<-my?Z$HnJgR)=S{z$zf3lp%k z%!(qj&tLDa7BX^$@v>amu>{8+b&dq~;)s z=}}{d{?eOvB@l#-!n_*Ql1~i3I%g%R%~3Xhy06)rW@YThe5gtk_CkBBQ5lFvZ$HWz z_n;eNX;c;X9~!0Bk8oBLq8?*tsgS#IMDOCxYfs4qykMpp+y&aWDH|H83 zHWq`GkaqO%45o<=df&WnD}7zkIjetwJ*aa{X=km&^m_$QT9WPCAjVD}-<6^w^X{NZ!nLKx*@K z{=GKG1YAIvEhJgf{Xb)|mAq|=CJO%6gz>1&+Nyh>kO`P)|1<%OT4~1fh}9DcLp+o# zHgtl$COdAe=dIzlv5wbZcyE{79NLaPLH6=&TkQbtcb&Y>uDbJn4*)~j9GKLM+vfOydch`nE|)_S3U z+hD$iRg5ll{a!0=EH;5Opl@I5J^KaAHP_7m;?g?R+H(M@1w=LX5OX+nAAh|{E%nrY zR~r-*VMS-|)<(O48Jw3C!DX%toRuyQMZRme;>kSt>`r&mBflkeGr0*IL0mmzw{`+z zjE{mock9;zm)p^%xpFFSSv2(YVDErQV9!nG)Qy7L?&*hT_H`a0^)&RDM-I&AL@ii4 zk6tV}yaXNBtY4{HXT_YPHC`1!MJ~TF8lo&_m*1! zg?gg0=xlFwTR2Q4y*gHI-?e$(u`WeY>0&fQB*i-{@b58qGMEXT;v;+@bI0iQ_@Sl? z1(9Lj7CEotiP_{Om%6f#?b^Pr95j3;PP9qk6C|b%2cheFoCpFo~>t+q-n)+sn|`04yJgN z>(Ue$%C>UXxN^0BJxp38-$}u<8OP{&FW;){fROmnZl)l1 zEN0Ks^4hHT2xwu9bMLX3iw|Oo4p@u1O>SR!X8^h`w#s+B5$1?id>B%iy^#N(qWqV*^mcw<$`fF-d!Qw zb9CuX-aFNSlCJ!HAP2=a%93)_WEiTtvjx|xtlO#&Czp}8WIibPmn^Y(Q%PsEUWou^ z8P7Z;!&&VzxvfbfNpD6!c8a|382nUu?J_I0)L7 zh`L+dbi*f;22*XfUkP&QMvjdPf!1IB%ho#_a3V}iUMtx>Yh`&2ib6uvak-R zd!_Zu(Y51GX3{b{eF^d!G@nPg=y|Y(R(dV9j!9WPLivC9s8JytF4@BME2D#HrAuYQ zR!$tli2x<7TCDlu`I!b&Fjd}}GapMIpyH0ek8;c{C$M-SyUfe~lVuFg@%j6u`UaS% zn6)yn`nZyCbsg(&?a6=-meyifM4fWO34g-eS5wgZwKlxJhUCg+Z)TUSu8mrEO&o7OCrma_X zT#65J6ck8re6jf zcpcoY?H~Gr*GrQ6gE88`&6?<#ub=`dZS=X6y$#nvcD8I;X$Q0n*9La^GubB>(2w#NW$^lt$R|N=^$6plP!Kw(2@jNv?#B>txMSNItDih}zdI+9JeNK^I$`{dIzor@ zUoefMo{ug;l(vr1hvPm;D)mIL!L_P_wtrnvuHmL}Ut55EeJ0N13@EBGOVy!tF}BG< z_^IA0o`vCOyT|k&!WsM;dNX z0<*X=Ki;w`j;m%~9ipv4LXa@;D`#r<^$%P2k9+zB@i^gVmRs1vJ(9WdP~shq;>${> zDL_=Ni#;yFvZbLnD=DTS;9v(K=hq!oUUomMzRwW5w||JJycXd4>)-Ydw;BH6*oU-F z2X08-j!A63Jjn8w7#Za(D7Y)SKnJ5o7vA|KUXQDqg$k|S^AbQk>86=+7SxT)J#)4O z^T+>&SqEOprhT^C(R#ojqdl3M=Js85vL(2107|yt!g3yD6!rv(K_jum&g_O@Q*TjHn3tagY)d#q#miatm;Kw29_ql`fCB}l9))hX={FZ5>-f8%D?av-#<4pRE(f`P0sYBHmAheK@l3+3Ck*L@c6F)OwJRWT__$+u?0|fc9l|<_L zv2unjp!eT3s_*3Evi5^!jsVd!eymlSVx6#PI21PSUJpb2q#f6QY|+xIsXrD#%Crwb zeTO(;Gal@8%o=dt;6W zYjlYtv+(CWGc%VPIcshgjW9@#RlHSu2`x+AVMzB#B$wmuIt741$|vn^O^3;X+}jdU(RoJoMtNaVH7^sH!rNnx2up#zC@vRoYiIPr z3_2aZ@4(=l+tf=vOTi<4{k${0F#1L>m%6NGo(DaF$V3p5BsK4o=d`dUn2+AdF24L< zkD+8BYpYy**1?}wG@u@EeJYp%nt(5Bo4Xzh)X;`b>fZ579?1TV@65aSz0!phI1H<~ z50R*I!t=mbf7G=_z3~I0(3>?V#~b}oOS*H0N(Q7O%H!L3j|Wmz&Ay*!Tjf!AAjlSu zHTi7R?8A?#)#Q&{ey4sBv_e$RH0^xz;CPY=>l-~Zv!EIjnyG&25hO_;TJZB6+6UKy zZ1KQl&vvlbkT6prP~)_lX0Oh10}9{5>CvUqjneA=nRPo!5I4^?_O`STm@&amXb#hT z!=`OvvwE^Sjfc~ub$s&X6)%aH=83L9lQ3DsZcCYlv;{gWx7m>#^J+k>YX@xO-2LI} z6O?B#heALhkdaAc;f9e8ZqH#UXFTxq38)vTu=g# z&206$9F|dUN-a6aAAf2Y)!8^sy5rV}rYZ8z`-YEx%AWf*_QW2u5UA%`V3-(}dF_=R zLGd2k%m#>!+~;GgeL_dx!%AnQXqie+%|wK>&5|rTyMCm7T(UhF&{wY(ZV0d`NfQ@& zw-wTx9?<0NbHN}ep9(Rac{y>fRxM<_pAb>5d0ZC7^DuOb*gcuCbib%e~V z<4`1NkA|=t%g|$Kdp!EN)X5q2V$Ksl+bxmgJK-KE1IL8S_ZuxH$)*_o%9#p5CDr9)L~BQal%5zUI5dYIALe{^$CDCd*suKMvExoz^| ziTcsI=aWejE~p1jNY^#5_AU*1Nl^*q^b^2PyDs2djs*0Wj+vd(7-T;4i0i;ZX&zZ! zJl45<&XT4eVIsO2lvpLSnt_1WBsAeQr@+GA5A zyZh)ryX`lM`$6HI9!!JKc;q!NW7%?kE8ZlNH#w(!T*JwY=*#H$5v+QhS)o^OSI`zk z<2^&y7nVVA_ah@K4nvYzgMG-`lXpBYS>^AR8q6Avysa2{f%yK2N`{Y>XEJEe z4JeQzH?+f%3{>YEQ@Tcgk86NG?sSVh>?7b`2#w44PJnjiKX7qWTIrLG3=XD7Hl;^e7Qp!bm?R^@ zMpiGRg;yb*^I+Yra?0)Zglim)Z+kKSG=Zz^ddFybh|wSQ9xft#d6;W@LK4$8P;)wH zN824NN;sVt@}PKSHNdE5g9b^++!&7@8g5O?f}d&y4|+lgu3(g$h?^F;E5bCJis&HP~7O9u!*Ycj-uyi>&1G5$&H?2ZpI3uD_Gw{flB4A z1X=T13Jp*R)jK@uzXDuOg|J3{s4|Y!jK#(*3N$)F!+QLB0ijmxYxJ5Uibr03a2gtZIv5 zQB76vt_xm~hFe_fyl%E!U#)N|24?IBE(=+fUp66%E4vlj86m3SwSeCk^mEIrFVIqK zPbX#CN|`MP5;BPS1-;aBkJvJ3P?yL@j}iU|d{tee?XUG>1;e!HNZoy10rWG@hZuJD0a=~q*KS7hSo(sI zk1y?U*V}xg4eCuQ9~rYJ<%$bn`UbEzFcF2Um%ES~ZV1?ho>ZO5s<&-javb}B&yueJ z?{wO8-t=Uar=vXBw+=QpA9!P*dC@|d+tcK{EnY_)qP$?#(2;7eqJ3A9Kf|WtPelgl3kYOj4xzjdBV8XEp#HszC(PLonL) z%Adz1VQ*8bk0bdA?djGQZL_&ou)TJdiza8j1fOxXW1+gKM^EF1->x+e()1<7X?%`U zOS-D+w+=+p;uiU%sgF3Cy_+Eomg#+$;h$cFh&p>%SU#lID~29})BnAc*n|d}dYX!q znjq=Nltazo-^v<`2%Y*jdup$-yW+KDSed525c9u$#H7e&oG=wIi`pDHDY0PcZ1&gd z1rCe!)N!UAYuY^V)p)8)aB2p3kRsm`L|h03QUCcoY#$iqi&juaZe>7HeQpbzPt))> zczZdWuF}DMb5`Z?psor|`j}t5hv_n#P z7VBT<3akKk{j=q8+{V;x1-_}mZNtI~X&(REIga58Nj(--2<19HRWS3CBu=wXk~jza zE#`Z(wO?~OQ~2DhLtq~;Cl9p{9`=X!L}N_(S^ll`E^@3TBCh$m_u0`BJnR-eQFW(Z z;qh?^`jVfPO*TA1P_dHjpK>;4hDMekv=YtTLAhmZB3;a?#$fR1X4;dv8;j))*A?^S z_9ZfV_F^vHvf`m$+(>p-&E`I^B+kY}S zLfo9CJ^8J5r|b2?&XvccmhXP_U)hY3{!q@qg)Lo860q8NjMUAyyG)kU2ht`(=-2+9 z+riB{iG4d#-j~HcXvdTPu^$|@HdEyn^L=NGID+PAc&*Q+Eh|*^Ue=B_V|!-uGJEOt zRi6}{xxU49ul0ls=(6w7q+iW1#KG*c^>z2Sl~6-r;93oOsga_3pK|g10kuKg*Mz0xDf#^x>hPUsxx1dg9s-VKfqSG>2hJv)&&^63W-}175wq56W zg4R}!_EzPqwxdNeUtZ{=Y*$SweK{tGB)U0?n9ApM-0Xw4Jr&Id#(at|Ibap$IcQgv zjOTR~#b&%R=DkE}KN@Pke_0SCcJz`jH4)fNMl{s3J#eIRq*YDZb*s*?j-|%H6Qt`c zmZFdqmK}N)-ZFRo>;z~O`Du3POc~)S6RaE%PBIN^FZD-v8y2J$;@k#ryHzl?7d;hG zo?=5sy~Yf#VCgFX072tH*lbNX=qesYdrMo%AVYjnJQR!qpFC)&KddMwGKH@v6@4ct zjXq@YkKfu2NjcfD_4Ac$_vIKK9=vZ7{EDEv<}1I#)4DUdFN=@l z=m%Y3t7L+$r}|huuoJz0Qgovn%Fbq^yV*!u5&k|AkM^=4@Mvxi1Z_j+-;HS>#H(*7ZHD_2f@AHjLBmNKrXqP9Kkof6Ej+;wZlH-FZ`6&sNS>>V`HZCGySfHz4KTAq<)uWG$ zhZ>3F=IP@_Il*oTfb7l{&l^TxvYOnuBP-IPU@g|Wnc7#3x(Cp|N{C@~O{Rf5D%P2| zXxxOLTK}f?K$3xo1B1>#1`_k%MTdv`s)nip>}WT=MFH7T4!p9iWBnN*VXQ5 z+&&$Vr7Z1OK#$ehZRFb;sNPT9Ns>PC9gUdZ$Te?5?SgvnBfLrD_Pg#$hMSJ^AB^MwlhY)Vvw`hI&_SBEoTjD(_0l_I1Ht{B*1B4 zU&5iR@R*MRW3fE@+F&Es<*xsVnvF-7%0~YV%?|_(=y7JSI zYpk5VSmrCj7?%i~2;G!dSLqhk-heG7#`{~tR|5GUrjN%_@ICJ{)s`)DH}?^uj)tzx z|AV348F}mWXgk&(r3_3yT2lE0YX1~c>n6h!ug>vWr!k8<*!07-J(H%>jO;|fseStj z^iHgg$JXr+Za&~+$G(D?-~Yxa=G6yDNoOTyW3G)BOIf;!xwvh7m-9{3ow{BtTPthl z+#T*WWLpmysb^~j%-2>1Z)Vf0ve!~~khLuiO<8nj%}OfZ*Prqn+vD{1>fpr9~S4$9@O%xV|jHa^tC$CT?S|#gDweBR&}U zcaZ^gX!siwoT$A=mwn%m?54q+9Wl3G$9BYvb95=aj59vuZ=bp2uFrx3G#7x^Pgq$? z_ru+XZJN77<`l7KnaU97`O85mNY932#OB3Els+Dta=iq?$1cY*4y@cHv#^=04!$2s zBt_rtqvtz4qsF*>|Nl7p7JsH6|9eury~W<8NN$x|5<-o+O%%DV@+surXuKJ@4!a>X5t6t2{eCIh+$Y4$WpbPQZH!_3_Wk_}ugB|kUe9x$=XuUmqatPXJ@Bs{XVx88 zcBP$1SnaCz_y^f(@$IhzNuJf+8P$hsR=(KU9r;r~R*%{mjogX(YVIF+8pQ@&>V?oz z?dKMU9sh3VAKZXM8yS|CJXu8)yCQS$jSalunsa%D_Qy!i^(_~NFVH@&79E_Jt(|yv zr7|5G4)fHOsRz)sVEetmntxrU188XE31|5jYeF2g6LO(s^JE0aD$~tAZ5x{kIk~T2 z^PiH|*sECG{{L&+f)HDbz%#})d{~`!y_Tl3HgQSvweSFPq-BhGZ_|K=#UNmfWmQ{y z9VVM5%fk;>?K$~LY3m!S1efkzGpdFJlMsILxp&X*^?pWKD~yLE7JA>ld7%OJa4FbT z|Mnk2G>t^VEx8GHzcS%87d%@amxDqZkBHChJ@ej=AOX%}s;obG1nUFwmx zXZp1UD-MyBu8;2CaNB}FC}H72EZMT92obuBr0q{mc%OCYVta0%0|^oI{Wo-Vl(vs+L_es`b?5oX=9ph=WpB+sfef*kPc8J8Zk4M;+w9@)MQf7f2 zlWj&;uG^cFi7bViccn>Qy^=(W23Q9RrjpB=i>())#VqatSL(W)>{+Pj>~ zeAL*9zQONg?eR3A6;5C#`uoozz}T8BM7YzW*810Hq>npOh$k4%T#X+Q5*2S`puhGJ)#|NZ$l^|QiD2BCLV$Q zxVam8s6+E{*rJR!G`Lt5?~?Vs6$k&b(fm0{SrR6`@aCxsnGA2Gmr~LKcHYaIB8JpO zfL>abFr((O*W_DKs2*%rUr#^I?#G05e~DI4 z2jO;S-7#%E-X6a~`cAs&|7w+$#GPojWkG9>L?jwbf!b3#r!JEX+fMS{;O=3-PRY+! zc0Wb+^k}Q*Q^aqBY8$KHel$zklMn>@Qirh5$unz=NswIj2Uvc?RQA!t1j*))N*-Z3xs^_|Sv>C#9&I$(Udr7*7ql^OI7q+tf(FZ; zpi9pSim&8yr3V-67uQjkb}$@np>JHR)A4`8h*sq0Ud)i6^d%z}fg-Z%nY0-U8z}g{ zo{?S-t)Dgf1!jKnRUmvJ+or~K9NoaosbDi@)V;bjvkWx^{&m-GU!4oA?|`S|&_-{r z$vRPI-b<@n$N>E)ltNZvNj4&;UO}QEpUfU{$5d4e8yxehN->ZdO|c*x8Ls_D5Wor( z8(^*4mA7ey#`IPlY+T7OU?$-s1A0hrwqro7mmg2n%t8gL0=wO!X~vi{;PK@-UQ5^t zMt=vtW&Em6u#@o&h2K)p9G^z7`IE)NRxY}e8+a#H^i7W0mLKFw~bmE=lFu;zaIQF=9_z?(S z5AoApP699d+q*ClH5Rm!qw&!XyIR0A-siQ>uF)uffXDfczhxawHr*lppv-`~~W@uRjD65#Ovwu4RgRUVQYNZl`><%S0|H8l0y0QCsM zPS+t()we=`$`ZO38MIBI7tPbxw}$2b{B2hgdewxLS&LRE&tK`=x$4}j4_d96Qfla{ zxpY5D!oFJM_@BDZUgqP5j{8oe-5E^Vv}EgBWcXV4Gr;&Tr${Nihy_rKj>1n$)e&~_c;-bju-h|K`PQUOS5wTFQZn+I7Nw?e3(oy8bnmif2COE? zzW^h;&7mde*Wsq+bg9|=j=DkQP4UQeW?dzzBfanA`Wx%#eY1Z;3IDTOyt4zB3P___ zP5}B@@qKbs_#oYA@wDbROBI&6c-GCO-+N%(&SQ*+_vTlHw&MuYuKIWKZ0Jdv{lHdb z?|yn4ok$lrnUzAWw4FW*pq!RXjKZghfGdog&Z9mg=U+~Bud3Gr`ish_E+?zGU_rG+VV0Xa9g=qa7t%TeQk2x-* zSnjWsp!0Qq-3L=19CN*FSPfb^kBkQIB{c*smod7j-rt3in7~htb35cK^HPV&yd_1G z_f;)7t>UM5b58HR7lD#pv*{0xE+?YD{GRq0|GY#JBkfI%7167!%vOsB8zp}*!s*Mc zOah;pRa;_}`uGmDH9tzL0tk@m%6Rbn& z(^zVx7Ktd~NQPqc`46(3f$@^ro) zTi6fzKSZkEUj?HaCxe$T^|0H;EY2YIRNbox3o;eso%emCWg zVUP&@^3eO8vbE3jK1b4+fUDm?S$ri&sJ-%pJo4R0%NbvWR!*!1;`Y4U&|)F_O(3LM zP*nih9rz~rtU{!2p9g!0d5Y=2WQgw79|Kp&ryfSX7hv`|JTfjtK5r=VVFV8ZD}^wE z7yrw>9e6YU4=Estk?{RFCFcRp5;df@hO=5exo&;@_KdCUQ>yB6H_u^LB1Sgb*vewu z>aoDm=B4Pz1*-)(e@ajO?Jf;1ye4XgFxeeAH1Z7pG`+YeH?y*(ZLqPgaLQR*A73LY zv|?BIPVWX%rs)yRMa%?CK2%>7B`F+^OVlJ1$Y z|I$DEmmFmzVGrHB4`2HuDB8?7IE{)t-Q3|dZ5Y~57Aca;PgauhV3TyFGoCdH;OgM_s zMZsr`X4P=A{i$Ziux8aoO%5;=)0G=&0(HBC7JvVV1ETqHxdW2Eh50$oGcfZ z8C}>vMvYbBRlLXfK901Qu=6)7f2e(ph6Tx#=1D=K(4LPs={9W9 zkN z<^bjmR^F*6EXIDIu}c@jhg(F)N(Le%!bpoMfS`8WMTvf0*;z4AmYRC$c8bcxT;D;N zpWIkvgI|waj+kotX;@?S)ZQ&bSGc1~>3$H0@<5xOUFZ#lMv`ACv%)Aymve`JPEq^& zGfZ0MuCF_F`+aKzkG6+A{XD^I1DZl#GgbI%*{tq$Y*{h3(gKu#sxbH%5{wHbBoIS% zGoYrfLcK)o@-)gYsQJJkQs)COq@hiQ%8CQlg1qJ3=cu*XODjEe)N^8E2(CN%%gcQW z8Y@imXg#D996P+^(S00L@@z4AXpi)Hpym6XMbp}{ z+EIG^r)?8cTz)qC-3Zr!@N04Dz6o5%4Ogv3^F2s2B3{Mc1^j@a47F&~7=J`j0B?RF za%84Xx1OP=-if?uFT1yWeZ8}wh22w@iTcXl1*K;+KNqrJ8q`(;f#r2*gMYODm#V2J zu*4^kzse)BQmSa;X?;UV+j~L8qf9RTVPr_%FSK!!erkTF_n8+3TBF$Txq!rTLr)De zXDb96vy$w3q#Lth_TP@Q3>m)|5?quFa0zK1U0627)h@`)J8MncU=0EVpcS|~4v#&0 zYidVdrY(6Rcr;H(+ugk&(n2Bmi#)V#s)UpNW^a(INl!@ z0eMU=UTW>D(FAL(exd>n?^nh44?QHRP1AknWf|*|C&dN`i<>!|1pfNbZ-RIbN36=r zVmGy~TM7&|D(;eeehOgxbVMwf*BlO=*Gll}m~&!Lu(i(l@4w<`7G5_5Yjf%4GKtgS z(~lk}M(6p_<6r$q%9GCHb@aV`WtU!Q{1o73nqAb&*WHPed`DA8Rs4Bl#68iq{_s6| z{`ur(p7okEhBfYvOL-CeW#Ku^U7KY3yY04UtoF$V*9q~Hc!aj~V3=+_@4p$X6z-+# z2I;KVX4!ML;;7`!>%_0U#GRO5TwRU}TCX}ILe)i4-_@0tyk-difbB?yL1yROWja?K zdQ@1IoGUFP;Jp5QOg&)!)#+j+l2WBik7(U?j@AUevgqp|UiqV@OMd44i7xr~AkUg8 zUoaOye2Kx8;g=~H8X_@axd?{o@;eEN-aGXu9qeZo9Yb4+8}$Hb`(c4S$+0z~e^-~e zh1FMPJ<94dW}H*i9fVqh@XVcAD#{ONPfOxSo_~7gbI|XvSjFDACqv!^#zt+!mFN{} zU0B6`!Ge+7CwhpDF0J;H6&WIW8lC04?p;u|K-f2kRf9?#-Cr~*9cRLzV{|6%zqeNLShqDjIeVc$;g zK#*PW#Fcp*mqo>N{WgRMM#I;1Zs7jh1h1JwA^%my`lX=ZVNDv^F62})Df>E&8O6V` zHCSU4NYH&a)ub!4GbqpLJH1e7`7%|ri=LXuin}Os7>~T6ircF$g5;taiNDJ5dz@3q z8(SMoI*FB3WkKVD4fIIuW7!<^s?{TrIXn8v^3lf!D|@Z4`o<%7(<|~yszE`ZI?1qg zUBgrx*+flD0e7+UQjq5C z?zYT~oH1sx`Jby_2SN(WmvNN=R?RIfb6+mCWR(NN<)w9eAUm7$% zP?1XAD_kAZm^T(&$#2!{$!l$WyECFV)jMB+qhnSg16U?T&u<#ZvzzPGa*EeuY+f*I zUPNl5&1&$h+`F}=#rMAGJ_hH&S9w_-3ZWgc`6_|va5GARp?2|o|B658)T(I2G=1ve zcoUm_gcSu{15-o6o_%d@#1>IaI5D$vb5hP5m%`u*9ibh)4PE#70o10b5qN{hpH*~D z>-j^gEAF*%YPb41iGKEQ1Gb*iAR^mi3+-tS~LKvJdR4r>io2T#g@X3$`{16WYeqqI9cbq1_RAO z+=EvXe7o$5d_;Vc2m1r&2Xo=nZ&qebopTzg{KQXwf^Cj#`>}0YMzi;P_0h)iIdW*Kx;el>jddGp}q2D z!rwDeruHob^92Bco;D~@Jc2|Z%o4C@8Mai@e+sq@b`gvG@+Z1c*GS$Gc@G%FwbP-* z()VIGW4f|L`;Nz+)31Gwe3QWkH1%F;lCQX65CJRRJ-1aUs^xV|&ROSNI=&A9vmqtx zAim&ik~)|`;+o$MMY(~Yb&d@9&Z6wc<2+Ia|9G;B?4gmpjj3B_HhO&lAL%SmzI?@L zqFFT%eU(dQCwZx_e(~UbM#Ij*JxzbYd(bz#dy>!DaiVw`O%C)mz#XL&Edx^U*Q~p% zTW?iu1*lZPKVyf_GKTgP)-qh*oNy6`8+XgvRcdkZuf&Eb6;)fO2QV@v^ugX*6v5~P z);T9OIAuPOnG9!KWoYl)>22_WKk#P`q=-@h_XeQ4xW(TMFKC0f)%)r^eUi=_uTFZZ zvf8;T*Y0;E$0hJ={U-s6C##el#!@9gZKBYV?sE*wosQ#bhlax2M?6gZX)G{=jVZT- zCgm3mvY9;JpjDo?kp)-0C+oLKglX?iO-YdGl<7y{#+@3Y@1g+=VUh+zZDWHj;?mmr z67sT5|NW2_(0?<9Y{(v90-2(%^1m&G+~U-PkUjEMPzRdMx;9n5gr;jptJ+uJ@Bq7! zP**)RqozefU@OUQwl^M0ur68oZnn2ZOJr>69w~P1-=OIJyfIUNiu(@q-Az5Rd!r)a z+Q0r=BbKqqv))a(9Dnb5fEotQpBz_R*c>JcUKpBAiE*tRuuAh-5{S*swypWmI11LyM3_@7ZK(+0txE zzty9R(WJnSW7ZFLS}!l>jyZncUhiVEZao*knAD-)piJg+@*pEttr?^@cKc$v=2Mx# zIEBER{Cgb6p6h?61?r0@Xj3RGA%FD5VGl4Lz5YmI?)5C_Wc(9; z*Apf-4x32s>4s!_nwZ+p*one+emDG30Ilt*aCV&uS{BBs$gBwl%oj^}>m=+H764{2 zC85xYSTjOuy8y5zznGzDX?W_+GjW+{ZQD~+gbmobUl!h4iM2Cr6~%8hu_KF7`~3~? z?cI*I27rw{TazTTs1rcspwrO)W(0P#TkFGjjg;>LG3(n;a0juyt%Ke{2l`_w_X#l0 z&6TBVMr#=D$oIOcorU1zj@)%E%$_)xr>NQ>&6DI4;5lPXdFxAnqI>$iFD;FVVf`X8 zqY{1Mfm2k-{!!T%Pku?)(3BWF^f4`x#OHl5S=p@BqZW{PpA2nY5=F~6?#%_wh3-F_ zx-8rn16c^p{Q28~Ch1Fl`xT8&vFN(f8gmcmo=UwpJq~-lvKs5i$wrgIPN7H7g`VqP z>pAKn?j{u*YhNTu%WePbQ_>me{J8Sq)&*m?T|-`T=8G%2#cv&C!tk%9I!go8%Nv&a zz)~hVB>oT#hq-7?yI6);S$J=SwC>D;pgkp5@^Il&r=-C7axMVq_{oo4 zEdSwm9{(O~y){69-y2Q8H_ZWSB9TyMe2$0UQF0fDI!I3(v|C=}NFkqF5JvO>&@o4e#jzwRnXNnu zxx1Ro5!zm}pczp&Hlw8n9CiCb_e8X-;oesKedO6D!b4OgN>6mju-@w8hJ2ej;O?V> zLzcAv91l@m#y4%l&tj^So$GK}-+q7%5AmBEr{e8b=-4=`jT*spz3McE^?ETnJ3 zLA_|;7>0G3Zho_~5|3DuaqkdQ3SH#$`6pF{#{%87jhwyPCb@CDKr03T-Z^{HCF1*0 zjpT>M=;0AjJ@Wp83j^n7OZ`8t6JkYAJ=a*=uO(tx?~eo#E*qiK)NclJ+Vr*E^l+Bj zhABNiZHH;5H{~~YB;o`q((%e18~GEw-%};1sViUcuuvTOVA>Bso%*D>&KrJ;5*Y5B2AMa@^%vlM#1z+&7jk>cG|r5h>5Eb!0dkgWZ`m)s#O&kaSoiqMG0V?8I{|$t6P&vW=Hk5FfOd|w<|Zz4^^Jt{d8j@9kKXwQEI_z z(9ib8jj`}`f#9+=6d;dvw%O85#CFz&-Rgca@azVS5K<7p^o-~`w_4^q_jh5^dftQ_ z(Pcq4`0pRqQY#&K@VexGQDx7prk_rot)(BIr9grQ0_Ux5+ckGSxvRl> z7tX?i2|QbhIt$;UMiVf}V>re;xQXl2=Z(M+&jZcy?F-{yOL2iiMrSnXX@0yTbpj(0 zP&VMY&O%~YiKmpQg}m}EyzT7W1DgVEW|yY#!GGEk!R9(}T$n}O!$OC#G1-taA+-q? zN>zF!gkLm^Pw+NJ6=(%}!{h(&t))OE!c`lqzc8Tz7|#A?8=~JA^7%?i+DS z+<6{60*6YT#)#~POia%$3(Ewq6*aE(r@f-acMxN`z2)M(|JoAgqG4-+$4VSqIZAuu z7*u4AF5W<54v2>we=GGq1@ALe#BE+eY&$FV{o5rrrdV3KqRBb~PkVfxYhV|K<7OPU zV5lRM?8Yy^Vh@w2PXyg*)t}3nZ#ZjDDhp^$Q$yb7?q`-Zhv~YwL-C2*dEfxt#o?O? z0UK$SE?a=Dgv}ootfuXvKaWrVEgR#TiBo|*yv&jh=VoMQxed-F6%WcMT<`YaOg!MK zw!c&J*lcSCaa{*F=J$>D?opm5jVed zAFrIc zM-^%w1_E4L)4l^xGC6t^)4=l~vK6GXBqGQvr^ZO$^}O?(?B}^Bg9nC?ag4}~MJKuU{w|c#P#o%bC3U{nT7m4rHedP%8-*&c3=VAQHOsy%?{XKT_ z%n2g6M%{lm6FKW%w&@0Qdr7*tZY?LCE;_14>g%?E*iee!B}csPFSs&h6TCu;r3y># z?AQk(t}>S!`m(<4yl1^TcHLYKdDHx2&(coaYx3Y|8&URzB}`}`G-V*58&jFKlhhr7 zEQAkbI`x-x+-ywlde(H+P}M&oY>BKOSU2vN504$?$X?2 z43VC?_@awEhArhO86ElZBs9^S`96`?wiNp3vv4tjA@tG}&BYLA;HsYm9CjQyWi-Av zgFM19v*4>)fwL`K=nr{i@O?f0rm(5}M{LpAF!vSW4U9x6RWpc?sStYuXN z;&;f8J_BQa2C;i5^A#6vH^o-htl#nO{p9berp$pl?5DRN+~!f!G%b$JE^*0?Uz1G@ zmcxOp|Dw%ZW(+!n{i!7rpEf02&u`s~`mWW4zz}W0i?RVw4sAiF2wj*XC+21aU;Hn* z#&LGgn(|_t8fz=|#FIwcmiIni`{%l;7~$Nm_xas(B1aF*Mm@_Nwn<-wsS1#v**PR($}|3b%iq0qzj|2NCRaZ|4eiZ3#0US$Pa{?mY!V9@Y_g}G7@J6m-iW5I6b+_AA*$xUQu5;sO!Yd zaqM!Ejz6DBL<*jK2xUZJNF985%6G{wpS=E{C$M4~nN@Tw1;b}A18fJYp>2I?OXT!j zCTyu6flBMB7WX!xC8@IMjz6mp(+5_M&{ zcWhVbQgNPy=vj>C!7@}<1BeN##Jj6yPJJtK^Z53lCttGwb4$(s<)kvcA4;4@SCB6@ zsMi?ZG4Cf2bjir0t8<>4!CP-=$FAt?#pwn+kP~jVnKL~!-NOc4lT?eo3fcYhc2??C zf6;zv6-jQ~mhkO^%uO>z=ea?kjSuqzN4NY}rqvZvyZq+6FRUycWCu9@e`tBUx*L|X zMryYdTNO#sdDrs(=o0NRG76!&LC^&}4pHaE`78z3eZ?vv+;=PZV=vllzV9B!?W^qT zE>|Z!B-RgdZCTJtST}EH9Gzdpwu@Vc;T9m!{ma_p9lB1zQqV!_c#v<@VG(=kIc#_kfR>H!}*T>ESgLm4VL??BCTvX6Ves<>DoeJbh0sS zZ_Sp5$WpkL#CpW8=3_1S@WJy=E|<_XGlz>p^h0*kggtE`lqk%CQM(-G2uzv(3cD0+ zs>DTA_rZ2^RsYU0mmfiR`)AcZpDD0+sR`GHlg$0?5VZ+8|FhCrFYv6@nqLKo>QU{V zON)1nrcJu@AE?J`x9fSP9g8@Cssovl2dzi(i=L@+iR6z58)wC9;7EVy5<`zYWQ<|ZvSnUw9A>ebxMXtb`3r~oWhZ_bX zH9RC557B98v5v=$L1eb8YaYDg;n#(;prZfqY_IUyo2=HdRfv;9o*mGPf5E9lP@^A@ zMdeJyZRTR|YA_dB;kl9~cTDUYss6I$c*<#)=BsMI(wW~^3UfnIiL1%l01lMjNv!5! zU-X=9<<}bTkOb{o?Z|#Ay)}f%!*OoPaN=rOacw*YI+Ha0{ zo#qyCEDq{-sPns;>B1#<^nXZ$eElMKM*2u?>k_fP?seR3W{+0=z7**v#)u|h*lnMw z)vQgKUf#hGL_U~vNFuk!=WgmK?D6vJT;tb09E>4VjW+t)dS^8ZGHd|-P2mf2$W?c- z?^5a?mc;azPfDp;<7U9KRod1CtaB=-!9!fM+XKNZsI}SW_Qat zDYMVYLkf6!q@jVRz449(1ZL#TlGMQ@VD_*#Pj>$(AzDSm7My%2ypp$W??iGAhj7 z%?eH3#q+=mS~`EOJVs7L{{KnqhQyeBt3%;-o`;m)ev{4Nqv3F4qu zIEf`2$&&Pm=S7y9Jqj#tV;vch8p(B~w|!e_krtx38C;yszL{IsV=Jo4FS*)X_NY^C zAo`g2i7Jq6wLbZ~Fx6il7zE*SO|nspS=h92QrtURKLL9_kn7vQp+niTKP0 z+yTCXUqkkFvdv|hk|R3vu}KXTk{lAMC-Oo-gy(gxDf0}Ke1Sm&0%%nCF5prC42g*$ zuo;CBDb39?GIBDrj+q#J@rVPNytB>K&(+N&)Mb|d=4#+#JufpnIn#5vOyKa(f!&|G@4G{J4!%4X(`>Cd*PjM?#L9!6wns5U{uLYNDvd{S zA#0sZov2at4*D#C^nH3vhbvQ%H2T&r-L)96L#-&i*)KR@D*+1N#<@+E-JL}yDEyRS zXpk&?H@|q!9BHw~les_IzmMZkXX-xB0B6`VXl`WlwDlRX&NL*k%`6#@K)Y2ZB170mc$-c7p1{)r zDc7e!I{oaz+rW$6y%>J<&Sx>XI8IQXh%pv9dd8*F{G>_XroC{xA4G2$m=C)in8!8t znSpkEcYZy&`zblq6H#taWu~*1lD}Kx8hxOA;xF^w(wHWqR{()*@?E?AFe=l>nG4x9 zazboX?-|mX7x7)I_e&1d6+N`^Zc+gkEg zXS7A#8oM&v&+NU!^q2~+>PI=MtEk^J0bT;Ct=1TG&gQy2Dao7iSAOmBT7~X6u8u}AJe-Oh3$+&|GDpWiCUf-}>AlB#=vLymBaU;86MMME-m%92= zt?3Uh1GU{2ql=iQ7ysoEU7EGk)Epd1@Rk?1@gy~*hklh{N5dQo`$}Yg8XCMzerTlE z0oXRTrQaEr-8sB2K-4>08hSpx{U1ma)ED#_w)Jg-d&yS6ptE-SmAG4^Dl@soLR)Q- z2nJ?%LVl_*;;k!Slbd?XB&r>U}PCjvWHx%M|m_J`BA;yc|p!~h%&s`<)tOAteTqdC0H;?*L5!|=XlN#%#{L9s|K*wpKvg69rfkxnSY}?4u zc}nB#6P%~R^7%Vh2$WZ+_uNA5?c=1Wc&cv{;&8BHP33el0Hyw?iDMLacR%&TT#i+s zc&PKV>q!8GSI*v9!0}IBlE$*#^&@B2Gta2xF^2+#c!Fx#{6)EjwdfN?NV_54$Zy%j z@#dJ{tsMS!8H=6Sl;XS4dxjxZ+)7wTsNBNm z3)MMQ?{`x%Pk~S<-1Rnx$ZGd$$TfF8@fCv4Lolbvst8Yj`%sO7J$flCH6%;PTqn3E zzr;ZkAkP&GL_VWLV9(zrSbPRv?BQhS(B#*j=nGQvmEwRt{^Bkv5ndJ|eExb9$9I(i z@*;3aBmE0+E4#?g9qggimk4I~wbX#1op3bw&QmrK_9z-i3mDCuj|p#tJ3ESr9>r#^ zruuBRsI&uAi|r|F`rZV6JKY>d+T;XTbSAQ-0}r0T;;zD3_lcjjp^{hO8wHd*+$-c- z$3y8?Ch$+n`;YFR{);{jU!siaV#H}5ox7dq}&u`sNErqivtx`K=U zG3kVZ2~GGdTP2j6alY1Fiq8@6IWsDsAdg;qc&Z!IJ0s;S`QZY%+5f_B4N4P8(TcUb z0SwSQ0|ec+P8Hlbck2`hisq+Lu8;dMod;3-iW7y95&xUuaW!p^r0 z$P#ooVwCydJ+QIsNhDVLuF1>Ch?BovDKiTqf#nIxzc^Glg2?T_y=s2^!AQ7ahVM!4 z$K~Esf5M7}if%HtuJIrnE2$@X&EvLlU1{?mKzr@X%P!0n!F-f!RF1FH{JU+HPhpHg zT)ai_nTAhJ+W!Kq<4ZkPUaHSklo=QJ7gtu};&B?=6@^p93Q5&(cjs*xtsmC>Xi;KG z0z_qEHQ~ygvIbI!MX_*BLCYc`jyMfV=OI0#@!s)n4>p@WCLF5p+=PHC0|2Tk4hvBl zdke_#+t)sQjI_qQp^Aoz4-E6f`^{hUGuFL#(mfh0s*ch1)j9ds>u~h&a5}2~~Z0NuK;J-%G6{e8mx>iQUwzjpuyOCn> z^}LoLu3&F2f>Vadqw=~ltLrw1xGA}Vk84&5^x$_&N9mXy@HL_|@uvH9KxNilqBapT z)thNRyS;jD=ZDs0(UI7r*1bGV_*e95Z3gORo?RW^)6>5xTr2MM|H)P-1YMs?lOW!6 z!Ml8ptuE?ITI01JtFU2B9hw@R7TYo|;w8~vU!7*Z<#t5R4{r>}`K=Yz5B1tvP~x~T z4tx2%A4iNO{1fi38k>TM)x(y+iDVI5_Km#7qYS-Z7KpZJt?zJysj#WagOArNL?&Jq z5r)IbarfzVHzLp7rAAnP-fxBW>|2Z^Jej_ibAE6432kPpq^y)j@=69OXhbokTlX9C zUA0dl@l$j1eIp&$LYQ`s+{h}rsWM^DGTpbE>u||;w5qSg+@%!Sl=3wzzcRA2kD-Y2i7o@R`4s>oE9 z5m0Y@*@VbfTa$58PEZV}kk?^ZT75cLZ`$l(5(}%-{b*A_8O`>ld#HWR05^p=NwkeR z^_w7IT~lo;l-T;eZMJ_0^^X=XK6k^RC~gP=wnf_h8a+s3w{4tu#34FrPE(4Haw>{d zZcD)D2l*sB4bIE(gmPS+YiFN_?*6iA#m#c;Y_)Av7ieu!qdt0cKB8VRHK9k>(*K7( zhfP83Vue}x_Hzw5c;dd|pi%hti2%_1_+PiT1;(M_rE(UP_&0B5zCZF3+Oz)4%g*y+ zyZMND{JWP&?%UZA`F`^s@8({edoLDE;+F_j8i04izJj9`yhmb7)>;n!y4KI1?f=PJ z;Ge_x>tCj->Cf`0Wiu{(nJ$ihj6?S-2$4)Uv|7F5o-$T$?hl#NG2{4<=j2T0wmvrG zj1Bwyi4^l6ly~=QA9}w@bQ2Igsn%|kAdmw~-K5l9Pxp3L5hjj#*TJp@;;6q-hfl;M z;K~33Ukrb|@<9lLc$#n$WNehV%V(pPq5b77R!+q&wbr!<&FwGNTP?FzfEG#_^U$@o z{ZSu|2{GHT1ZcJInYim*XUCxDv`9ppR3@h$#Ng(jwz^C36|2XxuIXGoF*Q<0nQ(Wj z=C^ZJN7wz*oxEKXxkgowWUN`K!YRh0H5QZ&a?PF*thg1gr4TV+7}$*QAj&? zm;Puv>HJ{a9dC?N>%7KAE|p5J4^_v?)5iORvUddymsnmEuZP-v<_Od{M|kW8T53Ph zN7u*jHEDLBUp%u>`M9|)*t@`dipCj~89iOroE!Xnw1H=<1}Fa~*kKXWNa}Sh8yNBl z>|TW_p?ZG|PUO={?+D<(w{(=irln?W_7;MGnJ(Xr8RD6qEkBHv*U=oLQjo=Nh8QO{ zB0JU$>y9lrF6KjPK=9v#J-e97>2G}xa^AkuNzk0~HtGSg<>3gg)>};#^XiT)PD;k; zyt?89--^yM!c7_8{3VuM@LP*-nvQN(-~aRE1qrB0$*#`w z;02-FAzCZHo(o-Fzx^wKB~lkK7yK^S^0ZS8=NUa+%jTr{Q0~(dQnggIfsX4_;GWZYG-@9b^QwgZ^hV%aPZr> zul&WjRV1NDda5;ArPzPMIomxcxUyoPmAqAx(~Qo&L_RlQRcbj1|BHClji|Yk9COa^ zW*Rc+hHFjaKwlEG19Y(4e^k3Ulrxvqh>6lU(r-EZBhiDqBm*3rLQ5Q3{Z!p}b1;k6 zK5mKQcSBAD;OUdI66r9!Dn|%0J2mdf^X4unGE7%3^|zrAlI)CsXP9xcJa}D}@MU&P zvX-OKXRKdqo5~Np;Wf)M&jB|fw1cMSI<6RnUYuAAXzsTpT7xcRzbdG)xwd>edji+iT%044Uu|7ZQ-_FWV8 z*6SUw=D*r)Upab_JX0A*5f4~9-VZ&+Q~s*m%*ShtABw+T>E+RAg-S5~bXapNIuDLZ zdtlg=9J0z9?Kef5O4Q~HrAXGQV6ktQNyZ(Q0d2Dxu)~M`xalP|<*tQre#vjS@OgKx z(`u=}nH)%FPtevEzSyUD4x3|&x{2qFNOpJZIv4y%zguG*G9RY7O#7daWRq1`oVbae zXINuxqW46Ni5Y=Lxxh%ZUaa3KV5fG7N~$geTgzJ94I>FQiXF;z5zDR#ysU*whD-$x zX@Olibm6v|1IEJGsK#rn?I-pr;)4&dDNv%FkX=FcX30jbM;4wDDT<$SFFT&q&|OxQ z?2Gez(4Dyl>f1R>!<5iGb9rLLD9t%Z!Swq)8R=T9s-Y_+$A_^UTOEzg5Fh)7+FRIr z4st9}wqRJlP5Z$*<(S-lZPaHX}xFi=21f(TiY{63`;Yzwb{eFgjeSN&rlMwcaOlrTg2>in3B$75cl=#^Uegp^mJ;_KF9Mzu|LLpNjP z=gxI5An%$`^d(p1%%{8*(0Lf1=9pCAoSrR9OcdHigEMLb*`A$wE6o`yEFrupvXRli_L1629}p-Ix#dHH|LeP zmGeue)AlI-==G;T;;g!ffaiWQ*miSu0R(pB468e#rjPU*n;EKvMtIEt2 z@;t`0VYUZ7;?qu?_DeT1nQbS$Ya144!Z@h+2Bef0qZ*{FmLeOtVpSACwD`o6X!Mvg6WN!_32TAMqI@OGMqf0vTi71jp}j<;;?x6$LabQ)EJAqpu+HBi&)Hzc~)% z)TjLq`7!7c;~0SU&r;uc7!0&sr5hX^k3q@llGQZlSY6coc)fdvfpE}YP3aIM9jYA2 zQE}uEuyUx2zBC$F+x+;0kD?FW4)Bpw;`GT<}%$0Cd@{P{9Ze4vb@Zz+8e@yV;s;P#sn zSDhmd`;Z=(Jp1j+(`qv&HTq;8^3LO3)-rsD){rHp6^xEIM+!&z$Ytf~{bR4!czTGR_2tq2b1F;o9~&af7L!3Pg?+V<|3}if2Qt0*|DPnMBX-Iu z$z{6AA#w>Dwn`<$lnS|}C4}TM%r=))l6&SBHV%@L-0yeM=03MvCfBjK4`Z9n=C{xH z_y7Le-g~{?ujljeeBLAQBryDAT!No$G+Z6*F0b-3H3h`d`B@M6IC{mnrsa9u>Ba)S z7%u|1{^(18Bxh)5r?P6vZlg8yNA}sCGfYT>i&LlTUPmBWy5;$itP|X|iyN{KU8CIR zup1>zskKX$S$L)&ykobtdJ$l; zO=mVt3Ki6yG$ets4f6=hq+r9(8mal-tE}5LpUA=`Qk!XR#Uit|W`#KaMBnYI+fyvl zk#MH!-0|pu1z~vJ+l|kCRg;J!GikPPlO#4(?ZZ@vB^9N~J%p`_Ux5#Y6edx!%13{d z;mYn01!B$_XO#^=clKV|6ur~y2R6+Nk%aHfnC|9ok(DQ7?*lwnqxl10)~*vE4VS!f#hoU} zVbjEDy~^8#-o*H72o?{zI-@+POBfAt$vR=TWcgA=#Fdm%7*|QB?Q7`XM#Fr2HRT(I_;Gx* zM-B_)_>@;=lN5;YtxSDt7+M3?8`#ozy#Oi*X2_-c;Gq+OjgmNfcON+}9{Cd|+gz()N3oR;+}bFPM&%yb$mN=>i1v5yW3G1xMU{h$VaHBHS{si z!^(>@n|ENnnY+e+^c*itsR#V+25%g{0AgRB(B@rUpA+iaD+D>Kja~ZF+(F${$RUXB z>xa|i|ATg1*$J1_cKmdfBKB&Dk;~q<*$6L@t4=uUxH`V`m!+fA@bo^SUVUl*Ymr(u zY5Z`9>(Nh2@@FtrBwK4>L&r$C)3c8E)yetao0}^o(n$9D*Y#JNBe$~S<2=MP*%u^< z!VU85hBqFP19xyi^&#CC;|!Ro7It@m%LUxL^-Lk6lFv_AFiolN^evWpUz*eaH~>1v z-+%ktdcth%iNW^+!2q`-6f-U6keAYcb7+?a_#%6FU!P8eF8=E>y#QuwrV0>>Vqd&9&2slk&0jc{(+~O~ zpUjYWk`=pZ@zC{{>vvZLgALO;SNt#Bw^h$8@{=QmHL2@>>&Czp+(H;cYP;6R=8arx ztGhvqk_9C2o=gqpoLppHPW#lz1Jua6Zf&{pkoQWS1RR@s*RDV5b#d&$pYFLL{N$`T z_)Hsi*;h%wJ5P1@Bx|@y%`4D$S(*E%^!B1U@*8?(^3(b{fLHJ;rf|%E1a2t4+*PwL zv@Sw)*_#6A_Vb0&#SGA->ocKPebv341t)Gl@HIq>)jOOd*NI-gTPIb?`yNCTW1HG% z%^*q=z$?4V8iDIkTS3v~giN&G61w^3%7yihu8!e(;)n;g9mnE#v==e~SfX@iT2(GC zup&kZ`Fu{_X&_lZX9_9!=$8y7XdH2`&cFY~Yo)p(`q%*~<`hKqd%+OS#l!NT@2rHfm+ zuI?=#3Ydzlk=-`VvO?OrdiMS^yE7;)FH>|G@jf8yP@@}uqctkYe(<+<;c&@dKw}%u zx^&~q?ekv-y@^YO0P*Ej)O;7|LnQLTi&ldQW}i4?Wbb1C$J7wN_l+NRKZZ~UPVI?o zhNTJVnd^;;gf^SMs;&~w6@HR9!q0B_@G=p#_aLetf!S|ChPwjdVXCr% z=ZsKBIKdef!GDXcHk+jG)-*-&Xw>A{AUoAF)J z?&eAVjH&o_((8Qu-Mw4eGl}#da^>(_;8h1T0g?vL<}kt^i1 zN3EJ0HYZ{~?ML2OPVeDlKgTGFHLd$I!Es^YRTEIsT+uZ((qW%3+PJ^&pFnqlyaw?3e%X_5Xj zNBaZc#<#E|AXo3KvajPm`E-J_U&-~KMFe39?vt8aA-7z!qfUB|icm)CFw?qTC(I{D z1(?CSxc<*1V$Na08aQq}D<|x?-9Di)>PS@$UQP|U4+d6h0fZ5}WmzzDR-YWHx2=J}=tM;C-4ye2N>)7H;r&EQwV!k4|hqoJ_z64kj2~R3jEml-5rHeCaU4C9$ z8#$+gTVx2bn*AqaBe%}@wO!)O9PnCJXNyGMfUu-m?xB|h=}>C#-qTkG_dwXPb}@H# zm+=lU&DMw@g%QSy$WYH8xrXX~@lNTe*(BMKt|a2(>ySLL%3nrDo{j-J84tGhk7rdM zlyHprTcK6M>ZatSRjXz&w$d6&qQnFnSd_p&3_5=d~NE6tC z&1f1@MszKrj#y4}T#MG7ZnqYUSp7D(zI1PN=bk40`~fSIDrX1mlEZ5OS^f~Uud*Gy;%N}7as zkoQhMyQs%wx|9hjI}P#vJC(^gR>l(@Ck-hBk8c`!iPN6nr;Ky(WwcOvNK7!1GtT?txBd%l@b=g%PqIA3U2JR@&VW={-6rzuo6G=x*&hUwLWzoz70;lELaw$!2=U zIpTbl4`}Wrpq148F>f&~^ZC!NkVsx<^9A02ygxe=?a~iQMt__H=zjw)lp)Pca7pwf zYPxt(NbZ6?lP8Y8VV9kOSa0ahcC8zGxS9d(6!?e}l$*kp^lz8}mrmOeZU8rh(E(L& zT^(c+z=Sk|^%sVVQKFx@F$R+>E>3fWfNYuE>JN|D5G*S@y|^pgWg-QK|s7Tyx!S<|QL5=m8;^nO@F(9<-AjQc<8bq13^xu5{%Z z=b~d7y}!>YrNdgnuhP@KGXWE0E7COQXjDx)-Px~4ogXW}>x}0~KP`ezK}=>G^Pp#S zuRGP}CTR{ahSJewM?K<^_W5VI`4-F6wRbT?v1v^E1xAD`*^pT{=-qfHPF5C};UUk2 z_rFYXnf7h&ifn_w(s7zjgY5|Wb))a6{7yre?qHqcavrJ0^nC^+6QuP49=>mSPUK%d zBCi(Oxh;%#{O^T6G>!uMoGP?1TM!ZwWc;38u(99rhI-L2vtwq|E!bYjfPxCMR7@`SW*1;GVY6g z_j~(k;hM~Hth{7Y9Rhi(-|1SaZK@E?8NQR$?E6^Sd_ zYVKkR6!g3my}rx(%X!3uQ<((uyykT&^{tO$BlG~dB%B9*{t<3PBwcu0wp8u1tqAVt zQ4*Yu{ZUmYF?I}rSs>qMn!NaV88$hp9Cc%6Jogr4vilI_#87fql_c8u4s=SqF~gGl z7((gN$u5rbx!5upjxX=NUjXbj5vzQx4Q*)HK|9Kpu|EhLkD5e$36r4muwFOVS6q`r-^6DYDU+&sXkW=c4qzO zWYV$)@jaFf(6N$yA$e1>`*Q(S#-H|;`ZqZZMn)%4;T5tPzT`@ZJGba{uehDb_-LhZH12GchE}hkvK;NQ5;gzRO!P{ro72yuk*3QQab-2#% z_!CN>{hgu8N&G*TlQ@N5F)3M+*s&Ih3qCm&*I22(?w*+*kDkrn`Sj;+xF6t4|MZ`E z5}Bh1v8+y;?Jj2l6}lcF^VHxvWT| zMtTSD`&}pe8y}6wl=V_?>s>2+(yOU5EKcCIs;;&uYZHSjbf$iW(K@*UCuhaU{pxoe zRt92rPYxX!cpotIYDhVm?y?eFJ}R_pJpjF0ob+2|R%>_Ik*>b|&2g(L?RHDW15-1{ z(PR}_cXdjo*S*~D@+;Ws+b{%EVdf+oU5!!Wt&5C%E1K)+P%m9oLvAA2i>^F6eqNZ-Z?73xBs_X; zz1xBLkQ7m=@w$?;iy6DlBU#$=$iYovUm+Pc`%l^5lxBKFBB2n&yPM$#h3spX75i;V@R$?3;GOYv%$SG ze=>EA_QU7cn(S%Ndvm|3-DSuUgzDIfi|UO#yDqsR)*oQUm+ay2-*ID|t?9;HYr&$vjrYjJM0 zyj|TNvB*-g6XH6TFhAb;#(O?8j6(!LNQ)J+h{+Y3kPl~_@qU?_1xdKO>AkCYfqB36 zgBHhvX)atXPQ&XM3%ID}r9I_IUQd#GeP)1YkP8-->($(S-!$n|a zN0hg`Ea7jBQiWa&BXi%?p*6|7ZtRB;B7xJTd&F(2p}NTG2dgQDGo*|RxRs&pb%NZ zbDp7qQb(Kn4bpXcFEV->w;kZ5v*o{8g+#w@GobXotZuVozIU*d(6E_vHrK&f7BslW%&13`$A`a!kKa!9!* zVd2}6uyxd}l|Ps&7pd}mW*y4hOlArpTU)>oL$|eP%tHw?n9LrU$M?#nlKNz#>L*NxZpubE72EuAu9MK7&|| zT-=*<3AC_1XB^s_FUgTj-5w!I*Y(yvYx(y%@bHGyhSvgS&p0*2J>Ewy!~!ljq{Yg% z$o?k1JlK(QbV*f-;U)7DF@wB}Aqe`e!YSQ1Yq zZyGYTxjLmx+BpgESp(Uue-yQaYw{frEi@bTDowjyb|8%DpWS8Nt699hop4*sVRqco zG)Z6!tMAr$e3V#rez(-`kO6U=Q(8yY`+@AKJF#u`h4C|?EnotMgfA^|+=s#Jd&FRZ zvih!95A4Y{*!*j%rb)xLNHFT>p7vvF8=kLcc;F+`)$XjFhUpYpm+w;vW)4AhGxaQX z=8;O}IE_Dugsp7<-pg7pgFm%l(w5rbus~~=B03p73MIJV3qsl5t;W(| z-a}Z%j+6eTjq6CPsGC{CP8%{nt=HP`eY5_Zu;3Mao$H26OD}tBM~olqkGRhKq{ugK zopxOpo<1(d$zl*lxBEm~Pq^R=;ke)2G-F!wr@dmNJr}u5tZ3^3)Y7;F($7S;YtAV( zadlv=ZNlomi|^V*#$wZNOMX}L8@FLUwF~k=l!>V$UhQ97s6BPsgIYN(7_s|%^Ddpp zPR+3&W=Eut>AY4~9B@MoplouXF8k7N8QbCf#(e`dW2CTR4fTeG#^M*~j!^l;W13G? zs~T{ThL?Er1+YVP)>gOOoV))Y>}WP>xwJB_vEIs?84reddSpC6vBey*;L|NdN)L(| z4&S<6iU^`#+pTaz!8NeV3HqA8UX_*F-be+VY|d4Z7jl}qRg+^+@V49YRC4-^AZngf z-ve#LUHlp?vH9)#IWj%MjM4zJT`Dt-#(}Qvc_r1 zU{Qujl-2Z{ic45^j0^2J=B!iEBxL8PTl9&UqGdl);kqIXEzY2nxnH@e+H$2ysS$K3a4GX=*9q8lr{aRSqj^k*eW!D8?F8D>4HpDw^S}7#YDT$ zr4BqkG$A$QNFGtTni5`6H;CU&K+PLT59PV)=QNgmSa4YWYP`0RX57sTSP@>$0)YGK zgO%K@FEqt&S=oQ%Ih$)kT(*)@d~=H>HvPQ~XS-5-$d1f_ba3uk;EP#IGFQcb>4KCY zYFvW9jwzB&g^!LEk=g8DD0Mqw;R+893@prOZtyTyd6)Nk)exB;@=u3GXFnp`V)%Vz(hhz1Y(m49x7~?2I zx5k3JxMO#LmFv0abwy)4RO4g@aDWycDHM>969;UqeQAwaVK+a@XjbWv*4{-Ek2)!8 zadn~F!ZV=%#Ntn!maXqT>P6z9L&e>s&X+wfKB7UiW4>dEvQl-GTIHCK1WOXqxSB9Lty z7NpT#MGLTX@Te{vy0n=y{N=F1#=?nU>PbZQH07q&!R?Fwe9xmh%d0-lLjX>PF@~Im zb|3%Oe1DvwdFX>XC-dN+<1%Zu0eVM{3fykv_Z@*d$wR?6!P`q`B7MH_lhu4XWr1Z^ zPYFEAL7j^tfKp!fi@3g{ok!i5WLtKV+r|;_<7NrAMST+C63rzVFJ;#5IkTse^%7oDaMhNA(#@gD+>3LTLr}s20>LZI{ap zY6v(xLA^3cUV(SN-@d{r;=MekT%pu_IT*fPcTgL@7<^%){F>*p+!eOJ0o}eyuz-5U zG^Li+l+`${dE5rl?yN_w)oj#ZGnLl*$l#>|WkHDM`y{?~**Y>nOHdEBoyqvU_7y3k z*_-a_nf1NjiR>duLF@nYdnZqm-tDMaNtJ{T-3Sfy;S6ByeE()?1_{Vu+o!iscw;Zj4^?uVoSV{krnW!UeW7? zW8)jp&dKK+S&9c2#J)4~FM5aXOBYFuMS1+ZhV@s>s`|HCn?3Z_w=+yFcWUF{a8UF4 zc_fx*Y37C%lEGWS5O{b}>VR~%R~CED{k+Ra#fTbug#el%8bW+;=Eh1g3%{i{XKSP^ z2`z16S|Szb0_ydcC%lIh+9-A#Xg6L39N2EkZxv&_%|w&2WUR$8fL**3Qp640DbtdD z1qki#3!-tIyj-Blq7=sF7Q5^u;_3{Sdb%&LoAW?YZ-a1+%VpnBzWzQaS?S2+)3^zW z17hfxt3q~;O3QF!?AvhULb#ZmCZv5yyO6w-3XJ={{ss(T?46oaL<$efUd7;{xR;bkyR@b97Md zV;}2&fsRsJ9Uppp$B_GS!udDV<44E`3#QXDzNokWEFDvI$dE6 z2O6dPZ^C(ubLHXdw=3ZSD^ISU#1$GO$CDb16g{{_Z``@v^lbBIoY%aadT_Oq%NpsE z`I5*?rNiW!M6uCWUjFK*6NXDp%g7-OY@ zcXvXNOlh1$SoFu=d-5jaNpV?Gy+1;bdH}xSb@74PVwJ{oj{OMws_UwP)uPI2)M!$Q z4*1~YNDeTCAo<{ZeaMLMv}U5VOL+Crm!)kb8K3eiAAFvch=*VCugqwC2Z1)Ny>^6d zYHr-uO|iPS3>XiQ{;heZ1IEId z@+2PiGr>&F;_S0V{q4Csa&P-TC(evX7`W9Dz#}>LKD&_bzIMF{@K>;m^WD9!x*z<5VsG0{vJf0s zi-gEHAbII4t-*lZ@j)JKHAKx?KnHSKOr_-)64U7~XeGr3)BE4D$)#D$7*umc7TsKV z?sz+Tj2omxri90Zau0tg*-Ny0N@Ty_ZaLbZ;@T^7NPEQ(&*&^cIc%3>GSHNfvWKE2PFZjgl0v2(D;p1U(Y{0*$Qeb^?yPonf9g165eYU+5HudKn`7&fx=lolxLN|Py`r=gZrH+u*h}vpa{9>#$FS%F>=g%>w)EI zsog0+gupitN}PtTTQ0vRhBNVB^#fax{h*qAGJa9@dprLC-c{qCX~6EtH{Y$Bx-;E` z9Ela1oGMurt5pzQyNOW)~#IfyFrFTJ~)R;^;1k`3dVk}(>r z34pp*bC{L=fp(*oS_ZMMZ?7|btl!g=+EFn$q!nNH@0Ak&vcy2GwUWIx4gZG*5SZ+Y zY%qTATlGIj<~LZTvr|JlnooDe%6yNpPJbOnG{jDC_$TOm(nT-IMaf4qCKC=u%y^;vUz5L1 zrM@W}UQt&Xg7Q;Wl?PqQvx0uE>UEv5 zJIDP;E+TMnJu_$mlGAhAJO1M0cO?tnJqLE2`SuWO?3(&5s^nc+>m|^rm;dKo>918c zrfg*6?Oi4Ae&dv8tzI@0A|Z^H8UNDVzzg3pLPP~A#w^33k%D`u=9-(1s1exq8y!tZ z%OS*Uz5xQ~UI-_#3v*M!n=!HqK6`_w&(QaRte1(?T^aN%RWuZsc$h!3#~R&|kyU7A z?p%Xj)=wGFeQP{5KKS#!kI+Ktu0Zv6nvAUPc5`apIv?4$*FPFR#1PR983tn7kK|X+ z-H&{Kg+tL>BKb%S6!fE=?xDz-eUKkJE{mDJENvU+)HJeU{K zac$=4aOlqI2#~9lG-!z_ujeG7fAi0NlV2fM0mko$*^MjdpwANP9~U#VM>#zHrgvL& z1=nD$VZZO;_+^sM6YTsWjss+lN zKc(uc{>j5<^ciC7r+B!EU6o9&Gb&up>r|-M#yBA^M6&u7+DT9MnzTY*43v?ijwGO8 zhv}=oOEad%8=)MJ?OO*O+-F4NfMausx+9?dxg6RJ(xM2bG21{*X~05S%WS7$zp*IC zSk{oNphLbuQ-DxKDb9Z9Tnc!|<@8br7bO9WA=wD|1kE9L5OFg8iytyRX&j2t0I#%* zIo3DMB0{>Cje-4A`Tp?TO=js4LJnr#GV(~w@#no!NtxxgW3Zu;0hbTIYD;FvKj!7f zAP5)cTrR0!GpWICSBa^OH~-^-DQhX;c+1U2j23zX&Q|sxEVIACtvJXo2UqKU*Z!@O z7N9%DrmKw|k#ZkxX6agpp8+3fU4$o-L)SU^{h!NUHIxLNHE*sznY!1lrw~$w{J;AQ z_;*d*ht$8Sh_Qy_O;hDe2fUA7MIpeDWz+Ks4h)2`ikz6RGM-f_QSbF9k)KZR#!&}!R6DYXt75}|kw28;+#9Q@zi?UAZ7UD_dlg8e{;<3bf5q%}V4gjh0-fQ`s zA5ah?WUta$8!{^>kdimH-COy9mFlMI%kA!nFDQ%QY36&(cQn{y;(cS#WD&|VOdjtN zPO9J>T6zY{==@{707B>QXMb#@Pt3~b=KIgcJ|K!wZpzEdoc}la%3kHJ7(OtyvdZf~ zsQU6^ZmwY7bv_kw;ByK>kkF6C{0~X!oBe5tyOaiP)90lU(3z4SX0|!z@LvT6@Hcl* zoOHT|ysSSOf6pO(M;#zf_;fmJrq|@U0pabHol4=Xv=3r--EP3sT4}p`*03!tFDQfq zC)#A66`6I`;vSxxZ%4#GCR>xQVVfE4>IAnJ~1MFi$L2# zdUSsN^cCnVx`Ae;6j>y)EncS&c(rdRP&AxIA`m~!1Df7`6|FtxdZjl3NC>p~N99=V-Uagm`C9TCyYmAE* z8i|cGwbVxbV~whDJ>bPJD8Sc=nFs*~E-UMPk)-zqacNPespn2b^WepHDql(P%wS4rebhbeu?!QX18(|mWQUPw~PnXH*_@qF&d+J zQopriH}B%+mgLam6`2A}rG|;>INa`nQJ`FQ;AL-z0~uqY3B>1&w3~yP&!RPyY{T^B zgK-2zw%bUC`O@^2bo%$21iyGyP3pVdkwB6Q;LdxU-~zp2Slf6Q{AsTYO02xKQLLB} zI52j%COLs+x}hbD7Zy}Pb2)}>Y1G;;Es$wuVU2!$|D!1%v4LRK(O*gUtKOd9RO*Xd z#>9iEE~H1kdW>3{|4JguWlS%ndA02tmLmj0Zd+M!2e7$^i$Gxjp}rHfYE8hSlUVX# z@ph%)mm?&B!8>5$79G;G!{xvugI4$xIF>HlxSs`YEZND*=c8u``n9%rIwheX){v6F zu73}m9VzFv)TrOFQN*AC`G@!S2jiKWAl{yZFUQ4kK(O9lf zo1BwxW_BeS_ewA}nr;1lh8V1HV@@MjV(ec1)p)wn!XcUz`hNWyjc346ZNMvg?|&CO zoUqyi`*DQ3oOr)zmUzV}maMqBR66&j`qLIvWc~&{RTEwE^?z)f^Xxxtg_$s z;?F<1hxB`GivxM9lg-)RfTmB6ks-o$Qs#nGnd@W1>~1#fwVbFnm)INf&J7ix`uNd)JKu*_TeybqOw>qv5`U7Pxei*M3xNm3SUVz=GbR2!P>w>NXL1_|%?N|&91^&!2| ziwp~K!C!wL7^MNGChDkGIdrDAMFpJ6%>%`Sf#@Ff?YnbN%CdBdgPamUIjaakdR^n^ z8G2Mwyh5b*a?`zZPo*Z77EhC2nV&Detc<_gj6}3rO@}Aws_Sb;hJ$dL#bQe^jhJ9T zd`pBJA{)1FZ%<6*1g+e819SxfkZ!ZxFEKuE1EkO3yd}tTRryF`&wkShEru1FsL_&TY@@M z?$=D?Te@1|lyMs8JRi#L{coQYTHEJqw+Q4%sb6zGdvGb&t@1w{I*RbBLs4PR zt|F1G5r!9|S9}}e+ukq4EGMi|hp+BIvRMzC@xgaGi&~ns| zV(k^EqR$-v)Vn%+BO~>1HL&B~G?%{>qy?Lq5h?l)K^%{#9otBj}oxSL_0wsnSlH&^Rwvdxt4c7ygX6hnFDZea+P;&B{;pG#f z76gpwZfQDC@$sZQ^LF}3GTwLL;Hcxx@+@$r)t6yW>CbWJ@ja5ksmw^z$=?LtY>>h1dAg~t6P zFSib(qndb4!a~-*`2NC~{B@4s6>4x_c~2UV(=nq@`Txq}q2DDOT=Gur)_zAwR|pNa zW|-I{5Fo)UJ!a=`J7LY0;N}7n^dyi_*6!L_%gA%AsX=!79n8sXizcaOoLDs|@o~y_ zpq=!3juuAvq}IpGNu>u`a(EEqE_n@l)If&%q@7dNFZwj?Kh(j!>wd?Ivx_Ln31f&O zq_Te0(Mn19VFzjzC#`V>es~8d2OGg$=tPew569(lQgkIiDeQcB6iQXYZxH{o|3rUi4yJGi5 ztQ+&b5_ywsxCL9%sTve6VeOrKFv=0MrVe_A{!A^$HpP!C0aW{rE)K(1PN(jU(3yu| zb%6<8a@V}IW`4nBwzC@EuU>boad&7KvMLY(jh?iGAx$w#XvbdeU-xTm`)6KEu zBkscuspSQ(56SH8TTTjhojT{m6ald)Il4GT{lhUjHG3~aN*0@>bAY;wZW}A6A7Suv zb-e7(xwc&L;$M#fGZVIW*_1FjupaOLjV z0ntvSJ_yw&&r2xw1jIK+sXoqS<>HPoJ}u#AoS!uc(;z<0MwQZM4cZq#t+)nL>L+^_ z$tm?LD=OJQF*GL$Xy+sl38#j8%~q17S0@(#rU?wIA6cx==eJlt90x>HZ|N*NNm$)1 zy8XvNpR}lwe-pormgh&I<>>g);3G|cWKkPi!|#Q(>O$Wu$m#=R@*5<*bdWk;31SAC z1GS~EPYdZF00465c{3Boa{!EE0^5yW+adfsyHGurKP!y^NUdO({4U=p*eTbCc0ip% z%HyWq`U7efa$I|{!!(hpVxG=)lHmejKkYf7t9^@hK5suvzZUe)bzV%G^1;P1Yy9Y zz>-NVtTx zH8`@AX4icwHkj~P$35`OfX-@vKyjCSMYXa+OGmBWsKKR@vAs=0D)s+FNbO>#%Caon zdy=~ao|%%JkeWI_WtUS|Q|@%miRD3Bjvzsg0}1zcP!fytS!@0V6Z88~sb-G^hfnJ% zEr!W7SE?+Z7fyPnw*_q_tye+b-r_G ztRTOCLwbBPF4#d0Ig)GwS|vcpliq~zjYD4421X82slR?Zs*yMp0DM2~@{S(^X9@q+ zkgd+V!X@XRM+ZfVVPju?OA?r#fsQqJZI|hAuu|(-NzgUPf4NI~%Z<^2`{I~yE|_p#vonNY^>lEuKb#V1>uSj{kB^p3t1zYrPt# z?VSXMIAv}{u0JAA#VpEzUY*buKY%YMn@^5h$rl_zH=AT;4bSA4V>@okgXv5vs%9@I zu$hiR*WOk@g@k>HRRtCgx;AE?&&_fVay3&IBIe=z4wmePCN2&nj9{j094rw}x4ANyJUZBeAB!|FZ4*x4X_Co_?O!3C(rSbRi5-R9bE(dNAzd!#L+w*L_I*X|vN z28{u%HxSfAL32BSted_c&^J;I$juv#wOcg;u-dRxx18KyKy00nZZWXq@KKv?(~0B zJ=`DT6|zSB!dJF}@Zhk&+PezE)GKqZaD^Y}c- ztbn0XXZv&Rge;8SvOh?zvLx&n@_9zRbjsVETi-Lni=;y5CGUV70)6NE5Rb;62cDi_4r$;R-w z-TTN&-=3gSrOHW+%^}SF@=!}s6LI%$p#|slu>gf6Z;v&pg01HNk@l19mxw(LCO7Z+45hxnmyk_*wk$Z040AS40)w|TLrl4@+{3#S zeLw=AiCvU_v}j?*np9@x6* zG=YWTn8WcQyQ!p4L&(tE>D$|A{;eaQ>j#2pF0$ym>!=aPfW!mihhCqs?C zbw8LtmdL=&?9YA-_2df2fDLwO`t^m;s+;X)bgemaUg%hZ`2ww^pup+bh&MA8`Tjj@ zsaY(OPZhMQU(R_H603ix%$fT?zh_FzzMDmq1UEu~DI-m3l@2J=;`Ot>kFKZs*pPv| zap^S?|B(z{8XctkD;*m0nQpC|d;@m^TqeW{UeS6_tUa$!3v7l8@4{TB4xOV*_vD2gSV-{4-9-fPnuRb~ndD{^riPEx3x zKTc_izf#pXB@>Mmt=FAXYk6JH`%_7F_5zABcD?Vov~nr+KR3@I5B|$xs$wVezlw>5 z+uWz_2V7R40at&3(<&(A14Qos%~u!nI8jd*qz(d(YGJwA zT+Kj@4b(;p%6kXdi}}PXM{V;8oa3E;Xl#mrUuQPYN$bG2r$gnu%OFqJ^lejCu97sM z1mEqwrvFFMxd$?#|NlQJJC5R%Q;3<8#v#ikxo$)WvE-EGdR)Rmxii~bQc3Q&B$ts} zo#fu+Hi~AhbBmd~VeVsNv(5PJ^Zos||F`#E@5}S~c-)JW5u|9zrfIru5Y%=n0mGtq z>_>lk`iW^Hd_{ay|?~PcVJx2#y#d6<|6F`8vLb!-*rQKAH_nr8N9kf)zNOY zPJh}8v}s1!(Pb*L6_Reep&hFz`B(Jv*JaR z$3>$lrF*vir!OYJ_tc?V#+vg7_XujbP-tf zjPaSe!+qs^@`tBpFr}gIW4>@h8#rjUTP^05XpN)>SITc%18Ow3Z6WaAG;|o2JUamh_4+3q8>%uFql?&cHl7T;7?svnRjsZ z88IMzU2Qo|Eszmhj?;O}VOMl({1y$3j-0TX-FJf+icTxobBfV#c=)8YhJE5@P1`C*qQKUs~zj ziCWGBh+8VSjjJ~ljW{u94->F6v&yaC~FYTPl6-Vq8WmXO- zBf(ML_Ff==fdq*$bld)e8dkB%mW^Q5Vnzcy@h5pUa6l<%R^_B$&`Xp&OoLUTV8GD! z=-ZnqGucvVyDfa$X-$AkPJJ5+zoYjyUfFRa(Rk^BwA)Y@=l|B_gFI&S&8+}R-u9Gd zTQG#B|IvWV7^@>?OZVctS(w*r5S|kxh&dfw$2>7G-zn|3^zJRM<>(modm|wfa5!mj zJP#EK$rS54A?XInHt7-RN{Hxra%4rBZ&jOj$6#{WBSI|KJM5QEIN$ykrU> zDacQJ*ShS`53zne<-Oqi`!KYOxX$5#(ONK0y>)tst(3j{LTy6KYfOM=j??U^T>o}C zvqRM{<yk~_9Go@_PmTj#K3QxFHUI@ zzAA6X$mlLB6c(_p@=;}X9XIW}&ie%#FhCzaS2XSaQQv$wTSL`+BUDA%uyD8l{V>Ovnu)*!9TDuz$AId6L94DA)LUDOURj-o z^#lQCdcH&)^{t-s|9@KnZk+t_-1U2s<=dA%MTCXmov{U10o>00IX=OFc#{|-*7&_F zH&=7}XJRfl;@+I=rpIa7(zxRaeh^)*i=D)sz>$QLgQ9@bsNGM?rM|;T-GIqq-BhzwvG@|MKWPXg8zZIxmn+xfr&)Y} zzsTEX-$sk3nj!WyM0usoOSd=y`P_w&FMBxWgE!&iT-9y!LxP)%WVV{s0D>rBj=!_CL~7L<=_&}@WuLq2~=jBC;iPPODtmud2z(`ZF?1j!D2LU50$I(iF6>8VHHF!&&*Y})q+TmX-hdD1 zDf4TmRSXzI-U>JTWWii3M0XQdl0tN~YPI3o3haSUS!R(u8=D z{J!qydsHgoUsXW{iT_R3JF2N1u_JG}tJszQ$ywDjUm#pJiN}R3s-&4dd>?G++Y);p zJ}C65{8TBeF0&?zZ6&g;YGD_RqvLLvT$w%jqgUI@I1V-ofkL6glmW(357Xd1O`*sd z1A0$|d|S2X@9ojp5SO6ib@rB>M@Mf24hT>-Fup?gn-0VEo(>v^?DB#bbp8%M!wvpM0FI@pLPb|-gG_MrZYta=D&&x)0?ReWQ{xF0~2 z?z1ciSU(jod-;Z9_l@PS$~GNZUyV=6a&D_@zeZ>(1N7@p4BDODc?H=4?Vux`5ay}| zO85BjQGOR5CSCM6wS`GNR7T1I_a$s0-V5BRQ15YbkTHdgd@ zB0K`@n*d}Bw~AgqGvE6}=@1mN=l4fb3ctXD`5Y7pIdAgU6Xfz_9ClC;`<375v4a&c z_JkMz$$-xFYI)$Fpr*BIdqO^D`1Mvu+YZ|R+TkUMgarM)6G4;S!uv{Y_Nj4&4QQ9c zW2z9aZZzw6sK4MC{;`GhV4bLy7QY9P(SAPi5%IajSd&*g&hx;Wpe+)YJr8abH!o0= zqGT}&81RW8Ld&(342Zh3UoK_2%J2K*py}?gX-OOM+ga~v)8VC6Q|F$`nWjRxNR^~d z^nM2(zVZJsT+YI1$mhCO8bSFIzm_-LXBks0nYc*p+|KS<%&Tc<{3V(Uuad$8bIAwuI<2p=;T?Xonc}H7}z2svPa}pxz?yTuYOL zSX0~I>$s7a7^1AvXzd$@U3F{{^yhZL(>l1vPLf4577)K8+o|L5G&-(4w2vImE9+=v96INVxE` zSmuam$X>ntbQ3KXHPeZM4tvHCKQf)sYorp(RlRx?JPxNH?Hgt5xxpDuj%bNn%)i_= zWd#k!KM%Ml%dvCYL_p~x1yJ^*b%0+mPYwdiCADACt*2J~Jo=2{43WMmrU^11*z@at zQ4>KjdD3gg?b%MLq}OS>wM?=1G$R2msT-(E>v{JUY?1q^m8bVtM;=wc8+G7?U7w=x zZ|-A~8)(ndinrndH;l_u62*h&OwHZ1Zpeo0J@YJPD-5ALNk6@fCFXZWUn|?D+&a=rxhis#t8?n zO)SgJ-}^4AODa0;JctKJIQW0t?lbl~38$^*T9%}oV5q)hiLQbp$K}Ddo^k)+ zya*>jd%nZI_nvpj4;N@ox4GRY-ZZUzVQv`ksO!0fuQeYG!|$s#&xQP ziF~49!b}kCSh%4a+_)Ps^dvu=TB};H_$dw*$LTQ;;3Zz=W>wE7$81)b0-O1=_JLS+ zj)Xx$<|>`M8Ib2*Xh$5*tNz;-+4C<1Vd0tLL$YYb0+`KkrlUcIS*-%~Xv%(9)A z(OjlKXP`^_gfKlhgGlSLYohmy0p~x`-VGD1F01CZ&>^I*15TL zI9oY*vXz&!p`4@KqK6~Z!RvDx^7MKL27#T!P1nRUK)-CA@@)p*lw{Nm6Kv`Ep4Vo@ zz8CwgGIH4P_@ozyAA8F;Bkt%b+_7J4dg}$Az3(-NWriP_2wU1?V|YavsONto2D2GT z@M%^6Z(2s*?|3+)b@t%(689QvMSNdX3;}yw4CqIw-Ns zcXUc0)TOv85?UQ60~!bin+X^GW5Ffxx3Ah!8C6?R1Crf4HAj88K3EqNCdnNl!C^wN96J(it5FK}_r8T>Piuud5GL;*2^$58v zc6i&WFz!oFcF5SSeocNo|7u4zxf2s>jyj)^@bA^X&ks1MtgAmtP(0r&3M^B$t1WW{g^&&=imjRciv7L)Ehg3yEBd`ek<$vHo=B(nUh*lB#Vm#7`n^PI?}fsr z(z(0Bj%%E1%bX^#wAnhU$bf3BTf0g`RHx8uRWtk9>#5)pJ6vq$FV#U=wp>b+&XWO@ zQ1EEo-P9;x76$0#G$T+8^bvzN>|E6mY56#TJ$&FLvVW;4cJH)ylz!|O2T1;*_^nml5Hb+OS=rQXLqTVXW8=$?rwDf(I z${jsMgyhcS69T3hEuiRt$p2fnG?OhmIPx7t_k^dsB(=r!SO`&^X)<^Ch$XG^9d;ydUOll{1>ry?bo3mYR!#%JvmWi5K{pz8G?8;$)G(P?|0$oN{k0C z8MWLWmDmx};q(I3+|+Kw8tL$q64$(n(KO>6L&>1LaO9qA#8RIuwU-r12e!*-%&On; z&PXZPqh~&Vt=?=R{+-!US9CeM+ihj}I(@7rOMf!+IHG5l%DD-S$y2-6RoOIH%YVz% z`kH_X9E}G_0)qdMMy#*=<~0`oGjjReF*1(2fR)Yyjq#1aP>=7+8=4R z@R8PIIR<0bL);GrErDorC~9X%)0?!{D$i8zx~;mFAm+FI0-UxFS3kUZAJwv3aBpzkvpK!GywhR1_x zQ(oITCf^e8vF;ylY4MjdW4Tg1gqoPkG0goa)9TNv(NBTl1iOLWq1|kS&?~YMH}{Ip zWJ5nG8|SBM?PZRBc?$bz-1_V?Yo{)GNdHY0br?|)P~JO8R4gU@Rlo_24Bo*ebILRi)-+`Cj1kQMV` z$SG`1_J2zjdiV)B5EEJT2t8XHV`*!PCc8~R_gz)yk#S~h51Q?B9_oU$D;Q$MYOi2H z|I57>wK$0*mQB}V_QKSHtL?EPPrB%BZm+{jz$HOd+N)QbbHpSgF~JXI^vY%=0)B?w z%^35@>TbNF!&5%`eL9qUH-fyuvpCxB6HnE8LC@@&l=atVq1r9%39Ae z+_nMwjH6b3+h7B2eK3cE(vCuXyP}2vN`JQhk_yS6*9e=4+F)CFQZpo^2{N^V;OP*6JRJzMQ){*C8AUt=R6Rrxyg(4!(!RFwVr$gN7vQ%Sih{NW>_Mp)(4 z{+|EkNauG4d~W8OTR)ChoV=2MD+{Cw@uvq-@Os)yHh$Z4nNj+GS7bj5d3WkU901XK z#aX%)(3x7?|J^$7hnEdCb)J6A(jd5{qMh>mhr)~NMyn@JqRDjnC4S6(x9DPmXh>?X zg=*c(3UR-JNZ*MXd$b_pqS0%Gp^rdAyht1LA8IGOrGZ|2k%eyeztRN$>g);m15@~= zKmnTvSomW&(HMsqT7uuxT5sKmj=V`tv$fqmo*8lvad-uq6=o1KBLtmeF@>G#TY?>n z)<021#Qha8ej$(6CLATZ|BrHk&s+)b(lW^vuQfh)P8}n#2xutbw2FFMmq7 z%)$7;eUYCJ!!A+&JJiwIW&EC3{2c3+roTQT9}{*ju%E6`au_dG|K;x5Z|EvrAGvYC zJ5BUaJByj0_hp0MM`W)A#Mnfo7lhzPn>L?z?7$!2MDQGbdg|@@N}H~E@Gd`_-0wRR z2=*S%D63>D?s?`0x)3|ktC;^qMMwII8SE)dfODd@vbVB_6?2g5gh!95xHXNd%q$wB zo_i?~T*GPLBGWT4l<);-0k*io{JZ>cV9%$F%@S64hN^lkbgTBbZ4|Zl<|S6bl2`eP#LC6nJ}B zSm(7#2BmgTHF!q&Lvt58f2bZDb*K~$O)R2v4Q6khWz-AEw%se(W6MkKzJ57Xo3i5S z)JG-|e;d4&a`swfrC<{HyQ2X;d_{A?RP<;AC$ulYt&T;F51uus$42EutR_wnUwfU3skh}s{cirxG=6~84;wwy-Vl5mU&)=R*5Q-DbKEJ}fC#f|T z&>pT60|z34ivr^3hZkO+1c^1LSWLC-_gU11KuoYF)z`u&UTXObL>1*2iXx1pC!c?d zM!DVNb7?s-PgLFxwrEe@22FB?UOmDN;T`ha_QvaU?)X!&Sr3oRa~~%BxY49 zSC_2)-J7%sVXP8axo-9CcRa^IACzuyxk0@5Zcz`HaO_xUb`PyR%d?&MMsu`SWOk zAo=_5bfkjJXPLT4vARuQe_eyyP}tVc`R@?_SK#|v0fP)Hj~NLlg|mHB3K zA8I?(NPlA+^!i(idoOQxW<>t9D9PKSo$S)?(nY5r{0Drj&NHVzO9U@rc5e!`YXJIh zU^-B$?`Z+c&GMM91Zx*udiHWzNDSIVX0-p==86q>U+cU%y3~>9n$ooMyxw$bctxak zBKriiI-6s7^c<^;2lJahgNpILur7IpmdU@D)3_farEFSSxd ztNKgSer6BfgwWUB#r=C}H0IUmMQ?EpPI8)`9KVlIz9BQRnj6Y;J4L_$>a1LGUK3ca z?-spiJjeZ!w5ot5%UwOKsdv;kT!K-`9AZHW=$`)&lJ zHwRD><#(#)Gc!+uo>;ZCmxmr-W#N;;b}~(Uwe2vHuaPB1`_4KW>_PLiOb?Br}IF)ajXP*uXy zs~)_$QzbSp$cx#X_1-TW#rS!T6o6Jd|`P%q%)E~oEfpQ*gzpFy*B%Hije{+1EV5M(TZbiQ1>sXW|Ub&CETzGH_ zr@7){!1=HU3`VYjAI+{id)NZWtEK!`+wcHiZkIQVqfEla$9=<-nC$9J2M??00*##P zON?gfe=E9%26LPbcM0N^FhphdqV*38P-}tOM~HK96SP9ai{y&(vZ>lp@a(f&TNVg1 z%0&bu6XIY8g2VsY(ngL(b~ts+EKVFtLch^Mp5gwvH1|tN%{?X55C)%`ouWi@L8Wv= zL9t-e#0Kv0#KsOCckD5y;ciD-!+=N{4r;uHe!xN&b=~82*L16$T{QbJ(x(^LbMT?h zq4%J!euh6z$*XrJlvQx7FOMPL;g5U#0U0# zNL9aR&+Cjst*nV{F5;2vLhV(-F4;DF`;T>g= zu3I$B4YSi97T9BCBPwO?r~8U<((-tyqxC+FN822^x@5Vxa!w9KGftxcy)uRfo+b!<*sHueo5-O0J^`+KO zcWQ@lu$R-lXw=&NmZtlVjWd@azt^G}u_OOf72eG_YYudry9l;y#tVb)k}3CfLzZLo zJU~bEUn$Fk#glpan-DFNWC6KXzP&fJx~_B?+ACGvT`N6Bfp~!{!}*v0+9i31b83Jp ze}$1%r@#|B@AjJBsqBUxccRaZdHCgRn-7GRgIivsmFXVF&%h|1%ir3qBd-Y3OZ~gZ zFpli5R3HuUgN*Efs3oZd4&>z;m?nhvNK9rr8!ZQ3V$6hi+UOOc?9#z?(O*L9Y$YO7|XOUX%y;_sLX+ zTkjib`SV>Pd?B;rk!RsSnjqU%GtG@I)mJ0Rk6E5ytk;>D%v?XTSvogr7K{WttcqP& z|1|b@Pog?)zDK`Xwb9L>X2l*Z<#wnNy07z=HtHwn_vlKY$6fH{qs!x)@uLFU-6E5n zwU)e>$+j%rrMH!g97fZowXIe#Q}T!HlffEVt9W%(ZOVPt#C1$j zYr=J71ez}oT`c6Cs2bQ1|Hn0sTx=HJ}B4H}Z}DC`O4R~i;S5tHaOroeYyxG*Dl zv&JlyTik{G&?Tn-5!T!H?MY$^>^jtA842FFA15?RDnBgo86TEJ3z>i|xK_fc8J-~T z&tlb|WeZQI3i9FTKH|EJ`F*l&unL&BVm2`CBTDD6 zO<8nc-&FOktZsc0Kr+^^Ft6s58<3khkQDmlz~*QuvQJN;e&Wc^R8)3H3KDb-jwGyD zNQ&ro7K^Q}8QK6M)Kbv?8 zz8E-;ipgjdZ#uBudp5PAy)+`Ot$ll93FF>Q8l669O??#6UFal{RC9&C@LW{ALc+_{ zX;k*;!XLo7pF#zZg=P{m+H!7ZWg@l}sRG)tLV454geS6ZhLcvUp{i>=Ly-hxg2Ltr zP2an)6fx%DoD@vW&NKyEzi4e*HDWScA=qUl+ir#T)lY_1Z?#;8+Z)It#^xtH1KTYi zY**e1cBYa~a|eJAb`Ko7f4PcsId{{-|NLd$FTK6AP4Tg%ia~FFGUh~fy{PjkVeib9 zlGaK}g7aL$LMK^c%4X*0NF@I*YoX(t3BCcJjBwpTCcnF}=(G&l>swbHXA6%XtM<#` zANp?HbX+>SwtM#D2-@)?ds-;O*QR`ykC?FW^ev_7d&qv&0~MQqkb_dN-G6y<9n-6j z#s7tcp1wxkt}d_OwK0poN+4wa%;)vgy{YTupYJ~S(N4Q$^DMa=h^g2qi(XKqVzyPv z5xiYioQUpv#8FOU%yr{$vUcQm7IPWh&9`^wO8{?DWWxUJJ)s$Gx%spiphSEILVxoXG?X%Ni8`E=_OS&&Se^bag84;6M21oTi! zi-D9SePYZV`Anc%;JNAjnsRnAmJGWcnh{zFHh~8n&JE8;2s_ zgeJx!@^*+gV?dUO8%@bzz>$VpFZeAvtWzBCSjQ~gvQ2Y z*;zp9MA+#?gRa}sh`<8<5ALmh51fKF#wYzNhVh8iztG~1JZz^8BuKZNPwr$Hsb?H~ zeMHi?eIE5H;|qT$sJc7V(le4NE~_Ye-06d&fgH;F1g7`31Q-IAfjYI%S(_V+8mL|+ zv(7FqCEO=HN8Qc-zgMhF}v06*Ty!}5Qz$2%g zKpC&ea;G=-7l-lZWTMc|N8<(@0>kCAQ>#=JB0AG|O7fybK?T{)=0(I8h%#U7>`4i6 z>+C$k^3n}qC1iZa>RCsc1@pvd-mg zjLIkwq}mT&PL*Dz!GJpF<J#|etRhE*l^~TBCDSt zgfXokWx^PlLp>+?>3+yN<|)ogw5;!bO45X~a%vO7QV5S*qZPPTj>^gZwRDbupRwMQd7xDEDbI^@KURBP zL7HQw+x6wqw))j9X}^Uo(#puMZzryHeT@xZ1x_)BWX{_LBPOa)`RsTBxnU7T70|F#bi$0J}>dUs-b4*XnQNiT;&woCwm*fv1 zUuMjBk~ro1kAiZ-YSV==@VQg5M12u*J7PQq`W}SNszkZ=O#R|J)^Fg4L7V7-vVrtp z#EiC|dfh%F_b)qMZlher@B@CMO7>Ddav=qaF}ikT`Oq0*52Kz(wh|?lo1u@fw$tIP z79;16krlPf^hF=cURFT2Exx7qAfxRdd-}YHOI7;AK;v0;X~V{t4O~0 zM72pD4b6(*&EO0>U+faohKnE%WiYqE&+?FKgv*u&UUYtYGWtL*CCk#Q_v{7wqAWsp z_H=*BAZYH- zVKvE!ZK_@Q5Axa`NbZb{a%D{?p#?f!TkubnykbXf3L+K6nxIcqg2d!x7Zas)cXWgZ zJ;o9fI=54B$M7#;#AMLGGrTN! z+Fi-u{Qz(j^v1ASI}ez*2Mnf-1k3gQ9d;Um#YW8jcLcwgbS8`$lH7R2e@_IiEo%fh z)w<#O!DFKA`Kb(Pf_%d1po>)bNi+T-Z~S}OexmtIjoA}!yhLi`%c`E)Z#%_1c2=Q} zv#Tsl0Pqon?zjsOMHxex%T6lV`ig1u#{^dV{|F#0zPt*t8#Sm``3fN3Zx<((nWV(_ ziev+d0!i&GRP{ShzrhK#+;?V+|A5F=BEqTmyDu?ilX+5GNJ{!pK+P_D+@r#IC}aHM z(Ph(IwNz6BBi|ob{SZTPCQZ`V%~!8_>F1^Sm-3L>c&l>W?@E-82Ay2Z^gAek9fdbT&mC4a=;|#xRJW-1ir?Liqo0{%Tnve+nT*6sX6MJZ*`8tEea!;!aDUNoaR8IoB($RV-2mSs6}x z(FQGXg|L3q_7?!QSD~+EwMjhSAO+h>Toa`U`5nP?;h|><&UsRfupJ{OX=vMT%kE3Y z{p0N;2FG)@oTUd8v|fbHE6lP%THWHP*PE~eQ^dH$&7{A*8o-v@qGY zo_i%9>+Bc43<^fLOib+x__3y@bToDoC%F6s>eGqm*^%a;!#5{!VUG%uYK-!cb;SM| zqgJ?bhvVNEAijYcN9=q<6HYe60yVm{x~^@OJZ;FR7jHTRO~+{O6ov%n*lMpnE+;a% z=Z4?z)sL*|XvM3QEekVjg8=B&!2$Lr!_N^-9`h5V-+tG;obK^qL9)ggOe1u#)7%fk zjt>$Z%&^;w{cxPh-}VmyxX2m{;r_3Nj#5Skbb-)9A2DY#JZhiCJ4eHw@N+NkJDBTe zR-U!9>w3zxos}vMNjo^f`y13YC~4z0dUam#Kt3)ioKyZn%#mNoQ^#*WFG-4Y6%TBu z+2UU&Q|2*GJg0Q1@x1{8i5Ei?1CnP^roVmE!zZ4>rd^k%#NAk;hEK+Qf*mzQ)1yfn z5)qx2W-5a~7+0)5MulfIqb;k}pR!1JmqHGE`c8QvWFRXj-(|AqZ@>kY)85kVGm;RL z`N8ou&QKhOOo)gJ=D9ex_r7C6J9wk$9`0ZMAer@ZK+2O-KvTTbve+jQI+|h@9Yg+)*@JX}6Ssl>uhL-cD`6uGGBUa|C=LYAZ=bl>wh~Hj> zpZTyG7;{QbI?|4BWSkw$+BF^}+aZC7+a_R8f z;!ObQPKf~@p0Yh01=tt(45V?U>}MY;bRtFV|6zj_h2WThE{Ud8zeu;+Gw zs&C*(E8HKNLVvgoc3t%#)Tnkm5@B2mQV+^Z=MfCd?g%dG`1GR6^)DjqXzTcph{shN znqR7#0+bSyXgs+M0&sORT)0rLlQ*Z;h5sRqYcoYOV(P?;hG&{24NSX3yU440E1gP-OMAK$z z{_D`xUl`_?&d|=qSE2_+3ABXf4x!ylqw+2zJw}i2z44~aEk4MZc`mbfqo%BHEy1&v z{m7HCkTs=uXQDD2`vFC-^Zy_mzF@59cN<+*^>U#~Jx#q7{PZ_`tnSg$eyFW##u z$9WS}-?Q!_>X))qIK5GOAVgBT57~-@A;76hj(wz%B`6d& zSerxT&`NjQ^W9%VTp0cxf~-S%C!g@en&$I?=vRda&s@n>ChHqe6pOE}4Q2@}f@_Qz zf{Gy-w;iQP^`hH84*BqWZ4|V)^DVO!?wr#0?arxso-(85z8) z%==Lpb{v1fU_-ojmvUr(h{=i?1R5iPP_j`kk3rv2So_bw$h&yqvV%OagPx#@w1%jR zEo3JDhgD;FNjQMiu=%S7HjWdJ@k^P*F~F%4NdeH%+u9Tb1|gw+vfw zGwZ~HL^G}7$m8z={wi+El!qPDk#G4^7vQ8_TToAQf1w}Zi=5E8xYu^FYGYShw`%09 z6h+unYW({4&!2javiHO`#nWlM(u2;LRp??GxN30eYmKu5*Tv}6#CS}3Kn8Seu&+)g zXi_+E#Nj%u-;N=ilgn)_sJHd+kGCqG_6v=~Pf&V8j~8H7rlnKE4rDy}`rWVN zk7y1q$zzCn(OCDv?@ryh&(?jr8~=A_4UkU-0YB66bN20g#J^do9G=@w31c&QeK&A@U6Uy1rrvF@+029178 zJcr{9dQ}}}M&dtjMQgg88r{idxp~yv?pr!%mu zXKO3v&)8UC!;1i0nO!23$+?i5p4Fwj1ii!q%2kO%cQf{gg-N(J*R2qKWHmAD7oxb?!V}X`&)q(g_!WzSCz~W2?e&R?4EAzVj72Dq-6Y* zQyIsCEXEJ1s6ilpkwuwrvanl_aJG!W6CYHS!%65khFjVWsZn-IS%IVLhv%nk;nNk71sAQ^BEV z_#1%CV%9%A{XMttE0)1_F;-dsv_)TC2%YkF7QoelBRl`b##Q*a_-1|uyPql!t|CCg z#cq|Ydt30{Tn&;XfqCu4Pbt zROD!y2UlmY?yXI{qP@!^o=aF!duYIEn0EkUuoNsOjftHS))5nMy*6f(Xm2Xb!CK`6 zvvhgpNYB~h-ju32cj=154IH`Z7CRKA>34bwqj|JwYbl*puRW z!h{QLpZdcjb&@L&Q{7Yx`@>R?d}zgVDi_Dbo#B##20rRtA-z-MH(oUgbY9{0Lk{GW zWsjce@;viWO;fZeCT1#l4YvYHm7}?Pyrsc@dt<5qf;Cl44b{c@^) zH=zak%bGX^;8cV(F;A@Ye1Ok-No&yS^96b9BWHEhlVcF2qJj8?XOs^~r*uDwNd_Gn zoeX*yAZFlZlcLKjbW)$OHjTWPfU%VRh{O_)Q=Zy$wtS|1Os(Dm=^6!6qiDeF2L{|E z=?rzg=hm`M+-(+rQ9KQ^!4uFxs?+W1w%#d<_z9w?Vu`u}M9_IM`y zKYWL@r0gl>P*{g2lv7f2n2kIoDXYi#iR4sEc#xcp9Y|6+j8qaflGZ`aDa<+N!-kkB zbKJ%-cCguO`|bJtUcddn*Xw@Wulv5Q_jP@)_jQF!Zs%D8o@;1wGkN5;?U001KN_#P zfH-iQ5M)ap1O(ijV3~!lrFV?gOTLx9X>UHq^I3J7m`mC`y77~Qme1oND&HBK9@Z(u zCpB$v5` zEYGCIK9>H2Ny>r0=-#w{RKFShqM6+-%FbsVb|zEEfmaFyW68{{FUok$XJzSWPKTVO z%kXo#TxHv?hr_kL%m2E#fXugNcB#i3)IP~Z484T=SQX=}#&!3er}g~j96|n=0Et>5 z%<)ig5L;Ve*!HW7zh=nbdsYShf5GDi;;(mfO`RDmXoQCAYUR+6l(>stTW$)jF`7CI zy=Q99`s0_~Hb(2h(NzT{-J8yF3JrpjIBpUyMw6u!bPw{p$4y`SuQ|fECdQ?+V6Lak zLh004PP#%>po5p+ykT>|lpl`!{mHw}F^h$qU{^hopn*DcH-E!D>SqUarS+@$7E)tH zCm1F6%S9C~U$klgM+yxZn)S7MRT<7C5zud}@t~gP z`DhAi$;KKBi(rh-=k*%}*2mbiJ-#N|F`e0G99;?tyCV}M>&E4)@8))ySc|e_Xb)xm zLFfyRzpGNhA1TfUIQTcK9u%W7#ICM}*D{Am?7N$Dm&?E#otr*-EydmuXJ|bLJmM4u zY#l!cpMpVTv;M+0<$k@Iy>)Z%Bj-9nk9uQNhr@Q}^XtSC9$-sH_k#|K}S>r4ld3E#`w-)h0$QLb&hJ5l>16TkoR0AJY7G zb7M*q3{(vcK7%rf?GEqG{~muQ=a=CWWA_Z5xSyd9QWERiY+fF5{x!HZ`4_!XssAznip$ z{qFOxtTt@<2J&?ileu#(L{`wu{_x#(8CB?G02k)iw`VVfKhi(9^BC@OQ6i818BdU% zk=Uqa*YwJm@-`Fe=YvYM{R_RvXiv@WJb%$pQ({iNWy4vJae9o!#soijk)G!NAd@7S z**u1=54i*R39DsAWq7rHGfMHXRBUN4knf zN@FZx8P4VLVj^6sbi&v8d9i0K*s5 z_GM}yKy1hbug#jgjg9<2ZqmTu&EXtsmHrjm`9c-m!4T1ItywOFA$T3C=gxMy7IwMkIpn&o z9Y^W0b9-Yf68M&~?EQmU;qC~0Vt2@$v}B7GNXRAG>yT(xlxiDXXF(>^q?^vJC-IT6 zGgR9mS??6PJqr_pnnE4Mv&MepvB{u?8XGEw$G^2P>V7=lcJgJ$i^34-al%R<6>=m; z?AAGc*M}B=l&zB&b=Ey*KUec6W4v{HWq;UfOqq^Nnhxsiw(h~ob$|u79+mRWc8N^* zZMD&<%-X}5le!S{xn0tjduiQ2LlHj+pLu=bSt2q4yLp&Ita|v!^iraZUx1$J+c_cX7EN^faOk^PzQk1p@2x; zX?$tQ=a|?J?kV3bmpN5!Gm7bZ4*+&Yn!fh7v-7?qFGK!uL=nRC&G9UIU0IiDUW)~C z`MvYO?sgz>@7j~0)IX}mTbqFgeiYq2!BX6A@we(YuEsH6%ct{U8c%iMaUc61+dx@T z89TsS^8Co=B6LA5Es--N-ob6_L-{unBTe?i)8z))dzh*1B&Ql+Z_X7xnBn;lJ#hjNG~d{vL`S z)4qH2_1v80)Bf{J+AZ3bZX}>i)$^?Ww+zpuI`xv9tQzkJtI|u?sl6(q5s`~+*YU2S zBJAb#X86jDlQe+U2KaViMgjK)q*s+=wafqrN3>^C5YYLK|6o6Oxly_^-wNl5vu}xT zs^=x5Ty}}GVU;MNb=SDaPS6604_yfrw3drByUqWeI2glXB?8y=msKjc9Gk@l(F8Nq zmqFl-tS}Z#a?S6)(o6)X%=nj=_F66p>$48oNXfqxt9Krxyp+ zxWJ3Q4ew~%)*5}*ug|yacy_Vwp9#Y6ukw_=r{#?&d+&;s+argAC@RHfZtAfXA*{4L& z&+6Xjh;qVcp7g05B&)9(!DFLeB%jH8-QzA7br!~ACmcnn6XzF=e$VsPnNhw?MUFkh zOgIF-3HH19jL`k6npnPO3!~|6q&Y$bUqW`}0(zq=t|x>sVwwzdLDI*q{-*FeP%AxU zRm)#O{mE%xeG8R*w>h@5ImKM3?mvfT)xCqFH1pQ&3Ai~uZ8y98=e<4cdMu0_cqP!M z;AhI_j3*-ae#0VM zd9V~TX?2!Q+p?X~fz11326Pq@5q~Ye9FZPXN7&gejl)1}?U*~=Hzou{CdQQgQDn}| zi-7X6(psJaG?Dv!G=u$p2LlWD&l`qVYjj_2iy(fOgH7bOZ(^_2gZM=rA~>t$^1<(y z3dVouJkhX@z67#%uU+zX)~(Lr+p23#OpU6IuX)3CP{GEMMXecphHZ41o>@x2&N1Ir zxrkbNK$h# zZk2b&9lN}fROc!Jemb-=>K<{Bs%5t>s zJpQe6(CkV-X7^L=ILVC|kTr6Rtj|mFfyW^Y&UVhr$F^81nRz@NgeICTR)iAjC zJa>-$AlQ}mY0mke7joP!0o(f`%N$|0{RVW#T(ZBrPt8k8Rn(79J5NxK?IFD?#b=^E zsNj52(Xo2~2r~j&A^wps^$*WKI^qJvySf@nhQ5L&66vzI@0rfmXHn@*7&_*4)xW`p zuEoJOzraNCuao4vcJwcN@4bBKZLL9(+3tjPR-zpENO+bofx5>HYa2-G^;DpEmvzM4 zPsg=bD@{dA9UQiwazKEh;s`&Zb%e!e#3G@5Fh;U1yq~A}B#&qZpbdN}f-G*NUn!u$ zP)`t_JEPu~Ux_V&-7Kq&nwqcw_U)U%f7(iM@3Qjp?q&Y+elA68rb!xpceif9GHm$_ ze&sl}APiRrI70H~F}h6X1sh#WN;*@E8Y0b&2-76$^->Odz6;x?2793Gd+;rEF$YXQ zWO2UJz8qR5Zf6SnEf!p9-&LOJcd_QbJJw(sI{j)Sx2!nVmk?%~xyj`Bk8s_KeVb}m zE~@Dt)Dgy>8^p)D0%PgU1SJsvpDxFU2k{veQMTj@UsuiyVO@72K0mZR(6r<_{LIZA z6tzhx_hGFnvGggWnHTb%0OA8CdA8o-{fp-DCs2a7KV$kK|Aqt%T*TY{^oIsH-zh!# zd3Q*1M9qYgbeRA3Q0IQpQMm3ytAi1sC2#9AH|k!kBu>Fgco1B03bJw~P4c#+ylnRj zFG}Jlk9zVp${UrHGNySTjT7k=kr7Q(Ky{aS#_sOVL%bXlO_=e^99rtlO)cOy8=8HkmX-C6*wAynvoWi5fjWa`4qX1 zUj7=0X|A4--f5^Uk>BdVRULC<4OO&i3mNS}F7l`CGUkhvI+MH?(vBn2%9kl1rG6#} zLXRtkjwyk8-eqX73~x@Ni3j(b{@JwAl~?1LiFil^x5&xOB@%tLeo15ScxZ5`{q0*# z;T}XmCs^Enp0?v;iuaQZu;Z6Mc{E=}Fo%Cr2V{I8XiW2nK; zwmYZItLprZpS?L49uzcI#fB0!%Abwg6`{N(HL2i*pdd@wcIU(ohE#tkOOJ;k+Sa z=o31Goqs?W9 z94I223gPq^LJybOVhDa83-ueuJyNl z(LIss^6mtMYgbS2e9Hd*;W5{~Z~(vYTrH&6x35hdpB`9a8{I`fR(0-06&c<>XlH$SsV!J0D2)PKvXn}W^P4>ZAB4s6dTL7jGaJ6P7h z;ja6~>IeBy&kv@M#sUhY$xU}OT~jUTmVx?BKi0YH$;_&)*Z`}SWAlW;{IBJb4$inY z9JN%Fc32i~PtUqxfeR~J^qj2uPJ4aEC6K_|^;XO6T%2HimRh(7Jo!yvi zz4zos?zqSE%^xqmyt}X3GMRYAOziSU5+lMY6fbDi1o4zA(qXv$g4g1-J+J3VDanz7 zQ-f(&z>w*3%1UHo#FnZzC*~?#j5=dC~(SG_O)ica_v>0>EaQ=fY;B{ zSdmy;;%8zGVvw)*7Phz%uf^Lk80>XEef3Az)I68JzWCWi$KLUykRI2sfxGNg#;8K3xyZ6{{DZO4+N(A$& z8B=ELno4!+|CMWKCmG`%rF$BhmCJ*fh^k`dzDk;4OjRk(n{P5--B+fiVXXpN% zpn!k=ygu~rwQbPoT!-zD`KQei>wQ#%|7FU8%lF0ao9+%$lYTUymwPf3-{{6|_~0L$ zNb`Zd()gHp9@K(9=Yj8{lM?WSBd*@4wLRshGVIk~vn}cFs0`}iO>%C>+m5p2V+lFn zJq^hf=ie&%ISy7@M68;}DcJr8X4s>P1!G0aJv1BSeDxe6bmvnc$*y(Bas*UmHR@K@ zqVxUrcZJ9b$iDoI7a6ir;qf0>ZkU%Ne0AMsyDg>d%S-s!zqO6ju2R>|wkQ*^V>+x> zoW-z@0n6rdf2$XPSfHza~*t(Qi0zu`(Cgr3g|S4J%ff+6KW1iJg{ zNRjfG(%LWQe44AtB=q2KjYRx8+*@-OTw>|SGTn1nWVxUNC8IMMRk;N)Pzl|Ab7ZUK zrbrPMV%|c8drVKwYNI9`DHYk`I+KV-CZ;nhq|70JJKCe!NG1bF?DUPwPb>0bG}5zP zdy-^ZO?i2vkNqpiOIe5PcwI~6)MrH&@9n(h!(Bgn$eV5NeH}*@@1{Pmm~J(N`(6fR zrmE7PXW=S;vMK{j7e_$lHcbsKE(ztuBQ_Y2%+H=XqmPDR+|cQCui)9NJ&fvRZg)<& z9cn&XT{i%6C4o6yN$EVpjMtuWn&;7e_VQ2nCn2ZU;w!ZYF&8$`k1JUzvDkT0$?OMd zc*WK@RL>sRbRTH%->+S@WL&_@%B+p$L$9rhjHrG?ZH{Hc(3y2x4dc_?f9`F>pA8T^ z$zRuhJJOZ{7DG%>Hq`Euckg*S{F_%fSeNk~8*+R4_pOe9SeqwsZ;txJodEF4%8=?J z@o!1H9Q;g9&DzkVBn=2-{CSsUO_JAK%x?RXM_}Vq{rcsQgkd*}QAN#}rW(+qdO!rU@@UQHv@mlce#XdZ`9hW+0S-XO6dyb7 z`9I5Ztls>lL`&sU)<5)#ci)TvJ)Ka~4UV;)Zte09)is8P69#WIm(?kAcQ<}du$7bM zr_vu1#$xbF4Ew42*mZAYYOW0~yPMLjgSfl0Bbf0l!n_0Pb)1skuW-Hy=l4+m(z|qI3LNiFsmY3E1bWD7>ac7nAl?+-; zq@QG?%&mO3o|o?@#W=P-XBzhBm8s``x|u2}Hk~!HBEugG`SsL3pzK{>IQ9WDV4qjJ6ZM%+1txe zizp-fRcvj%)Z9CYo?oe%gIL`3{l$6g%_|8h)Q&h_>_u7i4E2Ok3Yfv-qK<|y;bCFx z{LX5rB2;dKu<+|v`C9*N(tXn>)&H)VeJbDT8B<=Xf+1e^SNo0Mmo<8)-AP;dUI??I zt+#S2F~qxNcmj1Xw5$Kcrf}B;*uGh^gQ!>ghSOM`Q}z3+Nw%<26}5auttUtPkZW>u zr+JN!eeb)B{P-?@b>_z7lB446msM~u>&fU&L`1N(PO6TLu)>iysyK3!o+{$1 z-FR=B%)j)^;-omB>NiX6Ro`YEq0n^_C9W9sN+Iyx1NAKl%@eXfWl=%xZDd7&5V@M(&_rsUG&%DE^*zQE$k?=NQmb&gD?J6Vn6(rRGOkHb*qaAh0$Eoerg+>YG zqC47x&#aAsWbU>qaH(bZXDB-8Zth8P7}p(L-9qv{af|^S^7c z2W@M}qBZ{dbdhO=Llf%mtt)KRhhKIqJMhJS6p}>BcV3mp?B@;TF>4W9mR>}1gRxL> zjg`8TL+vgkEWccREv58LTvIP})?NPSv!#CsxNwFXx)r|cy*<57i&}Wx zCZv*Z+kaGG%0sU<|7hoa&emXce2ry0;w}t&&UvbMj6sYe$9BlP2;5m#`hU2t08Y6u z{XM2FRoirCxje_c`cR>!?>%kWK9IWAJ`43TZ&cr%(EC*JsqJNw%8k^6U28jlXH||y z-dH{!w7yMKG^2~?Ot}3-T{;cVkCR6qc7;phDs??SCQyMI3!pT zx@1~Q?w8ay@2x)2U(tV$byI|CVovo#RBq!=(dtc7og&-w4d#tJsc!@jL>fZBL#H(B zblR*$1)LSxH3;Rnw(yH~+4rR8u?6*I<#syUfzK3$di1~Tm8e!EJ7G{Ci|ofoM#S^w1gSCg92KKcarb zk(XV8RXHB?4dEV$-{;+d3-aV`8zCe3hfVz0j6>Twr-Vz+jcZQMc{RdWE&0-z-0Tb5 zpdq{7Kz({5WRb#!&ShNym+4fNiJfK1juZ(?9`blbO>!V7%#NhJVKt-us-_I{({hOH zS2k3D;#NXX(YMmWcgvCP65ES_1x+LbFKgxN2f*vd*rmBm49tdS(&vMqI5K{~LAC-X zmEGRKajce`A&m}yM`HxhQ~b*v0NBqBydU8+aFDm>H|C?5>g4X=!@KG7@!At*}GJlEGG_~Mr+=RpozmzVh)b|)u4tVv;FFR163yVoy zW$}x?r+c&(Unq*pe0qxgeXvgf)|q$FH6gms{YyjJ@_V`ti~%~=3J)SemOfec-a}~u z7GNF9ruEsdg0z_!-IJYw^5R1ja${F;azp{({uQG4xz~{%{6`Rd@_F5Dl4ro%QCHMV zPv1UeLd!i$h;MYeM{c)9E?1jWTMUS!$?J**j26}SXXqsju|E_}@&eN=_?15i(LQG+ zt}NFE^AsFcId086|5gT$m_Ek*er64qN5O;JBO>C~zjnx=J1i?!H6vM#WE1&Q8Ey90 zEi=_{Rs0R@`v&Q4z8b;OGmHDw*Y3*ydo6h8!q5@R79*|!&1fw@rFm!Juu{5u0sHT6 zGTrWNVUe-qM6FgI2@KGSHYWb?LSN7Nr^8*$`^dKP3E6)u(78GJ^m0L`6EgwuO0g)I zp#ONc<%YE~tqQ-jQQ-Vqrd?iO&lD4fdydxO&(C={tB-SwV!ln~vpRUL4=v)3M9GDq zx2fDhL3lbNd;N!7oXQ!H#B7#+fBc@ST-5eWgSO-IN*!;ez0m-lP7J;Lu}%4$GWWIy zbWNr7Rb1)(G0vz+hb-bb#eVkuN)Tm6Q%An|*JY?JRSbMtb-zfev$g z0*XdR)jLqsF!i1kZP8v)u}EzN4C83`RzI;I9T#Vn`3Ut`Py9EL>~+IeW`aKPw&)?* z0jzR}K9}Tfot8bOX^o{^fCMbTv_ywc45IQp`NPzYktjWDpA_qcdzo?dU}Bjw98$!D z4!H=oZ#T0!N^Lk8|pv#Qf%pzf`BSK+I7B-NC zRG=Km%)q9hn%G*Orl^8jpV6cJ<{IJTSU?RFEYj`44vM5F{Z$)e=VYvuH4WSG(e3p^ z*J?5G$T!VY)6KrM6)fx3{CcBC94~py@}m!^XJ%b%Z>})*abw5`5Zi)XTUxgrzaS3x zrXnvWaR;Er@D+ssfnxeZG9viUCv8+f{{re-EmP+RvQ!N*I`jIrcQe^JRU0WNhn|^| z{@~+2ojC{cNvD9d6ypNrBLl|)-9zWPfVXh32+1kx5b*^NdQWqlJZEk0Ae^Gj<_4|< zZwUMMV>{I?*9#fAxD! zz#hOK$(rZ8!N0nS?u6Yw?0C)B?BCW4pcWOM{gLP4yI#SA?F|PuhvyVw>J9(o!*d=a zLx^&So!Wj3*UXl_87KJyi_B4zdL2>4yu-GTpBV8PHm&aDJyckk!=#lYzFkROXTvtC!kU)M$y2)~#^a|!)AC%@Ks z1G=eJ(Oy}Cn z9lFc#R+-CrS6V;v5ayD1=r=mV_3ZR{F_?wDYVd@~9aFdaf<+pK!X zl4h#8RSqbDiBB(&`A1rfPWJ{0hw8faD~5A@7DaAMzv``%Fu_w6gOI!mMm)N(%v~6u zdoX^O(st@b?3hm6P920dh8DwcH}HDrE5Kg2ruNBK}4UvKq|KT-usC+wpJ%CB4%#GX-|;p+VwcE zuCmX$KH;eUF#JFI9X2#`Yb_r5&~d6gPJ3#fq51*!``Ul)+okSDwt8jo{rFYm{~351 zm}Hg&$PXtImmc6DDc(mmjlGR7tSRg2Za2C^cIbNrA*#FRzF|~rK2YtY#9drJ{8raw z$=(tAP_p01{gb=ejkUyO8>*=0K^V<|{*XPW1_;Bqbacu)&9BBH22qVO)dk{ngbWvzPoYNb*oXa9l=IADlf{=2(oN5Of?+*xa}Ow6A2q>NAHsRGcO( zjL=!gqkQ|EG*VwDJ4+Ky*HNu(#vm{o{x%`bNxT*4e|h$fzS(B%wPXmlob#P?l7D>b zRRk{8cXN8vd?5kdo3i?ln|9PY64k-acrNQ^DV*etqZLH7f27a!3b6ukP`XW4d|kXK zLYz?VVxd;xbJ8&tNslo>*kIi$g7z>#SgAzK6fPLWOryv=eaw+f^q-Kb7n_T93O$pH zhvuRNgQ(Ni*9JZHtZn@wbakwtS!kn!K;uQ7f_vIOS>QhGU&2<~>Bdum-PIO>J?1EJ zF_qP)=1KkOs9}d)sW4l)lugpCF&qf%_wzJ0V_=r9mDk8`C@fvP8FYDC_f`kxlt zD(9<6`8jkznMNr8{tTfhTh2+TY*K&^6SxD{@$z%|&RP>`*XoH1p!E&}D$^8Ia;6O6 zZ9XUQj{R(t?;|N`NqDH@}-DY~UxkgVje=FVI|F__+ZVNa? zAN|o8Zyd{T^}KoUP3nWGH&Xz$JLyG}Ur1out#-G+A6{3PrE>`T{|B zyw1j@#;(^7SL>sU8)^d!nBY>s$Vo?_MS;I6V$AAu{KM!k>#B@MP?68vlHn&@S!$)^ zKtrY@=sfM3W;QeZ7nBlE`hj?%w}rJuZ1NU;QTGIHn3|YKaIveXjkt+QP=#B+_+jH= z(w~D$n~M64thMeO^xO{BqtG-FSIK_v>e75ruRW^up+2?Y>V&Axj8H4eC5RZGmz< zM}852t|vulg!lKtbf3dZT?_sGLq^eTqHFs)~GTs+N|N#>wntvj*&b-!W7tG zN$6mn%59ETvcEbmCO{`*O0b*_$CYSuAlp3(oOz`WOOb>7SrYvL6zPsi0kDJd8QaIJ z{Dti!ljjbk0B;0%tIQ^vkb97u|FCkG3S7ks&$Nq3z&gPWps*2}S&nTK)Im3LU<+>P z%p}XWk3JmUdIQAB!4dSi@>st-NALvbS&sPp;mn0pnBe&DpdF8u`h&1(QIF5;LalaG zUQat1zu%{W#Qb5Bqqo%aNVp#lA;`Z{>chWRKjP{)9=}+I7sE3?> z`?K5qUiqiP+uajIBqEI&XB7>SBP$_?g;R(Bmh~wq{{b4W`=mXifr=%!Y9f&OCba%1 zaVJR4SI_}#X3~6;fS!A?FV{Lia95?dsW8c`R-g2E#Y)-;s%j25i%N(}z)snj7 zs#jEDJ9SdeG1RlTx$w*Qwx>rxjpNm?-uXcGd-*)eXkMyR68M62V+%-i8TrMm@usU9 zn|gY_lJmn;i`OjVe}A)-|kKzGUp$;1F9tMe*5S27?u$pYmm3af?a3w4*)hzO#T_#M{V!ze8CWu*%H zub@FlZ}D{8H@zG9(ng|7Z!D;rWJ%Fa&?_Y9-dUS8yAMsE*d{`VWzuCuv0T4>G1hz4 z#&0_5<(BZg%KXs_sARqHV3T>j<*15<14D#@xv<8&eXl(zt2eNv>F5kcq!bG;R!-^c@ zo4ymUpi-xtN2Zp&F%@>kl!ySsOR61FpL25le~oy_^edk2-bs!$1}?`MTe zE(eu)4CmDled5T`A4fG6x%Cu1lG6omdN>XeiLA7p=}DrnKV9t%!W>8{^0_IH?}wfi z|G>Ztk3m`@oSWQym*aO)O9W*P{ZG&`Q#$Kqsc%vohl|>HgJ%WDQXi&qw_c^~iYt<7 zD3N8Y8^sWV!C&FJSj&Zi(<~H=)P0`z;#-!vI_JSXj_iU`R^!~RgGNw3ov|2h8D^!j z6KPitWHN56-dr-02<=iq-oW{pB5eMtHTB+Tp180%gf#A0T6Xi!sKd>sWuMw&6%6r$ zx#LmjqRN)HTPK6wRgHmec16s7S75MUv4vMJOmguE>hG zt18vS+n%+x;bCfMI~ylnh4&Zty%e>fS}TQbKYK{?{N*;~P@6yFU-x%>Jp}cpE`k5^Zf3l=y!~1^*UBVXJ|j!D}PkI>0j3?gB3-@wllVkEZ%HfAK`47OG%h@2g@<>!BVe%mm zO?g~3yiCx!Q+M}4(3;kCwH;(Yigu2wPOF z_T<%&pWhlph}iP%)u>#`lQT44_!YS_OmoxvI^*cP$A8ozem0VYzyD0!$gmz6Od9d- zz;)i}+1%$p@=L0j1QxMNUeV`nNu8;Xb2;&e8xRL!4&5j$-4YD_$*}^m`)_5$Ci*|v z%2!zCbfaOUcK%d8=JfTe!)5yWURir#p4IKqUckBvxWB}boIT1M)73>FAk2?c7l zcbcCRDeANllk%P8K+bC2XKrG}Nj`%=Nnc)Y9ldo}or|fG9i4(8=%h>Ew|qb#M<;}v zo}}KtNu+Lzu9AJBA(qjQu-OivXo?9cV(w$On-!ELg+Vq{w`hst#Ku-@*Vmg)5c%}6 z*XDk(1nI*rda_fW_K<2ECA+?4WJ&F_aDFI;ejcx}cEd;iIjnB}3ro^J6^t%mR@pTS zCguXe9bEQ$kNicqI?N#oCl+hCedFNJ$6fv!t*RAKx|!s6X)Ji`S;gsv zg1w~6HRI)cFt2!bOBHDlT6B3m&GL8_EHsYS8o#`~Dd30BKy zFmM8*i`DRE zLlU0OeEsm1`vc^{D2JR3l_b_CN)EVfy47-fnl?t$b;1)|B4);;E@JvdC(h~SE&ZLL zegH)~i;=e-UMNb=uwC`{SOv_zWuaW++xnVXBr_26&OznP7Yn#>R*P;6XzLA72Q%Q* zYp%CFA`tuqC*}9};8MDs+E=-`<_{74=4mBbD7)|MJkE^O^?vuc3u4-U|D!pM9NU>t zOMrz=HFyypY<;`lqr-%coi~g*i_ws3|6jomsz$oiKC`vb|V@s@th#a6+PW=Xv-LZW@oBRwE zfwQ`8WPCIBhW{WvpHtfG+3e(S-I~8EatvAK!yEY*h^c0QtGZ9p8;gn2g>aSnjUUIb zkrQuQ6{jhHi0|$PHr|e~-~#p(Vhl*hNU3cHy!kpkaWv+YO@aA;$9XwJaZm ztRhiUl7>yi?%%0E+PqHpOIW;_dQ*AhB zB@jyIou?A{f1mx#e{&yl*cQPx7L8}?g--GHZGXZFhFi!%XncIw%&};?`6|P_Ys${> z$EV$!`NdJNy;B&gmp+#ZRGeV_h&de@nb3&(=wqqxb#VCM7I#F-wL!p8_Nt|m)p(Kl znI=&vDK|W0Bm+G-el%1~rZ^`jj8zJTZkgB-2)k)KmFb4{KT=t?j|ce2YSK{p{{vYt zk6J|VR6Bvyh3IQ(F7x(1qZp0uhNIA_Ho*KfpCXC$z6bJ62N2#C>Jf3-CvWYeTJCT) zYAvZcdb;&d<;cC}6ZeGuGsV#r4OFdB=>CHBwQC2aC^7y#5_t}Qc>juNn+y6rbkllC zW2*x;)$0~=PbcbkW)_8iZ{jpMiUG3z;lCxgOeJ1&$RU#DkZdNv>b~j$4w>NwVWJL4 z@)mCvmE}=hq8EzCG*D&G&zl!g>dARQH}Ttqg`ow!F4gXHNuc-CrntZH(QE%e`+(B! zLgBc5h6O50*XsqgUR9QJr)V5mcqLr1U(FYjMf09Rx40jet23?0DYe}`Ve?+`MhHVK zY+|W8x~2q1`#d{W&%#7Ku%ugA4ql!AVZPW7VUyoM1^rg%4xaha^u}j1#ibP2XXq`U z{j$!k5HYlQ;>DkG{Sz3*t1So6`W3Ok5i@sHe(_5QVE1=l6dzu*(fu6T5Ij%+R;%t3m^WGu$~d??cr(sq|6O&BQ3Lb(x$itJ7M>hiBH{n$@1KAE?{#{E7ft zv+|j*;|H&!g=Kz}GaCU+^rRGz=a<5xTKdMV3cclkm2YyIgroZ9k+Ebz;bCXo6Fl*? z3L|6Y$^pvV+S20`1Zs<%hS_y>*Bn(IbV11@Wxy8b+fxz z&Q@O|NsJxi?7J9YWZb$nE*d6iVD>I&;a>P8(vPnNyG-5|ENIRClmkO8Q^BA@k~#dl za=Q8X8wl`Me_|>&>^3bl(ad`9@X%xyGR-#cc^<{?&T0-+E!7ky+_BU(c6OuYiDV%r z1zBAV6dryywSEt>VB@m&q(7B8&YPgDxZRiK0XF$HufO^l%HFk|mF>E+l!SIJ9&oQ2 z@q2h00rM@}G_Mpca=7L!n_w<_BF4oak0>N(h0ERGC)ONpww8y_W$KxR9nVH8dh3_( zKRrQoE3mmm^Ivd!&3|Pb2QA8oxk|{Cc%Gd->>{e^KZAe1g5pJaCty}fgm|-Y!V0qI zXu(VI^$IAbe^B>x8kkLYFA(N5Db5WF{2|uiySJ5_1vxZM#5*Q|q;e$v{IfV4o+@E# z?hbw&1$mGIKG|jdf)y`F_+%1``uacCt)-+JUnFYFJm)*Ha$I4>&E~WV{yY_dv&mzE zXa?ZNCA+~;|3izvSWw>IVIIBvlU9&3&Z>NzGQL=xf{6U5>?vL{b`2!e%1+vPe+AS+ z_xPwOPDV94o4e&TORlzB#Tt4`*W?;*V$riI==hNJF64*;H?A=u=)spqSnn9Ssem5w zAjXT->xc48X`=Ulb=y>lomoPj*Fo|yiJRCI+3D9DIg_#ucd$Y{-qT24 zSJUZK)nt8nSoS%)DK7Kt3%6zl+~HMsgse}YKKZ1%BC4Z`L_;oo}lu#6}2=!imMi<_YP3_`=R z`FlfM-PrbJdj1wez3hvp{}K8#eNj*RGpnJg!{SBAUE-m+Q?$A%rSp;#Txc?}*QuCS zl$fG8ZJ~^qEQevh1+}k0sAEzP-#o z1^>SEb)s2ahnWyIrMDE7TcMEEifA^Y=5zBF+}OI{aO zG*`)tY6hPCZzwo|6F;gp7{ujN4>u~uy4Vv|=s2PkAy^@vDw@&u!hI579biWF9<j`wuX5JG$}=~UqJ9BYbG1d)ozC~}c$q*b5#B$A zsID$=~eO#(_%D1XJK z2K0lTJ!QM-JjQ90Z|t}YdXS8En*Hv~Nd03rD)3LxQS5RC*dR>w$rgYbw$qDQvPX8C z;AuqOJH6&BNzYK*CVN-!U+peL;Mb^km%<)tE5+x%!qB~TMnj+CLjO3%arkXFMJ+;2 zGUfs%avIdIOt&9c1NQbCIY-ViHeS|2u1dpiIyDoP7lAqiP0B~f`vdX8V#Sk12)nYj zD4OI0r?#*^BtV+jj&<05{+CUZn0nWaO%ipxqu(l7A+Cac)cpYTH@92`be~FNKf&t>4?^47s>vuqFAPa*m#jvF=8ABeYIQCYEclJjwsm@drS7Fb%-q{ zphVPo|C6?bBK&Em^p1JR)-Gw+L~gHsa@OXzz!Q?d5INsw*?Or4A0>?{W>RL-e=QX>_xJTMCD4NE%!rIR} z`+C}IdYx{+(fqOAN?$iUfwA}*Va3$cnIh9sK8t@U=b%%R`#E^a6A^coZ}Vs)Qd{ZH zc1#3%^Y!{3O3Y`|P1X~9{R54PMDa2rDR51NP#C{|Bi)=^9*8Sk%PaxX zMjk>n*8J>`#&F}QrA$FnD^|O}G{-TFFpie=PM{t{E=xq>k5Vjbd@buNviHPDK*+!B zwSk6t0R=^4-&UM~Wfn|H{I#uCM6<(@&3EWM!PP1iaG{l$G&b0k+4ZJx8nP{Sg~6JL zO+rT$)Tfw_br^jLUHkFKzcHmcoW>F?y0gmaUS!vo124<9s9S2fW+d(Wg!O-cxl&|W zHB?6wEbA|w$yXkyFKr3CckrnY^7WOsBG9_QR_bdjE?1PxGSvl>bl>AB`GeW+>MA$CP9(Ea8)Rzug z>dyvOg~kqwoK&`gVQxTW-QrE}Y`E`Q z#1x^{QXH619L7|zR`9EjQV*KxuQNNnzO!H@40Pv`+r%f}0C4*7;?8(7{_asqz&#)lcpS*>33F_GY{v){{~^317f$_x55kfEJz^`h>(CpJpbrVvN-R0^!tn%%?iu}l6rE`BD?*TweMIOyL7u)&it|3RGHo4#bhy7KBak8BzGHxtd{0(HNaMYo-6N&!aM#_{BA(V>JrKnx!LdT zt>2K`vTna^oZUSq&C0REXb2D&pG1lPhvCS#Cb5`hzUExyx{Imp*X!IW=1Ms6d(UPt zu_4UFJk#dS#|$ZB7O@|^ClFX6>23klLkbN__8nb{ zJ_&s%jL)g%dqE$SCcGv1HBlbb`Zd?%9ySI)clT8056Fg9e?dx?#e7B2bR^8^wA-~U zNNz|VXQTem8^47C8<7fTC|L4JLY3LTv6w=pW6O7(-k5aM^9%?#*yA_7^YD0Ql1O_0ly7pDL8Vey`HTDucdu5{?v_P>B1A=aR`8bmU#Q)x&5>~Ytu`0) z1q~(kaj~|Luu?^QGp>?Q4~k*-OKixvxUwFurom#r3Spi7T7C*K^T0#m)j8Pocku=t zwU=_YBf%V4Xpx78Btbj7Eq+)QGbKSPuKVR(_oJ;@t(e6Vb_cD*;nmiX7t`;=Ke&4@ z-68pFqHOS?v}%{`5vpX{lZQ%((#Jg~U!F|L8vo1A@{J`*L71{+s}Py25@J)g51wbM zy7+z#?8?6U0Z7nrfUge2X25|^-;GmmLOo5-=uRm_3U7zxYyKvEyoD>y%_Zje-Q9d^ zd*5!b{+U@m#H!+3;k7yVpwZx#Zr70lGUBScW<&6>nx;+{*F0*PwIek_g{+C0KXy%! zQ)e?4PbUv#Kn3SHy7zZRyhE+%X0%+n^!nAuYC|UYug(?LjP@?GKH;-^cYJvynVgtp z02xjiJQC}>WZTkEXpq%)yXQ3cP8zp}IOj7_;f+!DN)QCG>csZcdSPB^Jf zZO(lohAqF4SA>P{E;YU9Oy^MhU)ihRe-q%rMseo^7B*!j^VVZv{RlmQg;pyhN@3K#SdwQ%>GH#p0?R=rkRNP z@m8K7L}35>iXflr>D+13If8TwHE z^MJ+fh!~T*Us2P=40A<^K;(H5k#+DZgf?dP_u@G)>g!z6m`IK;@S$`O-<6^VIYZOH zC4QU(^zTJ&By}@!yyqCA)xr>vqIvggqJWl!qVXM#>CP1PW|i2*3+Vzp81|lAAtnVO zOMtNhTYg;9Cku!f09u_7g<=Kt>0Vj5WFXE4^f;iNLXmn$hfVZ%u4g+0%c|ujHl*<% zIm~r}?xzP?4mrmzk7ENpI0Y5ky0QP1M~rB)7wQ_+MuIfI>XEr}8i7^XK^Mmr9SCS?NEhE=P)>YOIY8Kjg zR6F8dwQJ(4$4{TBFo6pMd!A2C2M09UHB}6pHp{HwT!*HdgpJgCYf(37FxQS^3wR9f z%$C*cbZ#s!RU9mgSET(3H7tO$H+OpmKrzN!=B=u6kvfkYbajvZuXMo308c6e$Q{|g zNA75{s)Ej>i$A}$h^}~{o@}T_NRP_KJ0Nw?bh~KQW!<&)48xh$0LrP z3xS^ee~*{9e7Aje?^z^eW9p)jJ%VDv3-NE3(PCbn1m_(Y~(-UY!r!N1T>* zk3NpU{pt#!<*nL8E9VBB!nTv@wiR#v!lFQv%}V=U&B7voiu>wA6}KBD?6 z4ocszF7wzfLX)cbo*+|R^jpDP4DJm5K;}nd9Q1#$j1{jMb~f@8LbKz z5h5sUw4#3a2FTUkleD4{g?r#HI8z&o1^jy?Mb_V3cy!DiX*y=-gW6Xy{R?mxS-$l$ z6^ytJDiFyan@4^=i<)aMZy+a>Gy1a`Lf|6XBOm94;Iz4_ER)M{9KUsUX>!#nA79B3 zKbA!7T+jiVQukkWk6Dge|I!s;TkM9~xlB6<`-8Hmm0w!+!$*ZKw_V$@=O(&dTPP&X zt?Vt=EQBB>y5H(is@re7F8^C2Q(dCFwQN%b^e~^Es^(jhq6>saKuwprKdIiCZJv7o z`*iKAWt|33zKinb5jj+j^cuZ1C`b9aU*(vJ;mR{$?61J>jo%^HVu4#&L)ss zUpqb@MKCmm(l8A}oF2qJRyS-Xw06i2Q_tL5I3*5CONm_yE;s+@Q|x1iuI}Lf6#{1{ zZDct~g&@I)h`Hk>b92AdeXBfPBoU=hBhl1ji!v0$VEOyO40*?Vrxm|l;k%6 zKw(<<=i?u?{aJZ&zFk#@{mY!~ZGB~49t4yy7xKe-=wE2 z-j$w^<8pydz^?uha!vR+`LbXwj6kNg^44e6pmy|dwoauaGq>#WgyK!$_b2Yj#d5^M z#I_5p!+9?ep|UtxVw~xal|X)Wb36=Ne1!kHSfE7xG1JD^tX=JOTrj^FshPFoFy8w`(T50%NE$8{Un zr5K?-6KeH#G9Q~s&q|{1X`sdX>92th0VYJeCve~PY+5z=^%;yx$SAZ-Yxa+bMIy|cW3zn+E6sp>ZRgZj|2#UDeF44DH1h84I~V+qgHyR2r? zMl-`cLABRa+ohq*>Tbj=;U=OK1S!0F5y>91mLv5?+Dz7B-UiDJ6Ow>EJO#lUY)I7m zJ}_j9$G>!LB7A1)9UXLA(eIiCqL&h}L@x?$1ZO$#*v7_$DOmcg9|ISDHD1$vb4`sP zc2E@nXdbhXTdc$eWY-n?B2vyMmx++S`RHq@nQ&bOmP}hyJ(e*n8W(=KaS^P+Mt$qh+X&x89@^%g5j$ zZwkaXQslqkf1x@)d4Uo+r7?$a-KxmK*xnL_HKU5@f(rC9MM)iTLd^y7)4c~?!jx6> zL|n)I>OzpaG4v-`FfOZ%IAVZYx(y^4V)%8whvm4nqL&|H2K+psP4Q^(suV+p%$~ur z1Z7Pj+vjy@g$rk6-`oNrdJXkbD|zvTE7B{+A@FGw_Ggo1NQvj#KE_a!x9!T^0t1u; zTMIxbSoQ3i?K6EPj9zaWY|Ji(jdy09N8WVW_1P4Ue#N$b+6X4-(j8?tCZQxBxlQT+ z6h>9$04EB|e!S`eko&da{`xre^YEOe_F5DSiLpTICoyPwI|@^jpJ4*-?oRz~iaGdQ zy-WS}S&SIf^wR46~&dN4Q&wR}D_nc|u5)Z>Y4DKXhBzR_GdY zQPWlxE*DH5dhuvGXcoJ3%ery*$inz7hhU@bTEeH z*Frg9VSU=tN87sdqJ-?77}~7Rp(TH+bRO+<5gw`eFqPwd;eCG>7CA6ZRs8m_jeCzPZU6f zddNvu;@tP-W-?3F!OLd|Q#-1c%8EOxkKfC;(3mSaoKho)4pZr~0YMhKGzCl}U|B-_ zYO-U@N#saUacLkWxV4hilc5i}<275IUt8Rl(R4*oz`o-#CEHbQmrlP<&SMVyj@oK_ zKmz(Q*dw>yRxVEz51lF0qKe*Zvm15!Z{nZHU(WZqWR*b7UXI(51;;M1K5p}lKfs=> z0Ct?)AgSI@`G9wg^3hf<*P3+CEjJe+J*bn{3LF3vjEK!nzgHrKiqob835T7f-1zB1 zG$SN0Ux8xFq?%G2n}q6jF!$vv&d(!4-s3f4+@&H$6?mgr!gvIT9Pze#^c|mvrC2bB zt6v;oYXJ*|=jA6*e84|c)SXwdoU0$oj@>p!eb=AEZkJMsB0!p z3U1|H>Rr}@+y#mVqRRt6LWoe4irHVjG0W}h#I6AL-||A`1uCj%QN!%jsB(-+7_HM8 zl&P(|ECl{W?%_z}M{w}lhSbT;sH1Y{`5Y5pfjpF$8531DAD@lt83jCM!F4?p-!FV_ z%1rAG-TE6WLyHG^Y^>GXWUS5EJ)&L+ zJk%zOg~ThN4qgptty~LPYKqZfO{N}vC{Q3M*G1C53o@c^LVQm~F4^xu*0G^}m^L@B z@KpElYhh07naDYarbGGEbQk9Z;M&47oOFp;)r^m{(5Uu!x3|spU79|ibZc>U*6dd3dkfoud=&CGA#t9IA=^vk-F%O zLcb&Bk2Q*WuO@lzGIHTV?V0(3Rt&9rp7AFrd~4SE z5=7DiO58T7m*D$}gAZG*)CH6Guc~nmMhxjVuw?1=BhzRrft2`c=L8CI;5oD23t4oa zKI7=82gnhIA@Y%D#;N}a$;aS_`oTA+nH+ijc3_|p4)u+sB0Ng%te=U3&M0M_9gx{U#gsXvIuw}RUm2zu&M2x7iFTfawe)Sy9B9QARD?TFo+>`pNcGX`_uYrij!Iqp`Q zv&P#2G`6<*{ohm5S@Xxt#}DjvP~My#JwE0i(%Y9#EwA?y+>@)d9P7m{V0vTu%b6eD zlCeJ5%~GzI8447D!Q-P|lpxN)G`jj zd(W-0^%s0v%g@*?2)Q3!PJsJobRn|eS>or=gAs#SMaR^}FO;yGFO3`RjuSDmi(YuS z5^vcy3nndRs||uZ5Xp=OlD#S0iXO3myx_3+V)04H|6bg&#+0I^zW5;wfN%OsOWkw> zJgs&7VbNp$xRLdV*6FiJ{kAxzl(>^QPY$ZHeK(g72Z>7meZ+%Jek@pxe!|}wi%I&x(Mkn;{_|NlIZUPL! zC;;*=(lECBwu64wEZ_^E#fSI>{_tiDKijZ5d91y?YkU3hNeP-hr81fQ5lssf5lWGu1R$OH8=* zkG-@xvs~@1p#+76IV6BZh@{Tj-H0&uYNlE%TddPNWPot?#w>LYg@9IzY1PHP7sGdc zCh4xW19dnXgP%sWzpVj6Poze&tw$)homS6nPW%y1iYU%KYz3f!HMyBxZ%{!wsD@hx zDR$e-skJg()6;gCjoW|fvB+rp{@BfVISWpOy&;2hS(MU842+$@u8p=B#)(at5!%p9 zz;>IiAzNFMuxlC6=+ulASj(w_Y30^#AyWLO)q6tjt7@YU97jjCf+|J-MvoaV1#w>+ zsxwh1rSpukDbvEk#Yn+%o{y{VYzb2<2{vvIj-bx2sOJlVe~Q$;#RA_&6W)NLjm#=- z&P`@hLJje0OB$XOiKz4(?|3d)+0sN18ToUrQ%^LcyEO{(Zy@QzlJ(fWm9|()j;PH@ z=8ig;KLkd0qDR0AB1L4283i%+(m?oM!8w1qN&NSPwMzF(=SizS9`~-aGBDcx3EO!V z$sYm9w4Qr>_S4y5pQQCK-iH+q{Xr;=n+E02lMkq)jZ+hy>)x8=?v+oqm6UWY zIA#vVSn=MgK_y5w@6LMm>X+3FHG13CJo4^7^%;1eCa}X?eC>}{ybx}70!B8drKS_u z|4#Q1O*m-uaMv|Dd=T{D%MIignFwoYpS3`3zW|jOTFSs*xj_&8*)>{vycE4} zzECL(O~^`Bhc9;bmgz1c5myp% zjcSnBg0?r|hNvb7{{m6`6qee~t(eu^RR0V)M2uEnUC4c$!l1+(VB1>Oe(BAsh0oa` z<+<%4opEU|zbu?FVQV{c+7J52_x5BFliqJ`s)1HCAWfO{DEw1Ac|1=V5w8=x2ne90 zWJbS>ei_|EzYWPQW7h3}!zsR_^qRf=xC4uS#P(eANP78Uw&X4dwb<|Xccplo95E`J zQd*7}m{&w(whL?_5JNk;7M=55Y#C;`*9oBD>G#$ey^1h3KSpr|N|3=iY$qC$f>$KR zjB_A0H5g$vam@1fQ_v^^Ozx(V3bCUKR>d2Z;?mQsle}CCABoy_dwt9EqewlfF(b29 z0{nI!D}`_-%oOV2{ZOjlgk4HUn(p>Ry?Pt~u^##q;K_unDOh&TWivX2tUsSbR+vPr zys%&;c^P@}c`vXnau27yx=Ed#iT@j>?Kr;GQ-}w3+gaa>ziV(FXs&>Id3cKy|GxF) ziI;^gWcg$4As5?wher>cJ9PTcBth%_oaCYLLt{$LY^{I3zp_>G(&>nKMNrtZN&*!o zD0#g~#JqO{Cx^!*I3;>oo?HJ}yB#(wb;VOa`@{9{ixiGExyg{ZpI@x07dG6IXTPOL zxB_XB3f^<>hp!@GcGDaa_wdHHg1eCfHMW|) zeb!12xUmWEk9n-Sum5qN7tEcF~it? z;j8^#e9nQ%?VcU6y15hm=Q>#L&h96rwGi(2+B(=#q1t2M-eH02b{r(Sn8jU!tKRYA z$XDUFjHq1@b0OW|9)j1==RNdeenbq9mt-sOzj{4ot~|j_&{Ts5hmr>CeP?Lk6_-C= zNfy-oDy*Iq$Mw9h2%7i9X|^y4Z<8*iCW|pK-fHE6lf|8Txv#py&>9cOc6El7UyzVH zsx8X2s%yn%kES?xVo#3!GVxO+3s%|WOgps~HD|p14FWjasv5tY2oDt_yz(kO|MXF^)6t!cm;z+0 z(Y87fVF7Oyn@qd4G(dtSXT9obU?CljJLSbSQkHND_(mK9j7RZ`X4n9iibQU;BorQz zj!^f+t(1l9$6PJ5EZEt(+)NrMtk{kcT|dwQDRQ*zKB7UFRmY7h2|nyfnQd+rg$ut! z*&|)*tO|=v6C~nMUu4$7Qcw>|+Cn5Sl?S4z4dcYSv9wQKXFV4T7#(+a{(xagy|I@> zy9ML*1slPb6ToZDQ+h0S;&sbGXLWAN8J9|@ojJf%wm|s=$4f<&C1y0;kyDS{%u(_b zP`)hax-uuS?Le#20k2`qCptKAiSAqzJkqN7jSj*!b}sH5*hIZh??2^B^+p6~s6lg> zQXo6tHE#n9W=n=p6Qjj4@OouvG-90&XE@>bhL`RgufVn4ZsBP1q8AE`yIc(1{K?=5 zGfZMkL8=YN;NIdJ$5l97pdXO~m){5!JRRgrKaNsAIBvIh#u4Kk6U&vbHeVK)-^GE; z8NTcPdG!Bhzk{Yye-j6&Ek3S#^-iY!ti`$DLj1y+`<@}kTSEGOCWamQ{m^kGSlrLV zg`9;aKkL*_p>o;2@a~^>2EGR$#3z8N59M~Z2l}0`l*V&Sw2Wyl9{=cySLbu*uuRNRJ#%i&g@d%&W7WJAdV zV9vj89zEG`VpgKBR0E5vbrE@lzkjYXEqL;NFGaVMJb<~Mm3uIuqlozjl5fyN0DIBu2*bUf{q+x{j~UCL^KWw02^o7X#$-Y z>W}tfC-eY%QIs8uCm<%ik=vB9om`+8vB6qec%M&hQAVTK<*E)CyH(2TrW{aYfodCl zCk=fZblqqNMC1K;)}1$2gMK1^S@t4dHYZ1N|M2-$-zsv4xRMcQ<^CS~Tr>ZCxAWW~ z3w+^_Hv~U!;b%$8i`_gCGHl3jv7<-6_5KH{QM9D8|5~d}>J=UTnPruD^#{LXKTE5X zFa&QQ?Iom@i%>W%rKKnHn5{%2Ti1nEmpzIcy$gl^g^3sCDGr8*G&IC*Qg5?^ ze!lg=gl78n2bD()zlQn_uW336e(%vZ5NoDW)RHzNc@2C57?52Ae5JOQku+%Mt|i^V z>GkHXYSgmw(Uqn{Sg8kZ7;|DU<0))rvgTN3a`pv7*RFCKT>T)8dh|gmLXT5p9{R6I zNa^mTb*zuj%zoDvl<+Oxm}7!m!Y=Ks2@|6aBdKCG&ok#!9{HL-D)!;l9l81NmV?;# z$G|_LnjPmnY?`Y+qpvZQ19pp0J^t!*c{}q^_+p`$mI9X~G>9A68z7!U3|T$@>p_9L zCd*}W6`jj3Q@B5R1N4GdQ7!W67b*#klbSaiE}_Vk3C+x^RfE0a^2QrG)fTqpjg?!1 zHSzm zA`Z3X&Nx^!lm%00sDVbnbG&v{$~p*owoeGHGn73P&R)Ae4C{&xIR$t=unnYicSaLFlmh)%MbEV^bD|pE2vWg z%!473v|Pm@1c2OE&%QQkM+jr`DqHLNledNgeUSm7rkJp9I!j;1slW(Ld#Dx+%^x#i z=?Nl^FBVm--R%+uttO8@_G(MxeT1*wQ8ssk3YV?DPX>rxvs>y{E$P;;MLBu%Rh1EV zDayk~{Xm`I)n&K^!fuCUdsb9K-93vD%ZzlffO=m4&SaH^UO{u8<$;u)zJjhM!)hd2 zvDc_BVPaCs+eDnm?O2O;qWlV*-| znQE$fNWg?)3B-pc<}U!!OH0%Y+8A51sZP%aBf>E}3H6rV^ejEw-6qY&{%c$D z>6w~Kxx6^UO2KWgbC>Uf+Nvq4!lmhTYJwW$6|m>_&} z-qoiz&ax9J^TR9jSM<|Ks=z#PN1=%S()nnim%tA-CE(V($7VV^6qIQrOM$%pM)lxp zKlT#Z%(Ddgz2>j}lf=1&E;SzFe_T|KeCR)oid$;l4~PC1C~^ZBe(dw26NR~gBOajl zl{Wr@Oi<3eo(fdVQUQb(ig}`NYVI^48#Ys&0}vS)PY!f}_O8a_uysooR39C%TUJt|xw)mecI(}vO^ z5)3;xhV6Xb#%yMJS{@#$kAFh`$T*_zkF3HNsS8akI!>Tb1}41UBEZMyN|xk{AGDM# zH6?Ua1ui3Vcvts`zN)r9^z<5&4QLtTFCR_HhC~ucUl?)>lQa0a3$aEH+dEcc_2I0R zKMV_6;4#X|P|*Kec3!gTkAasCT1i?}UNo1J-JgASZ`$*P_=S#(Pk;Vtd8_c3*9TXE zJ~ZIEe(IBt5i55k{@!Fw{knGd6N*oOZMrw~ok8-y*?`nvhEIA}WP;d5Ux2O?rDz7N z>UnmOL2&KlEt7zgzJfws%AZV$h$D`3U|p|&H|#w_%^b{_$G5B}AD#mp?>e6R(2ZLB zg3Lg6xdZo4DU=5Qnq*hw6?M`Pn(Eu#D1hO32?i_Y+r21k(!+`3`&AJYDWU#Q_@AGI z9i|*0yg43#7SF?Ty{ew86gBUBU9x?IXu!gZ`v?I8i^NK_{FW;g{XM!Or zxQV&a@ODvhAwOo(I&^qI1DMsKG5EjH`%ls7pap3JHopt+iNnfV0=@Ijsg}KOJ3P*a zxRD*Ae;;FMu=HIGv07AMyFouD&MyODzc?NnSHGi+H|7R%qy|B)sul%TdgzgBIiFL+ z;R{=0^N9CeWJsh_w5Lr;#kCmZHmEy-CcdwGOqdCI5JOz-KOUl!XdJMx4XwUt^vO3V z?|`_Z1@5RM1UEmDpk3VSLiVX*sFuCbq!x!3t3p0q9oBsQpsdJSJ}Yl4CWme{%jwIx z);RVnPtoH{SALrR@UU|sDq!6C64|2cyz4U4P>B%FD~6 zCGCDmeH5|t9}fgeuqUH`&j(YqPjR zZRUl7jn&=Q!LCWc1CtP_lTC?Eb0&g1H^s=Ct>x7W=N1l227FURny+PPWoFu-fm}-i*?c&ZaT~&!1(605c_mqxF--{tC zw0Iy!p!hEp+fqor_0G3ctcu=F%$d3ZU&x{`bED(@Ke;2@;^Nf%|9ba-yW8{b#a(QD z|MI7g(&0nr+Op%s$jtX0PhQ@8dQnR4kp3b3M*qcs4w+l*)Bkk6=%YSPH&KB*SMu3f z*^Jhn0Hq~7EBj-5m#%fE(9L2VxV>@vc3VQAgeQ(LG;br(^!{bVcj^%r!OCS+s2saw zAbhcSDyvykNPH0d6-j-5jP%xIa2*4u%t>}j2Gc@C`;z^_B9gvIf zuq{aQ=H8H&?|KeRw7=ASVDXk?$5@DFBTxE{%9NM>SapH}qJZt6dc_4X+EuNVU#^N| zk*JN=hPK$GCYs*kyr3)ih-J(e$oS!G#M$4;f4`cNj1anBO2Ym|B2ynMO_pLOSP_?x zHq2@2hCE5hj|@>s2w=dXy&`CWp@@4b8x6mkK;~PbfA(wFA46;$@$#I?;boG@xshzw zuYe9khn@d?wRw*xZPa7#wnVmKH$Lyb;Xb4+SkAS`b4vkP_9Mbtl_m@q_{^r zANIAh?83a!nFZsD?t$A*k5a;MruS^dEDT^NwAXe2F#koC6lA(l*rCI?3vZ2=S%#q= zrGeW=2;K|Ub$Zu|ydPP68ih_MgGtM^nwD0x*^v6*lNrxzjL(ph_Bz0We~JSJStBmNkwd$4=9yh1>JQOI^#89TeDaPOHeW&LS1Ul-))O3vj9&-`=qWU`4jZ8>Wb!)gjPBImUL&yr-M6<^{0MMeR0 z*|icu7qwTTGr+7))3r#_67muTsXsq^xepupj)#5V?+40P5s$ib4VKYxVaHc>eIBDy z`IN`RGRQm08z*5=#pq&GoW$GW)v1?2&3p;=MCIqEUBAKk5(6U>xQjQDeXu2IeZ(mF zEnY1l76*>`x&CXjGu#T&m`6d`ZqF>#|KPL!ul66Emozm{-_SaB*0A8B7FDrHeoivt zut`R2ik7j~?XxF!&g$?B-6RfsA@|i?{&2hG$6a+Z(I1|4OjPl2oeDCIKt%U-)iwY@ zTJ5OWS$_HrWfo!R1(d&U<|H)PYt`VB4)o=v-49NY5(jemBXSnWkmc%bY1|iQ6#@7X z?#cB?%8*Xr%4HWpcdHzMb?`M>)h#7V-L>4rmLls8EKCc3r57n?x9;JZUyE8eWFqjv zJedTt6aXn#+pH=?Y3EBtXZXkeXcaQx`SW`H4X)Q;Njz`G^dx zPi^mKhHaPmTzJa7a>lc@v`h?;+Vg_0WM$s~w)Z$0s`GBgqSCy=f}qf#;;n5NU{-== zOA@Dyk(G(DG#=xD_*Nm&nn@9l*DN zom1nDh0Bf*hH$XG`Q{-JCjryoJAdO+0eKC+CFatrDla)UcXb;eeU^`z^-pIKl6=tG~HI72m%h2hs4*Fpc#+s}uDY@K+=v!s0vx8o=zZMkTsT)?Rs zZ`Lg63VYv_{fR8L4M*|9cp`+I4#MRraEXNF$()ndg+nQbqo%D8>TsNVMykIGZ*Tekj1cX*b5pBLSz{U){{ zdv)6Y_+E>mt^>?P^EklcwKnspS@Xe>-Bk!49C}flST%SWh+3%o-1K)pv)IFDTzdUh zb*tr&^UeH=oU6&pdzRn`+$YL?M@>BiTh zKtD`<4W3r&*AZ${FrcG@5D!|x3#}C@QxSuvmUSU~dHAYPxdCJ|>}>Qq@sgRZx$wVT z-Ql^S9gic4@|_7XN-~!Z>vJ~tUAx_V<6A#~a^wC`-M){&vxYedUTR7g2|h#8phRG; zR@V3D7oQn~$c4!{-G7_mWV@!jq7#vtF!s~_xF#VJPKkUwH{bTYp1lV6=RTVVL0Cm$ z99t}yIbOKI#RQheB?$H7N8R9vCx}`lbWg^dS#znJ=W%wajZaz#u zyHdsPiK>25VEK^C5j_%&H{e{j(_e*}I~Ft^J`J~57xs9A-nzYtk&SrsK`*$R{@^Qg zVt0Q^J=OX%zILiplQ_isjnbY8bRy)_qemn3FD4O9D{6x18r(hXdWF5;@D^`TcUmUE z9=n+MY7?ObB<6G-#c|h{+bw z_8x=KvD>RQt8J@b@i(tJEhob}7331}I#5E8m%u&zSz~PC!bC-^ zZ!EHxHEOzn6T4a=nCFLIB|iH@nCNj2Y;B zXhzc5+ms^dM!Crz;i#yedK=gO0;~MTqH2TLO`N6maqVwivvZ9Sm|ac+1SKi#$ta5m zT$}<bZF#Z%0}2iVnL(d7$ez_lm!y$LOENwL3O zH|Fkc4mLI124+e_1;oaRqYTaq;Kt#=QRAiXp}uuWU5%cqpO*@;7Ri4bUN-V?0yb)H zEjm8T{7qd2a6(f_@FmG|pNLjeW zDL{7*+JkN2(46wZj~Rhlaw#Mg$bjMzzeVy{O;-x6HBbvDy2Qawf|_S5Ui$jGo|=o* zzCl|}%xlEnU|U~UzL@X0 z4^Udve6BQnGvh?uArH=(jNe5we1`Ft>!nW%Rpq}#DV!8Kr;)!kD`rV^5^n&{^I|nF zJ1xDf@{g3jOKG3_IGB^$t6gBnH3E-hBExD`RYBx;M&}al=y&$6!l8SV`J6$1_X>-}OIeoVc(8FNV3ZpHROUui;X{AEC4Rs|dZ;60AersC**;;j2E zs{1AjmO|o1`xqr)AKem_JuS1$cv!iai4_cnKlx)U!h1Z_dn!hpa_2|%EzE$zQ!9n= zB>2FG0cT_OliBxNnLd$VA;OGPFqD0o>@r!BE7DzQeZJV_?YHFfq*KAZSK!4_kxnIB5~z^Y2=1?% zcAzit^*!{_6_9p)zN{H*(2!hh4*}rzN)ckOLxePqlw)w($Gwa;KUi*PmyhQ;F_n&_ z@^keQtq`^f`*TEcgqnvMmaV5Z@sSY2Hi+ywxb8Jf+2O0+6^b`{u(8j0B@O1`6Fp`& zW@E_&t479LQcdJJ_m4}F31?G~OnxxvT~Uy#Pg z!#F#h#8HUEeTnZ5+dlxo%is2okyJf46*doVon){2vu3K?!@+0NkDawm=RumQA!C4^ zxwwY-IW>rL@Skg@9`jkkejI_tGYU0UHeTFzrLD`Z9)pi{o^P6iFA>C4Kun*~Y_8+A z>}z<_(0RlnqajG5fqu-oGqgw0^Pe|pM#UwiCtc!)nod38BuOmsrB#C{k)sFXTvRxMv1UwFC{ zaP|RJ7mHe+`w8@6I)3dNb`D0yX@avn%g^%R4O#yky>d#XvQiR6?ur=T4e(;+A(1$s zTdm=1fF@JB)Xv+R7-AGcOYDg28)5Eub@>UE9fknkw7K8k5u8-@&@-4j%HR%U6!STV z#7eg`qbo-d-MYtjf_FqcfAcvD4~2IL%vhyjr27YP_Y7^DwO)gjOmOGWefNm+lcftE zYuSSbmjV6AzqOvsJOnf?cHDE}rm^#MJn^0xl)Q*W_^Jt0Y5^r5 zaXYN3HTUp}Xc6;n&@Zzy$+Mt|$7(!bb#D}=BsK8Dv`GQJM2{3z)yO+RWlagqG+n7P^bDf!a5XX-7vLXd|53(ynFpXI2+ECj?cu^Jv$Ex$ z4LMldn&nWpvnA2w7E}V>=lz{5;dvU>Ugh}6oMDj!Mw%JG>oIJJcWAZK zH%7pLvQ%rkG>r*S&0duhw_#@)r~PEr%{CKmPC!8CO^)zm$tl1JR97rH^v{I;!{knE zc}Kh%$HI+}35<^4ddgAEqY>XsNGwp+)sr2yapkd`Og}8gH+g_Um32^{w;XK z1~tKtuAZk!8t;{;1ldk^$7#z#;ay`n#HxA4W~|+H#@7S>LxV4icj^VdpKr2Q4E%K*aW9Y-Z?9k08Ewgt4DSZIf)et5}9_{L9by-w?MK zGlG|z%P{yw8G_e#ug?nt$LqY;nlYcf7<0*W*q^~Yx0AW0m47I3Vc~!0*{oL7h|c-t ze=2-w6ykJ(WmN04d5P=mPK+CqH`Dqgyj8Mf3(G7La$-;HcXIZE<1Az6Us`${IdS>3jC|A@yO(qlN7KD^pBI4XICf9o9NlWcQ( z)N>iWBS8CdO=51lK``gV%krCkg8VI0 zt6lw9zduh4@)7DlN%5YW?nq)p%&@*tDUHQ>VYYYjlKDB@$-FIeVmNTLtWHs#s z{q6>%03<{UxOQ(_+-KK5o-aD+G1NqwLhVT9!}0%E)-O zA8!sW77St(vI>LO-T!u?d?}qUj#!J`72JAf4BHu@zweqXNf}GCdeQ^@Kw-6E*H`Ka zAR(ua{r7Ss1zYd!BMmg(sYB1*D(O>e;8?CP(d9on`1Tv1q!;(#@Hmwi5(puWNo{*{H2 z%uFc#z7(Rn+#ufpeB<9oj5re}6-@rh9v!I)!#5bXU?HUnz7rvRlQz^nmA1`p`%U|; z8?5sy8pnSwsf21#RA>1zlb|W-iV$G%4BY>3z}Mq!N(Kf;!s(bBJrwnITv+nT(;gU0 zJVWRWWnWmh+*}IM2vF(svEdH!w~u}SpgM{QYnw)yn9aI2P}o|-XY6n*kQB=elRlhI zjlB&D6tZ8=V8?eY>VnF$HKXhv{Me{h+i1xh==n^@8UU{F9YuIN<|-MmJLE(-XAeW} z=VUkTRE^>Vx6a7{xmn33rQ%W59x0(hamj^Og^++$JTu8f(9!n)ts6m;G6oYFyspMM?`Dd%Cc*-T^pYguSzX38w8&r)zfA$^_vq3?lDY*hR-S#2S;WBR>K%!c5-Y z!i`?g@e95yl4x!f;WuC6r4EMeyxHAEdAh#r6E8MO!67@BQIHFVE-xJEFGo{-<|~ZmAj{LscP_)Bavr69@FDs$h#pa9R%yUV9jik_ z><_Fq9|lt{kWCG%3eV{+4R-JDHiEO63Jr5I`|u~Jf)UAnGEAt4fqIX z_kOO4VQcM$RQMFbdp|-MIc-34CC>MI^r2!<&Pp5B6?t7qplvaaT||rGZuH;N zO9hTHaRh;W8~0ZMq4!dwbgM=O_d2RUARZM(zGJKc_2MVGfqtF^R5G>eOY%_fH7JaC zf&GXLx+H>6-yFDt!Ta1~v4r~mMYP$%Cw&gxJaiZNSWppm2TmycQ`loeHbQ1Wf{&*n zT@Wh0fNRRt(ognnqu|u z;}%RyVp-X9R@{BxN|{8(e0wW$uI#rhv|Klya&hNEs%OX7Ycku1L1K_ipT9$tAyyRU zpv?FgAKsV?QK^9PhN$%rWB2&l45|R2;R>@h#w-@kIq4sw1JAn=W~9ciY3sU$4?Ph@bi4fR87cI1G!Is)3|!+ zUQkDyS8?ilszCRV3{_fBR88^R0Ms1$DOV_|+8nj>Qg-Hm#yE5zY;w6t z=0!4q^-(-5Gqswl;r^c?hS+q1GxlI(1$LF^G@}r(D{<5L1f_Ggs|m^$P>B_fe$?Y! za2gp3=I@{FJ%z`P>dIWkJU>)@tXI-BRg7{%|8z(uxN)tWDL6fE>o#yTSe#2*dt40F zvc?z1j`D~93;w#gG>2n#{k5KU^leCTHk&|=CH*D#E_{fRPCaLAB z>=}N$43eQ^7mOAQ_Br%mU8BKsIH4KEoi*K~{=T}(hf43>*qZ|E5VK~MNAJ|ibojwk z@H-XM66974h5M)aC=)ejg+bijf7F9&iN081VmD*l3g9yZy}ZE)+P)<_y$9B-eP-_( z<2 zf8$N#jiaJQvKjHs?3c!&)iMvf<~j|LHTstr64dzjRtfBLuASUw5twsS0cz=4SUl7j zk!dXJh%-K#N>>Rfr{{q!(20wn+$QOs>&r|BboWDSB)2UI7HvA&r zjv}AgCO`sDJ)qRC3=Gb)GJ^x%O@}lzISs@HU_VxnjWKd&kya$DCy7S6rZp8{yUL3L z-O?#4{LE@c>DRZR;^gcg_mE?26;zR}?m^@J@A|%b(QLV{9M9Dgpf#hV?-Bok&b0rB ze{q+R7q19YYENpPI`=kXp#`TPnP3z6NZV@L(&wH83HdSD`Du(4^NTQ;&X@boP0fWo^c9m1Zy8$y$7ioyRZR-! zb}gD-$442&P2DKMj|v?{?IG|FJhNFrGkC8zjcEk8n96x_AHqFiB``M+#=l&S)UTp zTvw&tF@fmqy)@khP_=hui2l8Z5>X$lh|ns!e_Yc7$!ZD!r56?k>? z1_LRsks&!WRvLw572cvW#dpG%YcKbv={D2bjC_t053XfX8fJ@L=R>3=LW_ZJ=(kcMc2&T0UG{SQCIz@MfW3;gJ zA^wgh{+k)l+0M)-2>_0CO?|uV+*ps&I9~JkBu%;=w;^GS(!$JCe!tl8eIvy3Jko{| zH$~%ji)+cxj}UP9k>SCGP&0OI!mycI;*XN1!?QKDzhm(exf|8Y&oe$lw3E<-F^kvU zk7SnT0~yS8`J-Ixnp8Mc*;FBJc#kbM6JZxWRbHzNGFO_L^lHo}R$VL7@11m=iT@F; zxs+9aqvI^DS1Wa%X1_z^$abK~}YBkVr z{{SG7b9JlfMp_B+peY=f;|3vj{^R^0>t4nBZXAXC?a=EK?FLb8nn_XN4qQlI(Lax0 zYbgA7aQDWT`zHkzr}aPjthYx2W*v;|jf_TAfM*kxhetSqbbgcq*C!qw+G2gau2<^R zh`yOWu~-UCE6YD_!-;o`JnO!iy2Ds=UJrHc`GPH{IS<(+q-Y0;(2!%cpsH-a2QWct z7>umSXEwI!zx8+^QVAO>3ygvlvBu1H)GkbK%gTAtjlFJjfH+eN#Id?$Ck@HdD+2!d z9PJ!;L`s=`m{{CC z#OXJew#}37TU^z)y5Svt`L}(q%cTzKIZI!V)?@tAaV1yL(qFFVR+h{9#);}zTuU>> zE=d}2+Kd488ooUT1Io#FRa%4JM`qE))hX}JnvqU(YgBks{>>b9h_mmYhN?O4YuZ(( z&i9f@yN@#H%MJA9kfZ^o?VY_L3fK7~ykC~IC^d1tp!%i;$*!P&dhtd|N^LE!(->0B zBhET!N>uAziT*vc6 z0`uYX{3clT;0ay&7ECV-@?d$d3)x{-`f~#PxG_K8JE_ek#58CfxrtdvtRs6jSHe+p zP|MCO>xmy&!1}H>YHs^ps%a61HNJoAU&A`cVpD?!;zS=P1J-IF&P#TT7MrV5EOty( zY4KsK>cJrSfJvNM?LXP%>*>`w&obfpy>wl~mVNX5-8gcJNgUk`ZEk@+sz&VubxN-`hP*m=6mXev)o93eE=C zYFrRF9Ulm-9G={gD*tun445HnG(%~w>!5QJc#9`7q>sR>5N?T7+43XzOzsK6GW{D_YGE=tub!ZzF=7#6Igt}<=)G#^R*Na{?Klw< zs-=;bXZ_r0r}cwQ=X%H{a$VS5@$?D0p;-44fojFJDg_~9LH7n@?Djf=kLLk_N8^n9 z!FN?>dI;!iN>u8wyr!pOgubY71xHa6!H;ZL3ZcL28j_IswqshrhlP+JN10XZ=wJCL zZ{G&4$7b5kI$Oftsur1(i+}m*^Mlzu{ZdA+JZShVh#GZDaiJoR>M+PQIXmZkHzAP8 zCj5QZ&nv08TJTFWWH(>x`(jn@NqM^c^h&O+dsPzT9d=3jbOdv=WG(pcFOi=S!hnx^ z&EQdah#2RYUf8-M(`&8D-FN&`LGP5=09DxuBJav?!NilqQ-htfW!Kd0a{(yMRl6>uz`N<%)s4b_^`=qh zX>?-CF|q{YL5r+(?X0UC^Dp!=NA;>ooBR5lg5am%#uQpEt$<)_DgqL^{V!Nf_#J0e z(KwsdE-Uo{eC1NM)ji9>o7R2jht8bVG}i10w|I2p!Mz7bj{@JDD@gsu-DiEX>egjP zarf9FDMGtk_+a$mb?xT~eiV{D2*Dx6%1~*)D=d&PYM}YZ)8nyCv3f{;6`tg|>=nB` z;fLcYCJ@bqw)Pf{Jzs22dra;OK548xP7z)vp1Xtynk2Fy)M4$-BCSCkf>-XsSiR_TqxtTYw4cyfdq*>~KQ@ za!&~|AG#UAKmu>FCx^!=FJE5(KGAsHkX-Xa1FCC-&c$?y{Hughlc}e;ohMn|&4P>d ztE08}kgheSO@v)UPAR-qH##N!CH$$;fWkn6!fs-A$(Ii#AcZM0rh5P}kojQ-)SB%9 zILbV!CvpUXvf_*w3o#*O;YHn5*NR`+F^=b|hM9tk)wVOWJqPu_=6 zyiSZy-HT}4ac20a&zN+9Z#S8>G1DQeY{~o2u!x0|=SwyAR`1C;F-{wL+}U1IZ0cm| zLl^8p%%2>cfyLiS{0H1-ol`fz4cFmh-?jtxMpDm5dvqN!ybVi@ zeAx$_l7gA%K^M96qIYRZVhWv=+|lThJ}cNS0um}r^EQ=8AA1)fSIh8q!>W*v(4Nmg zV-J@4`X}9xm_6D*i|=kPa1&v*KexUv7EB@JmP6gKL$^W>nsVRQg%W~EDSM;+`guPL`7z7R5+ydG zj$+;kU!}N($D!v0FY+Vjnp)+9Nrpx)*ZFYgZv= z?vcQJT(<1bD8+I^;sz*72t7<^guYmspD+EdF4nOP9_IY1*wP2m2XvOdbEH(BUH_?w zu+!IynSVOJA4w87K4&?5Pu0k|W9ZyJnlQ~TE4mn9CG{o@cF>vIlhr994RKce{oLr9 zcuv%LPPXjAa`ttW+LG|p;ifl*Cnhi|!B%8Ew;sDOXGwU& ziqK;IN(rAe+1|TBU9;gl$A8Q0gzmIe87+!L@%ee1`SFOT2pyW$Azsqmb(^Ea#EZDI zFB8!NaoPh-6lqhO0#1GP?jew;L*o(oTaK-9GOML-(9vFx)vL?151UqdzGxOqsktn0 z&CL(@70*Pk7YEig0XrMKV$Z_g@`{AVGC$?1sE5Y~M)L&M&^K zZrkOIQSD-KQs59oGE#C`8NH2nPHXtRURw!Zx*Ua|#(z$3l+VjueH7MJTCOzHH}`7e zrGt=c9M*9H>6sBY;pwY!!QIH;g#Ro#Qo^mdyxPQm#0f6}gB>dbGoOaMJ{9j|VuVKo zHIgPUhKQT?s4zj&af7*U#A4G7);Zdn!gjW$!_0xL5=WxXP;|rcKSk}S5x<$&KxsuA zgZKtgDryA_A^Dz6jIj~gT}Fjr{JBxcIl+8mI$R7z-L#N6Iy-%PbX2qobH5xzAR74> z!m^7iEqF5B;L>o0+HPHZ_={n|0a48RsKE=H`sLSwEXs$uqZO()aYb8^VxCELczvCc zQlICe{I|%zVcY{ETtvO}407y#>2$~l?-;Qq+|U8^6tOiwe#aMi{S<88a+Iw{8|hr) z`|N%w4K=0x@hTLZxc{N7avnx|XH`RHIm-#qRd{$KkpJV>&QAd2_X_TyOW>A!M=F?? zO4C38lT_}G=yeaL02qAqRO;)Vsz_Eb0rs2sUaNt2X58+`r3 zfndpv6-?xgNn zt{hcQ-Z9D#@fD@acf=X>9g&wws&}v9Mj_kXsZZW%!01;%N38`{$R@ME%SX9Y??^Lt z0JBF?P^!+OpX+Usv!NNrc2v{&*D;(ytIZLNd;HwPMuuXVh&6s3gQG+rT8y)T{jKvH zQlb*x4JBKctllg&c&*GIc4w9Uu#rIo4`R036+nAp9-~JDv$m!W`UDEFeAM$Z(BNd< zNMSB_+CtO~eFnN+s_@THUEjYGKDM=2(AJd9`?@jlQ-dnWdc2%b19Zc+5SzB%FTWr3 zrY$L{FHa6hD#A(88a>WLW+G?$f4`eDVjLOk;9QBuk1CZdoGWjS4r^O=e3RXI$ zqswN{wwkdHJ7u^QdjDeZKd@04q>w)@esBLMUiZh!F?eO z3hro1k0zHxHi46Zpa#J$%RPFV9-L*{BuMOs|Ew?vy=~cVO4XcV-uuQOIn<>&%v3v} z*Yok*OQ6~fpywTAKC^(o50lf}KD8RksulF>y9#54AC65NK*U3=JpNC4;?Olo zmN(PA@yF9Q!LO^2Q&lx^*o%`-;9`%Vdev3XwfkLVCpyssL(s6>(!}-8%Fu3U zz5A4+d_uq*;n@X8mS~|%ZvSt0)*|^__8hYhYK-&C@aG500MONh_%Or1|q!;u@yisQpN!>E$epM6v3nRq?hQyb;o7y4A^T z?2K|f2S8I!Z@TLMeQ#A-r@84>abYV; z6ra;ytb3#2+;Znb!wb`wNGEY>g9sqUop24<=?$*G7nH`qB5knQd6hC_6!=LNnYI`(*7Mdp4Rdb z@Vom>Zcf5(75mdLvk*K~o(t?VGuWSqp2)LD{4}D(+!gtd=CNRdh3Ez4@3y0%oMkTX z!Dz~0IM03E z@9U1Dc^r|r*ZD1jUDN?wp39T@3VbxV7Wrh4L~HX=d&)L)srAE^n>%CnRIEU#d6(s; ze|R&eGQ${$RZCSgw~rGQkNad)FG@Mls;{GQ#xxHcV&SNo{Y>NE>D)e7T*!fykbxgf3CEC-y)R_?VZv(e zHbG+s;<9D~WDa7;V08C$Wdd&O+)bOOXLIo)`8&Gk}BIV#-{Nq1%S zft?4J=#d4tN+$Td;mc<`z8v_=zui%=j-B4|E?h3e-NglV^H4r$J+Kq>xk4k+7lGb| z)m5uN-)>=dM$f}MoXPv(JH3)S;g8WQp!3a3ZfEe9Ri+-TinY7zZM;F8<`V_}iI78Lz7PZn*vd;1FjRyMGa zyyt#^6Q1KPq6@$OkHoBRYAx2@86`DyPX1DohqhJA<(8Y)wsOQH=Z_>-TyVC2Zk}-e z#eGkaXEBiu33Dp?qA(j{$~g1(^piO-dUff(d^JgP9&xwXpbo(?_w44_-y1C*Vz<2% zGH&zpw1Q|~K&Z|RnZ`2E!QZ(j6_cUClJqmiDx!{DYr&|`pgU+2erWbeCd(v^9u7b3 zokxg?E$W(AzB3y>CA)K)Z3i&Nv2u48wf9r%k9kBAIf{~SS^}<4N1n%Rt$Wm8-yyrR z+(^mLp{w0DGtVIH=A9+05hA&l*Y0Qyq-7AFtg1vjGtN#1?IvjumWdfHY)*TOEO;^U zK%2C+GYi1VYRAMQI-iGsjPOddE=vv7uc=<)f`M+(Lc>!20xwrJWh(X+l}vpwk5Od5-eTWY zF(FpZsRuv6={{bPavOW5V6tqb+-2KovnV=Om4HPnEz!VxN)#z>RzPGgIi1bQ6cduR znA$aqPX&G5X?T>D+-RIr$9O?@8HV0+eL&#?@WYA}d z;LXmCtcZY5Hg%1mVWQxhEEo9Au9`oA95u{GfhB_;LHe0jHX~*+Yr}x`49S_K!mXA* z&l=>@+T*a%6omALHF|B$eyT0nDY?XkoI^!i`{No;mQlPW#TEZJM^uFJF86dcln2aw zv6^@*?TiogpPiPPWY1reU6-2VwKldQ9uD$7E$eIj%R?o(O7`5)om()bQo#;m(8cor z=>K-KHCF)4H04 zNA@DOBS>sU2?o)Uv6s8mcx2}>Y$9j)+STs1+QI`peXSg>~+WFt)% z6qOO^+oie7Fh&$No(joaJ=(9Ba&0YTc$X)-gubSS!N3E{`7ROPlNp4g47y&ZXuIb5 zU#jE>?TA>EM7Esa5nK5L2KyTdX}4`9ZZ+4ICa)UT?o?Df?<4PU#92}vCjWuTRx40d z{qoCxX4XyNx|{*YU%ZO{8LcyXLKU^1C7nq+Qyq5vUc71bnp(c}&Tdu>hFXL#i3m|1L^5jU}73322QWM10 zMSZ}SBz4W$#NU!{v}rJMINtiQNx$tD#9Mdn1FoIvOqTdSs>!gOrbJ8qF;#nMt&X>M zV0piy0+R3O2nhC&;;3IUOQ`pA4(?N&bOiv|~l{C6X1-`*>r+MHthu>INe z5WjGP0M)Q*=>b{unYu2xq!M*xAC-1BXY@k^i&W}2piUj_;+Wg|UY@$_`yBRts zKtmK)8uSh~jojG{_;&kDu02V1NUFg~#*NclmA$3tLMn>*v7!GQi`ZG#&te{Bhuodc z-|`RAU#LkmdN|>8MKu5%eFs*59U4-7VKz5zvS@GC6>k)_SOM+yK_jAYqz%YBb^s>gDU!Xv z{3d1~8ou2BFq%N3z{f<$k^kBlt zx3*rgFz}B1Xj3);I4SJ>w)Hg%VbetY35YBV{i~t=3)?QQUZC`ZX;F&WRzKUoe`T#dd_n%om3~RxX8j0X`n4 zyc-024fyjs-AD2WL$BCOe4J+j#Aiky&%QeiCaNwAIE{A+l12hA2ToE#BA zu2@XcJ=OW$h}nWEdSYX;f>Xn3nB(^o7uu+~sgrM@UNDC!w;($~Z9c4GMcSaeWqdb= zxLLqz=}4b2=X!5KU#_sfc-zrMD>dPP|E}aGmgfiu72}kpl|fI_MAkO1?5Jpixa=Ex zH!j||>%zGi0BP?ZdN{ZL+#i~)r*9&EwU9|C4fc-Rm*bPfbjH5JvJbj))+{J94j7=R z={}m)yww2%8XUSe0tj0ykA;BFWpqATIg40#x+}>w$CL7i^5eJmp?I_#a2Gq(hc}=6 z9J6i=(zsiX?Jw3U?aL#M*PMJ(vT*?B!h^xpK*rN6H!$IErkNql1%AxoplcQ^slbQn zUnk@y-djU~;-Kgp-bJD6C-q>2KdMcZ&V5NNNPC^MtAMmk)e~`H!J71>>)Wv^*9U{i`4ZH4EQl^av-9i(lBsxh+g@ zlrJ)cfPK3Ub6f0DN&oX16p9{KI3XB6V3uiyj)EU2$_&U4Kzx+EN3V|>(9{8$b?1o+ z56Tv5B@=V)K0b6Wmy4rC9Cr88Z!%?m{d3w-~NjVR@WAHQHd8tYianA>rvB zeJxO8>#&mU`l<<+;`Dv|!r}<9ZwBs{u-je#7^=lasH8NlNFu#pr7~2Nfo%V-T!4ES zu%Riz{l3yppSA(I@8_d_+lGYx8V|0n;DvPk@P34=wjDYZ58nQEshJ5OoL-aoQKq!bL z9$t<)ANrhx(YOIJ}ZuJrlSds!Su-%R~3JuoYb%af(^W8Vzz*-9LEv zaM1U#pP!*obR;q5Ozl^v$nQ^457;Jo#SSVi=-s~#t+si3bsW5wUfGm-q9lh5*zAc0 z)f4zpem;ct5tCXo0&-;e5;7pA)3_b6_!?lYYY-_115;iRN{SIhPuzdLJ=4f--0&ZN zs$=3OY{$)e_L-97449{Dd`IghAb!xZ&yV^fhaB(MhefuxUD#@Au*dP^k)lZlmbQam z3B)zt{=lC^D*+q1#{7#<#-9x!!I@83sdnsVR~#rSS6f2YpXPxgdeUv+cZ`awnkSy- zgJ||hs^E$z2X5Ci$gfxz{B{*D{8+av(t;xb{#T>?YBnp6lzX~-HdlDWG1q)MI@;)! zqV(xkN}vztnsM{J57KaS>gT+n$`3#Yz zwjU%GNh;SmYup~p|8fj=SNrgn#Oc@&xj@1-=!=&ZSPfD&pD=ggg89#Hhr5IRsq`uT zdD{7G)<@jnzPcvfj(K~`miIj27cogN0h73&cbV>h!rm`*ffj=(yxl+9H@-=o!ksXIM@E%vXmKDi|Vaup>@BW((xV21EyJ^CM+fjh4% z)k~xN8fGN#uW-b7xd(BPD5=F03;K`fgB0`SZc}M0fENc(U!4vAc) ze@@2Y}FU^b((wvxs8c^PXLi>h)XrwryZII zEM2?EyG76r@AdE5!qtb6jiJ;MJsup4#IZcH@ zzx1!2upb|NwEeb!RYAv-8+Wxm*Ys|J&jLRw(q*eU2F$%Eon{4y@+&-tWah?fDJ9DaG7^CG8x{vUaZ1+|&^14_%wV>yrIuF@P9#g^wB6oQUa-D(gT zAkL&@ZU1^hY8`EF09l(gMu-bOXQb-L|TCwDLv(M~# z6Mk9Tw=j(S<>o1G?38`h>%PO(?T5Arv*?##)o&xcrXGwd5nj}jGIQvd?m=zrHjj%@;R$zi4-6=-ohPcU8B(dy zxRAr1`zR?-ObtiurN3O-BfsseK|Gpg&t~c^jls;3&=7 zeuIi_dbgNO&!NO70p9Oz&9)LFSJ(Lvpa|q}j4u;82xXmP>9Jak+x9e?*T`+_aK<=g z)=IT$?{r_9(RAo#8_?H@L2!^!>BhHH4BeTIk65ns3#p?57T=JE>sA6r0aUCDg?>Oc zZk}o2+pCS~(UsDMSSAcv!#Z(HCOf zG*3(2t39=oy4;a^+Kd_nOka*S*iv>D=kHsNcY?Y`6#0-NSW^)VHZalEyDFgxg!B5` zX7)F(Qk!)Z`75X0IMegIPK>>A;BT^Y(w*V&=MH}x0IA&b*_1}y&Vmwu-;41VSM~;( zY|1j$K9J3>NdrBPAo=N(34B0;&?%%9)Y2!K*kyPAz4=A_hhTX%TUO$SW39Tc6D==gX{1loYQuukAkuH|zd!pzpISO4?U^=H)3nQ&)H*a5cf(&69Jj zFrgA}+R>@l^ig9ZPjmF!Mz57s+lpY-ocK~i$uIaRM>R0)K))I;M~L;4uKJTO$9Q{Km(8llY;fbh-tvFX@Y!)u_)L6#VVxj}V2KZy5P$zi z!$;29=L##}!Kcqzi2W7?_A0S{EXIhpd$a%Hj!5LlC*$9yJN@Tpuil{y^cp?9s@l&T-ZZv4v-6N!My2J(?e+U4YR}R^;>OSI zhn)Oh1#+rP%>^-?dJ`vm!{+mTaP_OYlzbS_qS`N^~n;16S zS(??(_q;c;q&foJ>b}T*U!EkrAiq53$}pnzpY$kw-{nL7M*l>2bN7;El#|Qa*3!w& zXgArR=(U(yDKg2VOe46=@Z^|{7{3Xlk(SI>|2SO&r5GQ++eUxUq!$eusDO&Iv}UBr z(6yaE>g9yII{wUXlH)+$gm5)pMC#bcWDZCvkNwUuDODziQoHt!Vzu*#Q~ndGHkrwC zR-FmOg55`ZQ>Wd#qZ=3wGq^%*Iq5x{FN2zm*TpAe59Fu#BT_^SSCtUyA=R3v){ZA+vJI(v~ST6*4Vs+)~_Sv79nVHtNP)3KXQPxIs7sv$G&QI`A#>J2zX=&F zM-gj@O7A!9G22J9M}U6R?6u~?<&9etW9!KUGVrL4YJ}$E9MCFZ2A*SZ?t}_(_o8Th zz#4n5`g`L9BW1j+aWsVO@V=A>NeO7RFBZm3gP(@>&9ryo+aPC3I|8GXy`=^jiW< zTj-46Kgy1-{;{brjHc(_yB-mu;VR_aO>W-nL}61}O(S}+3mg0Ud&0+h1{IX zEw_eJ{E-RA`*yWa&!q*9x*zegn$~^8DXgFOz7gFV%@37YHsPktw;gFws_B};>@PIk_kbz6cPN;#Ei~a4G{^)2F1sMgVKiL#8b%0VM85*U0)E!uWX=F6i{9dg#&x6$#b8cf&5b_(t0W{N=u$?@1l} z6pBdERYLUe>k-9TFIUx~{=xEYL_vPuJ1%p;8O zNBF{fE>vEoZ~y=Pdaj0_eR*$eWlOL3smCY(Ju`bsOZ|@7t#1C)OL;L#r=dmDRbNYD ze}^QoWAppBCI*jTKnd|s;MY9C(}#QQN#WN_&rhpOji0I$9(BxnDQ8>NB~|Nh0kW*d zb(anmlNA`;PkywL#a<$Rnzjb&*f= zc7lH~Q*5U`&9}6Ud=lyU0PQ*Uq!u?1*l1pH{fm?QL6a z-Uay8!b`&98yom=+DwadMr6*Z zXRICTR65On>4550@f_a6YOn6LzMzLMXKrm=od6$w7z2I^M(re?IgeZA{z#)WPbvT( zS204)!Nz~8n2a5j6gS=Wa&gsqrp&SQyVIK6ew&pCgl9L9ZD1nLY8D&B zf1ZGd2^|E@L$(u`zw2Q@#52ivf zu2~TBNeaZrP$SANM2dh6J{rKhpgVGACZu~+X=XK~Cf9zBm1@#SqL1j*p7WoWk3hMz{89cIPR$|0IWe zlv}}f3UpdKY@vit@>BZOkEFg)33Qd;#|Lj++%^ZTXu66_AuF>(Gg_V z*$tF^4gKHopHgO``)n%&X;@42>@yv2)E~V^WpP*Q%|5*_Ez?8YWQQON@32F>jU3xA zR2qZmzh-v2OKv&KbA?rwG*cxdKA5A_`u@Uxog1#g?Tw$dS(x>G9QZ@NaAvuqpRkAM zJVO5Lk~GV7Wij65V-ZZ2aJ8L;8ig>Q(W<{6e%KR*?H0vJIz)wR7%hH~>ww?zNRKj@ zFej~gcvDF~ZIG+hy>VTltc+BMpH; z;-ZyQJ3M#}au)tad60?hcsAZ+yxPPWe4QktJm_d2@jy=;TdIs-p!kr3|_2O+}e4r<&DY7H#31+xxEn&PEG7Y zJ#&;C@ap%DyQ=}7zF?>8$$t$6wuhxaF;l-y@q1^~2>ib|!?DQUz+Szzn{Uo4UkQE_ zPzG#QXPe9Jo5hPHs^yx8KAJ0zv70cS53VaC&mG0O#i%gXJLET^;scv3D%E7W*MA%K zOq%(AWgV{EPr0-Es?+cvK&ux~;PYq37t#CHcLb*aRy-KTxhmry(v8r=hic7roXGo!`0h}<_f)QUEi8EVp$inO*V`fm%y(Y zzuT`CaC@KY1EIYy(6h}aJn22E!Jb$pTvAoY|6jlrG~w+IYv5N}sr6_jg$O@f0>3`w z(hxe|UGD#!uI{z+a&nTZ)Z0?`S0m|$#<1^jQ2U4UP@DqaN<3H_@iGv)fp`r*-}bXr zz28QBR5Tl7bVb+=2u)50j(K3MTr{@N6$Cgu$&DggczRriMgCwNSJQ=&2ka=@Mw%NR zX1h5~w35~>7qa|Vzw+G`mU2h7ffv-YT)@Hmdms0K2}^ZA-asOlsIXV&YJ{iLJPx)ne3!P zY)Vr%tt0e<=wDcq!P)YbEL6}$n;ykcqz|XJu@;Q&>m}qZmBn}|QgNge_@dqo@W*WE zO5MAl8+~wsj&s<1tP6e>RqV(+a{tMC#{?&dnkW4St_Y83>wp#DD)sG@giKc5u+&#Q zO%KsgZB*zsGO5()A47A)1-)wz-`9G{D%#rZ+)F!)z^$+Y3D3mB=z!6pEu9d$Ffhkx zhYNWPr+bs_yQI0t!my19SkIAjx-+_g8yS%>8 zf4}SazVPpNVsAHg{IxJC|AY6~mu#X{nMoHmbqqL48XAERMXRO47pZqJTgMiMh@DH0 zEo@7okaJ^U)7Z3t92AEqRRd=IjH1o26#`lJoN842R#dEjZF}`SHq=GmB-WJve=B%$dg~MeUe_i9Dm$3yw?eEO4_nYfqpI_J z+=YMYzfyqoxkfH+w>KZ}cdAJ)Ix?iNZ*GbPIJBOpz5VRse50*}+!&->_8IY`eB{Kl zBV2by>#A;7D-7Ta?#YVfrx$j>c}MEtTPZQdqDleDX9E7HDirPd*A^PQC4Ry>E>n?* z+=OS15K(d$0Ju9P*-=7K_+_o-wdm)r7`zYJB0m>>fw7aEJfIZxLE@I)>)hPl@1%-c z-9_W?$k@*>rgeMJ%weaE8|Uv^G}?j@hI2OTPWIrK%aB%_n{t9_P?NaGe^pJ4&}H5zxH->Rv-Gn^Uqk zSUv=~ejNu6ba+8y+5s*|&10;aUx~Dn_jA6><@wZ{7tHd<1`vMNC|52>v6en^(_>IF zGY$6H{ZR({;BL3!tdy*}j39hkjh03bK0&l8!!WWv#;XA%9P&td5__cn6Sh5r)Gj-< zg*h;ArT7tEyS*(z8MCplN6Y&8XuHx;fO@6iDE(tZV)sny)_ArLH?eF|*G>6BB13p_ z)dj@7KZ5=P^#iMd!13cijrc~7IWJdc_F3_KlA2MNx-R#JfgdHTty7X_yRt*B_Nv4O zi!>MSTqITC&z0ii-o^YQF#B$th5DY=gHoK&3USwc9}fm^M-`*q?-AncHdPkkQ%5p(Apn2ofKunSF-Sx!sQiNfB$<)CD_`g54oW@&5K z^@76E!jWA^0aXZI3zlPyUmtx`^3gHMjYx0wd?LK8T4W`z-_d zVPy?%`8^_HWE?$QD{lv4qgwC&?b2!29kMBHCWG+!OtHO)o)X@nU@;`)As@(q;2T=V z!+{>kDCT9X`9{_`kR&b+Sjlb&_KL(MRL-`bPyC-_dJp%e z)(i5TX)lh^>qEb3DxY|L>bH~76ZbdH0TOqlUEB};?QHm2^84)&E!QIha4pTz@yMn0 z<=#c^QMvNNrmH#TatUBxl?=m^J{k$qyfP5VCRK7^*Ygg)xMZ>~&R5!#_=A|WVt0i7 z^;5HviqGZZd=237TL&)RuDUeldF4C^m)FzgXA;6WxqT$`R3BuW@#FS~>-W~j^89y8 z<|N@Mxdw9@7CkVdM13R1XRbhbF)t)93wY#XT1`+uVN}IN=Kk)m%aWy%?NLqRSO3bZ zzC??djUS1eJf_~dS`n(A2r^glsjm&o3X0`Vig=;SA5ROK?=tkgXx@PiWwut0JAr zV`(cbnf3g0Cx8bl=ZDhK0fg>cl?E;PpEO~%M&r?qhYNbDsbREZ%|hf7)}5H@I|mk= z49sPGk5K|>At6-Jlc>@Pl=BmqKNigMi3($65gOfo3i92PK3GSL3WDxY7nU=vmNBG9 zrFBUWsRhToGGiUDLb+;=Q25RI;F^;I8FEi&G;9U|!}E!i(pwu*Al?*332Di+!?qrL43wI=J8n zuKI}cx205U*fMw++zQHUg(0<8#nPx`H}o{Xr(%|?!DVmi&Gu|{BHIGuaU}jJ{1YHC zq1O4{VWpOx@12&4_Ozab)tL13S@qUWwun^BN8iOxjfsuE&ch(@+4U>JyO3+4jD}jj zu})Id8K`9Ho1RG|>l?ix9`-L`3-dC#&Q^$i87#ZixO}Px%=c#0{efw0g?e)D$3Em- zD=QN%RPZIWJ7MvY!5=KY63VOFoCqLu*}@N$*2<$ozS+Z6w<_eW zh5+s(_I)~mJg+pIx5@N1Eh``MfT9Xz5TfmE(@%lH&s=H+>HB*MK<;g1>cJaGrqbL| z%ZexGxF3ClKSoW_6DzUqJbgWU6O<;J1J&5A&KnA28J?C6U$7-8EBv>lt-pN`%Yi{; z%g7d2%lEn?$i?z>Cja#pbbQ`bMwl!QGu^3YKFM-jNUxm$! zh~szI`Gt$Z3W0_+Vh3RChCg!2v|=kHYHeCx%OoJ%IuzqkJ7UZDS&j*#uE6~nR~cAt zr~HV~IIEf_0%zJyIm0uggy5GtBkEU@kO8@#W!#h2P2Ym@Q;Z@&7KFjgxdNqN2O`Ca z*%$*Jl{C3*$nzd;KSgw3l_%mb&cF9z98SMO$gnel>us} zGmNEQ>*|9NjigO~7XgE)h!C8@SkE2-qHT3TQ`qh!rZ-puWoN2Pkhhl4;w9vWFo~*4 zcKd=4F-o-cwa&PIxXk^C)9cKyZI{nmaq`n_px!8I2zb@SsYbs=l;q?P3TFhg3_*ZQ zdPA#Sq}!&2n0M?@{P&xa<)-&Je|PITqsO1LW*Wg(z%c|u`Y~(b&d487nhmxS_}!!I z+wZ2c3(9zRWJQ|_lrsno+!<-$Wec14i81|m!9^^%t*wd|k#pFW$DUy;?RGP^6ywj*;S8yp> z_^*)w$=<%a+`KW0l-#reI(LjS~LX}do-Bg~EwyZK!J`>qC?WLEl@ zd=6}_eZ1&VY%b^xN89*NTmLB!T%Jg=HX=9VM_{~Es-i=kXp+8+JLJ)bbsQV_ro@G1 zC7fp@ne2&|TVA z(RkQsM2+=IOmT@!L2@@>cdx+|v&VF~BNVj~)*){sj}cOPTo7ksgiThiY4n;IF|n&Z zFw)W~^<6SG$;Gs|NC^*At^4DtV~8FFv~sBWkZR5ZNGNY8(yRX~W5w92Qe_SI#n=4oNxbVtZ#c-Rw!(rIkNFt)<$PqBr+N z=$KpfGE1c?VfwC1h`lSf&qZcK)JU+%H~G!T>!vSnY~*Q6Q#?!Ob5)f#<`cUG%3ETS zxDw&$n*{fFsruoCt1{ZULNqs>vGMCXBP^26idGahsQpqkzl;QhlBL*Fz^eQ2(!pAxb`F1Y$AEYRPSMqRi;D znO#mMIoG=Ob1;<&a=fh{Q3kjrtm^n)MpKVxuaR)w!fTs87b33L4V4nhwG(D0wDU`ge@6ggYWn;`nQ>OixeGAsD!UyF&Sy z)h5*9oq;t%&&ihS(yv#Hb+$H#m1J(-sj2CltqZ}2X8;a*2VZ6jdQJ3Q9!MhZjof#s z94-lIEWN|gVv5&0a@|P>?LP@x_T=8@2HTKYDW%yQJ4h6br=I55;`K@^6oLdW|E3m! zTl_b3Lof4ALTr6LG&T>FvRgcC4UXO8uMjAj#FGx&+%dm99lLK3>W2XwR)G8BiVay>LHWRtoTA!*z7)x| zNGy=9WbS*FjoOW$DfbVrO7z3tg$c)Fm}%1SGDP(C#-5mWl=frVF7&ZY(bg7#YbdZ%Y>ptAi1`ICD6_~RopAajd&A{WksBV4++o=*I&K*& zOEs|A*e;nXd#Z3)a8sk(N18f0T+E}^);=SJt{p@AxUKLL&ju>7P%Y#Ew~@f{a32_} zx`>_rvh~Bt)u7GRl8@4+Da0=wO{9s>n*C87Q5~eT5G8Rk^{t>5e&DS2aK^~xB7FzSnJ<@O{? z{7X|9Z-r}&?YA#tCvW}NodIYqYSac1$QEr9;dT(R3f!KNV^k>ifE0C>&?hapea6G_ zjb|O9E1pSS-I*aoZylfYk_b*wQW;|0DyU;d1T(U$ai7Wm)v`OH`-W~%LV=G-?{?H; zd#D(7)BGueVu{SKG?ROkys|+J&!lumB|jbL`@&G+k}1?3{NeneJ;i(KTJ=ed!v_Pn zYBB7X5>b|3SufCWQ}f{yrOam%%MWZ%7?H?bENco$Tn$Hqz}=jRvXJU~C9%c_2dtG! zZn2;V?{`+=lzhgFcCo85)(t}>=LS?sv9jj(*rm>NX&6s(l1khrmvtS)D}zvP^-Kmb z(ekhT!gN6P;mWp^6YQx{c2sZpCS|tPaCrrpg&`@4>fHi|*ik7GyHolB`zz-+A>d*8=qmQc^q$c=SET4>3EiV8_IW`!W%W?E=P8Y z-vir+?wMT4&MBJm<~Ts2=F}V7$bDxCv)b8by~2qVb`5YJ+I}lf?`vX_R7%Bep#&B(7iS5T1*$&k{e7O$-2?21rx}avA8$#cCKithBdr#D&A635TdEVi-FK}?isySV3*}ljQUxyl6lYB;n$iLuYgsv-aVYiWANR?VW4BA$ragQ z&wwEFnL_#%h4s*Bk)~?OmRd!&Ppt+Nl!Ez-_uss1#Ycs+2_q==9FGSy6{ZM`9?aDv zzbD(kZ^GdbFA#r%3y7^Ga!$wz9l%NkC4&qWhv#_Y#?Q~10)wfiXcb^{M=I}SjA?GE zFh6aVH>-OdJ5m?^R$@Ha)8Iu|2b?n%b?Z>hv^fBHVXX|{C}MDmJ(f2}0dtoN3=-`` zU+KZf1+{?p--(a=!iahVF8-Ycb3~3w$D`7Kf}dXrX>_q%k~wPghNzY+{!tTS4LC! z*at}LGH*CFuEZ1(-iEcSda#Z3Y2sf)NoY{0X6cH1A^S3~c?LisNj^H4tG4phzYhWDslJT-uDpw_^*T}5Z2H*s@!MB97f!#U?P@_t@1e|n_ZbnIeb z=e&leRefmr)k3OXw;Mx=Nww^bdLg)l4q zKrsyxl?_5`@?NT84RNU@z-rOPDUxm(Sple8yzU?#7Ze*LGRl0>Y=}JM0k$Q}2LR67 zmFHQbCHz%YO>9tyF8i&|WG(@7e3>B7#SCNv`|isMxV*iRFC^jpT5aHG)aAzi-lOi^ zJHEWbkTi~8R0)l{(eYP@FUj1pIV-sHl{1J}p`15wuJ*Ru zq-DHGe$T%8ZXd*Y?L*3T#3`nNuzTdu=`6##Mg5uM>HfhEq&swh3}=flrHvW`N4W8I zkHH-gs-619j5cl`8}m+UBTn@SSRG-IVUV_rMKfA{0sWg_3BrF?5K@ORFQnnjH0&2u z<-RKWGtJ~m?MTD0$aAhJAQ*QcJ?!mlx3VOTna1zJM7%(;*jLo0b zL#-9p^#mpqrW-8UIT+e#u9VzCU)zGNPr2PI{U&6)I?wS`UqwyDkJ3*52V&%u1Grc+ zLS!Eq-C~T4RgwEUr zLTlESa+5W^8p&w^xu+~?&nsU|b(k&DKgn>6%&6P~y7W7jW$n~1ZGJbeKcSLUAF+^$ z)O8&C1khrjBC64T==Yw27!&lm;9Q-srw1Gol&)W99MEm46%D(eKdZ3hWJh|)rcl#+ z=zwY`AlMW0-EN%p2bJ@b-yZ4QJX|lrhOCkw`nhg}i>4RU7s>lUnZpFeX$)!PLp4BD z?}7+K$HF%E<}TC0!B^oNvCYT1g^Hk!i4kjj+qF)5c51hy9VFf3M3@|k}2V7kgW~#KwyB5@c z)twYHcJ`ABECWD!{UUz~8prk-UAaw(ZE>k$UaQBk_mctGPO5P@?G_NPuEKL)x8~L-4;Y>G*fv5#fb3exhIVM6bne zK}+vpA>-sm0wHjW0$vWW+*t9{-<(&i6uB)ezP095U-5l{ZfpTc#XG%A6q2td83dq~ zIigG(c?}1k|A44>+%p9N=UVJ|srGc(@$}P_tF=f+IPsJ|f5}gQv=-ag#8-Vs0|;GL zm1_~y-v5xa1`J2S(20N!8h>n5&@m{~jf`d6c_3gYVI6xc#q#@nwH zoeO^$UmZODZQtGt**`;5o&2~nnZNkz2QAIps7Ch%fT08G0qL(k-tD=AM97rFx<*>(Iw12&H-ardR=OwlTDNsWtbfxfZlHa^ zC`!aTTbtp2;=cGy>(Ekh*b0IA&FjxgWuuSUoJ9U-@Xx;y*WDxD&pQ*qE4f>!CuW@u z@Lj1&^xNoTo=Op>hH2#k+i23_mqm$d9xAHY`j&PPZ#524MxM4C+ED-vJotg1UMm~t zK5@Kryj!iy7{+o$)oy!0DvV8c>5mx>1U&v>hlOyM=YD9>O28a zsX>z#-;4(D)8OqaaNZmBurO3~F)FqK^%$tZ3l+V#epJR@$)!xTeB zm^!K*2X6?|=XP)9t`Nas~(2CLgsq;(Vz;S4(U%KGYs`#UoM>fzrMVG*h3-{$%<{! zI=|TkP4_y17EfJGUjFmj+kL-YO*T=3UA#3*byjmpJO4TT!P`rDH`c*%gmNAEv3-2G z{DV2aq=V@xD*5Ot>7?VNf+4?9V@!G+ldhI6-p@nKn62c%46~igcg@P=$pLm`xsoBA zi9E4^*fqJp(7tI(v+FK+=I5(})smMqTfDS67aKkl2Duwczj+Ui*u~Q_Uojt z6eW9lN;|ECuT|XDeK5APB-i;IHnRMVFUK^?Ft_3^!MWd#^3bE2d-XwVoqK;x*HGCv zZ)7ro@brbH^#7sh!aPZtWQy9zgKc<1hC}IRgf(`=z_G%B1x$fVB|r*h`ojAyTw(Cb zjN-~m*2ReVp)!zJtVL~(i~XncN4__+D0YSy5c(%=Xvfm<{2lE@#NhfI?HO__`}<+q zWLbJ7J-v1zhECEEPCfcUSp4S(VF}4k(v< z`Tg9pgSutH{#tAL$w~xcilbFKx4XcpQwQ0Qa0P z-BPDJ%V+(FpN`xUG;lcuaam$Sk=+mdXqo^~1WKMt?;;VOJdd*LTMN(ns#&HM(1g{v z63!~a>++q$b}A^xs4F9VDHKZBtuY+_7$&txDfqpUXDdCf>wDeS2PYF?vZ)E4JzW9l z<$)iamma~>8QAq+R+$zy=-gas(3`}%w8HDUjeYQv`wbG*{Y?%4cwa+wm38@DXvhMQ zUA6Vss>lRc4#&LYt?_zLj;KW4vO1o5)uNANs3aw|)T_7JxIaC&6KN(@2Oh@~9_$8h zx-g9Bl@Yl++uU0F6>_btkd0kmJ}QhVtTR%%ou^jGw zTm5H{3#cKqI0F0`B41JAU%Sr!M|C?mEAdi}o6T#AZ>HWeJU#a8Y7H4Xv+tw6&ZZ-* z!#~a^ZawoR+iEDS0N0p0g_u0vY80CKG$by*D;n&n1M)R2HHjKccZj+ArQ^?U+l{s$JDv>q(!MKLizoWXf^%Mb+HooZ5tu zN6bY1n`MEPkoPb~Q@RvCCLS9Fwpe1KbIv`x-lNO+~W8C>C?7`V&e3WONGanL?I zyO22aDJH%f82sHE2l@NIm7Nv8@+%uLv@*4@lNTC=5)r|5O~khR5fapD^VY6N7ph$r zGfx#hp@mWQ>>%b`4Q5$=u#LQwuS*rqdMcPj^}d^w*a~t>ou)BkFkA(>oLuaS;lNO` zd~XL~m_vWAX5X7JvPtAAZbv^Bh>3AXjEKpNEk@SQle`xnpbaiLnSXNo%lB;nPEbOW zA=?fK!O*%gPs2`+#4*(G?@G#?KbNHwnOy#r4dj7AAESb%oXI@oXPREsHlmPtF0~d1P9=}t1qwswaQrI?zQlNz2 zQ%SnRbpJ7uTucpFM(^_C+KLX7hD|9f0o4;Mmwum0Sj{)hWcprVPjx&=11vH`N5BD4 z#Fs*be|De|MSQm|kbZwI$@wFfFXy&0^1}=Xh|gt_TuNk))KoEXj~5Qi=WE$bWcZTx zJ^QPrnR8Z!>w6j;WL0D?Ox*-RZLLhlrYac8_`bd;lfY7sUx_oh(i!|#!2D3*d0j$67Shg>%=l?p~ z>@pB>U_6W`KH9id`*j5d^cI1M>_QC~H#J+UL4QNMX6 z*M4R8DaTSdr)&{fwaG?qv}2biP@7;!>CYoe{?w4iMDcdt?UC`?#C(j@uB{D^)HIV0=v=9|P#?ad)W4M5PY3ld@Oa07 z$W?9&M2N3BotCRo2x`+0L4!9J@q^loki59or-<%)=i6GV4Mip93VR2Pa>J4x z8L2a=*EaWc_*foZ-poBjuy6zY>Lg6^p;7f+oYL1Wp5JU;mRJHB_b=u*M!ownYxz_Y z-z`*y#tAer;atr}h@TCtJ>IZx#PPKTG~_iP-F#C|C9>Xaor?D)&Rr@*6CUQjlKgMvO+Vu-DHXDzZA^&L%{#*(nq9!f$wp88787r5a_=8T->C{+M&s$>GJ3P{# zz_2D?6}l=QLRX8LEnued3mlD;cS`DgEZ@j}5{ z-&60H3ALLaO*N|e(&7}wS{S0Yb$d(x8O3*U!Kq2CA#q`(L3N_j7c)b4k|{Q#n(W%@ zL3qM!UbS~g1Eoi@h=Fd_&Ar-RV0@vrwDoy;No^#H3yt^lqXr9KU9NA$Em}%2pm!^{ zo#6}h>M*D^f0qF7-P zg=sk}fckodkuHc}oR4SFy)6!b2VWPF^?OxXw5S9^m*JJ1Yy=k0DM3G69p_nYNvP(_ z7aZ|3Ko^na>$EUTfB_rOu1ML3Sp&EPJKSSyJf3U=3=1FNDCI92KT`m?M>UvD4s$(e zXXd`xdbT&&fq_3Pc}eh)l}+3(${TnsysPpA4y*Ry4lBh^&xDtun%`kQPS1n0!`7ee z%k^KezV@JbEfEhVEopBodkTEU8Gxf}YM9O}elJOcw5ymkHxQaoN?FB=-F^RBJeB?(=Z@XeH&=^TuKLy3PTn7~2(KQuD z%IKvT?P`@b#6=kbww?U-l(yey2#ujR>U0$&cJHJ*~-^quXV;8gWh0>%v5M7m6Qa=Nxi_i(H(?tDSk67t zAH;C*+>IJ^hxA~d(?#TQaTujHsU>XsG~?`C8k)QOipY0AukTqZp0TD|MsJZ{YO)9X6HD z2Zai}U<}0Lw|b3~+^()FOT2sF)$SH!RIJ)4q4 zni||wP|(31PcXN?$k{vbXA@OvIF8t&L>L>2yss_hSC|7&Znn6du`~T-=Dk~sdlq)2 z3GNUsVz%EogykovH9|8gHpvj#J>*`cqZlso2zt)ZXMo$WCFCP{|I~4p%RLBd7XxEP zgjJ>2klsSQ#6Hq+vQ{iOEK&wVesw|~&_4P&^ho&z+N7GZ<_P=^i?$#|Km*l3V3_II zw(H%b+P90FQ7P^nI}xZ4G|gGbfsU@yvKiwOW7Y!?XFa>S#|p}%4}GxZIMm#mK8UTj zS~rQ(P#3v{V*f_hY?jz@xkohJqx9*hrbfH5wk#}8R97$3*66s^zcYX`2HsMMOj>1- znhLwq@2oOVz!`>SY(%KbHBV-r5$WOQhTPFuiTQ8gYlju=CJA#)XW3mXUMT&pQu#Kv z#JyX~vzPBNVxY0Uz!%Lmyz8xJh{7SI1C1>8aeh>InlT%Bk$cFI(O9WixU3El6DXNx z_TVgwZeb3PN-;KMH|E>7+GP?Pvo^_erU(g_43=3$jJ+Wp&FqND6b&jk)(_Td6NAkd zkd$T3#X<)VrK8;!cd7>vZUwQCqr+ZYW!ps3Y)IQ{JCRcqQ#a~wgqm$Aw_m+~XZMge zd>!Q4Z=GGCj0qYX*mHI&ZO_IZBFSzTekA7c8NvL_z^B-9uZ%6Z|D3eLN9x;A!~5X0 z`n)yF_dR4{Sm+E2Z5-BzlmyzqHhZAo2L6*9%7Xt_w9gdW9%^@_{QjrPaktcMyBsq9 zL8RVM-F?2%TmM&`68&TI*FQkwSc6;fJE#$#Psizkr2FnIWHPhDTKhxjTHyMNamOy% z+cjEVp&q9U;58YbZ#{3Ri1MtiRyQj$>~QRcB?|~T#1x-5!vs$9Q)C7liu4YdIjNRW zM~?qX?EANMS~Yh?64e23kX<}4tyZ-BdF^+*eK$f1Oa`f)Rl_&VZj%=-+Z`8lt7kb{rMKsAS_sE~~BhoK9V&}tB zY<*D0Q521FE!EaC^MpHDVNr`V4xB2w{7Qx^*0?ZG-^fd?!QE;VDgD3ousrS?MOdq- z4SP3=onX8jk8-#PKBjc4>|(n81?2i~D6h03fky(78UD7_LMh8Ml97N=z}9Vc!h>cvH3_mf9 zL*%S%KDCRX-&EudEWoF$aRFl>>rx>s&<->4b?$FUk`UyXs*5f*e^tWMq-;pV`8zk_ zaw7occp!i74s9aOTpk$P5{9B{mo;EcI@n;?YLV=!Zi^+K9I4*tASmv1Zbp6mB%i4VEMI}=Q5KwFI*auQ_)u+AivvWVj#YWV3D zy5hY>KK_PmM?)aF!atBTrTLQ6j*^ z{Le)0kZSHSuWR@rjIv=2UPiol=;4J6HAOFvLY_O4f<{hRWG@Ek59qvC9!aq;mD*bA^`z2`hZcfypao1Ywp;5YlNrb48bKcRa z1<4si#Hln`3lmn+_X_GQ|Dr+anK46=$mexpBa+Ws3o(NG_W`BYKHDH6$W2$D_U7D z1co@0C{vFP(z;2cpNnNJBHi!eN0ElTZiW!(Kh0~77>m`aJV!&!LnJi^E^B0WmSzUE+`k1AmJF&417Z$p!L4K@4me+kZ%2sy zFk&uoD`ZSQ{)SFB0}qpG^Y1DlR%%MRS`P+~UTA&GyW;8gAXHr`!N`e{T@g{zLOr33 z3H~Z=b+PqBd2_0WYeY3IZtH+EBKVlCDUfgoqiRy1Jci)NnSk#x_}9F^sCRpSTmKa?@C-csMz-kZ&V0CMfixbTBN0Vb-tcvXm{j5B4;A&; zKsh7#9gpMyb55AhrRUaP#|h%=W=mD`1-=VT4`0v#8et?W{wn}yEwbFdWIkN%dv;wH z=*qYpwPG{8`^F;ld{|B$&D*tXxbrZX@MJZpHLd6uq>m&CE_N8fCjx5HDdX@#7-$l* zY*}XJdLDcW%4(fFMpW=RW1ct=kVKbgO~+E09@!1>pWNS;7H`v_tAB3QlJR-cT-k-7 z$SXad6Lc3mpg~mWp0oXa`767GI=n_973GHFC65^?a`O}A%H_#BSw)hfy0uNM=RG$34phO&29mD*v5~Xr*d$^`DFN*lSS?1IjV$A(qig z!d#k6&2r3Z&(=5bvghP?`xCN-uCT@QQk?y7+n30;yi=6LFGtQmE#A88Vl=c#Uq3CSS97LB9rt?|W`Mi49MCi(E(wPs{haZkSDyrkF~G96uW6u={@s_=xbc``LcTE z)QLQaza3n~dk*Bk#h0w*#5yfQJvBn>ZepyiSNZp*45y+^(jPf3s{jCv6_rq^3m$3 z|Hthi`UUYlYAutiKyhl#YR;-ky5`4qRjTR?zOz0<{1i>Oua~c0%RLhXRZX_O*Y0jX z&_CN#&2RYga9G_NH`ISjfgDU*j=K`R)dDQJT{{0CQEwWTWZu62Pc`LqS3230nF}>$ zHe*RHX^KL-qn1wNl)IE#*tk&Q&Q@7jnNlv93!qt9D5N z=k}Uiq;&2?T-GzX^z*3D1-2}ZPJb-#s5RmSPcn$~zD$P6#2pK+<`8;Ix;>b(A)KBavPKv+K-%=j8 z#q}a5r^y1t7026FaXF9kREhCRuCqS@2)C_L+rqlP;?+|zez7TqGw-VQqWEOEu|xYV zW?E?5Ul??11aSRhb;sK7&IgP6L#iK{mc>#>KSiWdX^w3kILY$bh=H(WH;BIDOE|L{ zP-FJGg9541d6KM5yBOE(#=d5vA1Y% zYuWZu^S9Mrb8*~+yNe&}bvVwOG&U$o6Q;2b&`wlK)3j`Vk;Je!(GNOhDw<`VM^%=} zM?UC~JBch`x05Ca>6Ow)U0xSnYwg9EB~;)h3gI&$>H}>G(}b0v)Ei{kI*76(+8S;- zf|@t-h#p@34@hm)jknlkr!hYOv~6t@tRuy?UTX~O;0ETfVukD(RRg0)@9vYi8&EvG zg8LB)XH$;rtfRIxjZ30@1PCeS$kPU`Macknx#G=lVFqYni9cc9@p^SZx_>X(9+ z$@JZM*O+b+;bprU%z@Yj?n#O+o)WDQcSn^^&!YO;N$Q4$5H8CA)&6TIda)LgO_ELc z=uI{Q$5#|Snsi&+3TYA(irj@o4Hx0@B#eq>5LU5fE`JddlcwGr@sCs(`u`Q~6mTW| zf=jOJ*MnN7SW~El&e!)IuinGc2NND!x{RPc#GJ}_Hc$LM#^Z)*iMl#^Zw|+Ku|+olZ+n#kT`#X9NTole6>9Qc`krxEdeig6EST%vG7W~x~&ObNN zGn_gdVirsk+0?yo!^!99Ln`)^UCm0*(wNIV*7R6>CgRi&oVG0x?*Uz27};&}Z#HgU zN}O?r-d^=sA1q?7Vs$=W*VB5Fa=ykqR%Ky@RJ$jGFh7>W(ff9<7+?qO#`|(v%1>Nv z*{M(18Ub5JzE>!fHeO+53jD^np?9D+QLGxj>X3W44~*tAO<9K}mK8iF3scnH@~3rE z{Ts*H_%zx-lj->7vEIr5tR=w6PUFU96NJ=B<4DpAw+j{`>>jdc!&?4^S8-q-I)jvt zeK6QeyGOep%{BZLYl+EjptbRvJv)*j4HJ5@Xdz)N9}do%K1;Vc}TRknMt7w>)b zo7K#&Uo+mP!A88nx7Qzy3x86=A;O+~`_VHr=xN|!)@b}G z1V>wK#(T>+_L_mw70gcWK~78C4JX(-~=H3@Ico_SNO$#mLrvLAw0oM1myl zV?U87RRryV2Hu2w*SFd+ei|KM*ki=Zp4ETO6TodZl%{5xn{|tv64Jw6j9vR(waqr* z-R>R?*Ig8`q+*xz#b=Xr2b`{D^bCAw`3t|ibo+|ZFugJ@5eJbWJ0Oz<)Rb3X zR3~h)*Q`OCXPMR$!s@)jw|HBGn?-;Na2AN0Tj!k|1DYGZ-0*WC>dnnw-}LMnIPvvj ztrMchbmK!hi^IyhmiRKO0--p?7d`*tb3sNv`#*KQxNe zuW9)(tLd5pevqC8HFOazfTXTquy=Iu$Lr_Ri^3=vQ**XzM(|2+Iq&wC5hC7m!4)Z; zg{W&~vpN~f3z0+i1tc=m{gUztZ7Ym6YoR>3tSFA{y6ljYzXMOCJ)`Mz&WV1NRO?0H zPj%S;k#~fZZ$G~d4$gO$Lq`-XFj}ri4N||hXNGiK#+5|YLZ&Jnl%c9<{Sim|)=#Rx z+6Mw+82;4db5nlx3Z?AXL?fB5IHQ;N>akYkRinW&eR7Gxw)K>4;?5)vrHYYjeHrYUiO(23CPmO0me6@%Io+`1!H1{js0F zWEqP`a8K-ndBHQ`;IBDEcQ>P~?6? zoTu}ki%MFbDvoYTAt9=j$CZ66=BYlcQsn_0#FtZh-r2EKcw8?LlO#)b=@6G1;ysub zq$^I&p*y}orTaiudkMEq;ufG^+d)-% zptG$I!A65548s|Nc=d}%Lu;@jM9*YDJH?>#?{KU>GauUn563L#{LucZS7|*lG4LMj z7PGj7y7rWPL8tdnM%w%naBL4WQ;>LZJAUyPdIh6);7L(!RA5OGSg57{Q zsV>ZtQdunWMR?+K^`{9#$i}F$yR}s>7|GZoewcUDapn*$@$f){Z4JArdFGvz(YE*@ zd~cp%@C$Ol9-M=0OpE+%8%Ylz@H?UF>pwNCa4dDI)p6Ark@#om<||Ct8)1Ajz?!Ci>lSMF7m|sNrCHryU=Vu^$%(GiRWJsdz$F_Rj{ER6bY7aZAd!R z)y`*Ov-$oWOp z(erI)KHQLLE!klfp3G%Aue6H^)5uGX%+*uK!t^w;H^qS=;oF5pmEzX8_G`1&bH3S0 z@YJ0KBtS!{a5rqo>7|-mjDC=?UV^zU`bmeO!xYnz|5+7oOk8>?W#bcA|1k5k7@g1*IJGU?7--tI0W zO6Wov8G83pC*)7N$?74>x5+v};o2GcAILc)F(BAc=k7QmLmUp~M;pp-7*(4XRp&7e zJ%jX#7VsWx%c4IkK%DNYMTe59dE%tQrLW)7nja{-0Q~^x)KQ z!>-zHhfOb==BA(6IwNY(DSwxl~Vt*>O^&a*F**xNuj$~*+}2)BfO1`~|b zOLQU>4}h4&?7j6{%*xSTyk-C}oHuc85?(k9TDBAaab^ZO^5&{wG3eIZFH37O*s~wh zKQs=HPrF;FvO<$&n};gJse7D2RXfX8;^=JLe)5-tSg0PQY%=%CP(3LwOmClaWK6{s zBpRpXUAHkx9xvzD?dX_W%U_=Q*?_2|7kS)B<(& zS}3xy`eXoQe|AL&NQXBetKkpeH-++*gIR@+!BJ_QXTD^O9qxjN@PmHr)Wr+R+ zw_-6?J7md4WStXV20{s*{MBGCR>(9-vMm18pKXO{1Rj{tgvs`Y5X{O!?$4 zf&Q3i5B=OS{)Q77(X%?@$J@~U?7)jgX1(1JzxBR-!o@Cd@cE_BS(PP%iU;8~Rcxn^ z9n^~BSH`>@i7mqmq6-Q^+;~PXCQ7WwQS>2R0banNmLGzYy*mL;?g<>|c>}5&Jy_`&v9`1UPz~BV`6?WrkqXxieKumR_rfQ)F^V|~FBo=Jhik(<> zVeWD@sItKW zL=krlTiIfH8mme($)Qrcvs-1@{lRl`y>yK?AeFeOei@j4;**pCXEayF55Moxk_k^? z{?H08dXEhJZ04)sV4rVC0zj_x)AYQ$N`W$jS#m~xTs343%dc`ub7xz_Wp7JXi<1)i z-Td&WEO`PvmoLj43Ei>W95Vs_6-qCon#Uslt{zMzOPU205~tW!qyIL4sK@`Ook~_e zKbd*ZwdSC%Zr%P4e>!^49%r6c-uf2)JY5bviV^s_Ttv+WJQN z%yVl%Pim^(Q?20KumujJ+QR2Zr%|5#GVfqlMl>yc?i)vlcTcLcLp7hw2Zp;Pn02GKe z0b;;KVO07ItJ&R5LA^{eYD$|oWq+INVoWsm&3-65J~4pM7%wh9t{*q%_C!W~Yx{{1 z^q(ud3ZL;W*JghS+Q>g%ENz>6rT!j*+5ra`A$&}(jt$#D-d*pA%)rEwPN>^t%ER1G zOpa0H(gRK4(B2yDiJRcb26kGjgs}sFt$7&cRO-_(v$MYJHfom{37gBvok@m@Nn2kh zJI$2?xR~W*sS+l4tV9}nMMjvy8Lv0tYXYy zM!8+qc7hjH`jhjN^d)jt5%$y4K+qim|MrXy?t?c{eXSlG#RxujCDZ#uMXG^MAxh{md+N`BwON`_B5 z;Ukdk&2ZTxJXnyiMMN>B>OfyY7P#o{4$3j4&FXXb9SeX(y>42Nwo@ z*RxdEbE3|ji7owbnNHn5>71MpcY>uxwAFHoU>4X{j|U|Lt&TvheSiI0FKfhm6^*5Q zLW~iVqi6WHol2ZiYJ2n(uMCcyu?wER!$=f0d}vQ125?z0`dw`0+_3W~B=7^MTJ_5m zBCMKWmWMs2w_YsgYHqj?gMS-m{O_Ok_i4sajRzm4|I)cHagI>q8p=tx+#2Rm>0qqX zwU2rV%3$kGOSkQM?A96j_@>Kb&RMrmvjmH+`S;!$dX=!$rq9hIqq*2iPlD zjdoYL2c%2DemXf_&a}y)l(FMOi*L$~!^u~r9Uo{5L|#!ymR;#_`{)|?+M=WAWh$fQ zrN0bdqY=2?Mmo4>*s9rzO@g;LW16GGJhj8dOQU0BL-NW|O>dbRIA6hs(ar@2Vl&|m> zf3JdK&lAy$39i^hJ4+DcMri7cd`~RYf1Y8roY!xC&7IyLk7Iq#s0BTqOoX4 zGnNs&qp@#9Ic7aLVYJ+hv68487U@W>HQVz|u>KEAi%q3>Zt%WwlJ-o>dMX(_Z+L7O zn&!|PbOGSkQ;bU!dvUN;cPv7s?oNBpB%AkA2VvS(^9?3|9qcntpW0YQ+5W{Am*UP`yZRTxMFK zTkZ03kbZW^duxGhAS?aAT|*xwf|v0*?s3k2T&ab(>740!#z_N@LsC=xSN5fuJgHl| z+-#<4Z;zI=@)~<2CRgVFLvk!e3|>TEVDk6x^5BckBsSMNC*w3Yr;Hc4YIXCMfV-H@ z%#XD@P+l9c=d!IA^&79=54?5QPcHjgV1rt@m(o&SVPRpn?hA2{mXHJPgKMCuASrh!iB1?uc*>Lj+idby8*DSeF-=W3DTANVP3Vlg-!W=S_7c zaBd-C>n+7Hq-F8?JGI}h;68*uHZfb8rRrCn$BZvSv zRd-Y@e8C4&%d91#96!n=T{%}myB=(p5GPXpknXv3m7F&w>-U(*{dNAHmeEY@WIHMT znWy1e>4_5yq3fmCs;3dO*^f^|JhXJ~%+^_|@Wt^Cb_U1*`@I`&ZG#O_{FImA)VTV} z&grchGFh40p3Gez&hhA9h0QCEzHA+@)|NvDX!ys>CiT1OOB1=3=(3eAj%!^-bquT6 zwSwKnNHPPgq=G4f+1RP0YQ6OtKX9OuwE9Y-T@xOVU~PnxY3(EO0M`O55h+3I&R1zh z^OuacLJbC{Y?HUgRIqX-1Zu0HS<>Tcdv@aNKjtFA-`a-8@n&xunJHy+yJUVzt%RTr zPcAnHWhvShU?ls~mFI5AUKeAmmJ8_Bqshb4^{>uBc!jy6LHMsPO6?llaA(x0Gqyj8 z*rr1$-f=8zL2ewvis_!5Oh_!}emtb)g=~X_3=B_d4FH+2eEDaoUQ3~U|1~19Y~?-i zgrt|<9K?2F4)FHMP~niVGj4&%)l81o3W8$Ik-i&y+&(_?pEJ)hGVSU_1H%ZAGN3zF^^$h*o!(k4~5p~K4( z<*S7GLY?kH9df*t-emYTX-Q?MqK(-ur1x8s1LfTl39E5!NC9f3c7ay0?Y}Q2=IH-b z>&)*OC5C7AEfe*QHOdlT5SrWY~w#vkjW%F>x*YRuKVe@k>P zgCI+s9@78W>lV0RL=FP6*VlrTRkSGe2$0?f@cKcQQ(8o{~rMsx#G z)Sa9?8Th+}F~C0mRG_!YjrN>}Vy#BS;d@AW^@6p8jZnHg^jNZf)yT!kuF2KdVFA{^M@ScXk&p+w|qB4?(9OL!WEyaKy!>?IIv)L8( zqFrFjCfkZR5JtT0quz(*n%x+=2&=13N(+Beq&XY0mL>G--z-c*n?FZQi+7Qbb@xjLj5r>0!vg zbPqfN`y8;uy(V?xQG(3zUg25Rq9T|ev^t@!n&RZX!kg2!!u&MT?9Hqk;C_&f?DH;S zJcehNYtbisuXh=VnT3>)%W%q6+Bo6>;R(6HPTj$!+a*VKp7PW~&h%8b>#=__pGjU~ z|E#04583wZGe1F1JOL8$hvX`wFRz*3)DrIMXxx0C|N5xj9b>-Eg7g4-%^D_f z6IjL*6&o}jFX*5Zkzi2_80u{rLGhJ0VQJMKCzn4*y|IZ4Ek{SV=ZBrBT8le_{ti6E z9Pgph<6!h*oEZi9+=JvG*gIl2qtOgl^%E^x?PRHZ*m&B6hy)T=bM8hk-k;bQYX%u< zO4SgsI*L7Mxbs(ucEt9g9ZjVzzr@LCk_Vlwtvd6b`L)i6$4dUHhT$&T)K!zf3Rij| zdK1~{CjS9HZ*6Lgr*WkiEl0>Pve#i0cK~X>^L$;=z_l4zkU6&S`CZ#L%}C70PY`Yx zt}sq;1Jh!^?)Aw50Ue(2(jkhS{+Y`NI{uwd*?lMKnPI%A z5RCwhN9;P6{lr{+x1q>IWgdrjCpZ2UeF_B0JmbKRj%qh!F;D3gLp(~qqz3xuxvcE_lok4{o3BXY;{kj}0{X}pJ6+#$(9!;Y-cAiDblIm2Fh+}D4u&T5CQHSuGm2-*7I3tPj1ud2_f^}_TcjQpLY%I+ zP;|HHF6^BpstxO8HX5GGi4G(zLg~&9FbL8Py%y6r59ew-S+p(~B_*ThzBa83Q=CaE_``_GW~e$ztLFgo{D%wIQfD6K_~j1yXj;;C$ntqRkEkdVDGAU3RH zjKD|^WV{Vjvx@EWGGYE3Wkp}yQ9Xn;O?*3=y#@nBXiZ*y8kN2K;?^>ch^xDZ zHMZ5*Ze;d~SHfrM2ET-WlofSz$p*&*ImOKg3LYN6x??#R=P05)v?%MMfIT5hH*~&e z3HQrG@CodZduGt>%rE@_vg8UYNxJfgQ!@<5`{Kw>8bUy~dqDs6Q?)0qFJWj0(5LUO zGgUN=!s4X;s^<-dsx!@d&DOq+sZ)x`ff|LeZm_fv9E03s93h_@HRr+kO>2MMTJxeN zk=NqeJ8ksHBhJpT9^oFw-$yU#e{E;K)v2(D>`j3)X2peT-#AeAJg=amU;QO#iS`a_ z#Q-B){vAsxV*jU1PCDowbj8XxyGHt`Ila}yasb#ja0S?6zBBLp;jT27T+=C2*Z=`H zVtQvmwvu7L3J%Y(q~?|e@$NS^9luvddV} z0})#smA=>EDfdYfgYb`D6DMR9AhJ8Y>0N&3E%ZYB_rY2m(+Fpj?sCwn29sQ?<=fYP zG$_0e@c(ftZO_vNA@AALnV9V4n7hlbrXP$7+30R*O&#i@kc2^Lwvt4 zZx==qS9_MS$prdo3aLCi!q-kb%E&ibUx3z;EgsI_r@9rb$Qr-fsL2s_v(l@wz}e|# zz^5ZgiT{k0wWwPHb4NIQfjohk(xBXa*equ}NcG9|to$Y70$Nxg?Q*Qbo8Ymdb3o8O zx5%2PEZ4;M#q|gx1)E%beaHn59Ih5)(cDQX_K>hM@n&NF2s<33`aZ0NvjtU3t@X2i z;W%Zw7)byfQGxFOq)82BrU~pywyQ(IdJ%N&9AX&L@B{v8X9lvlLYO&ZDA0sF zmdh4R_8~P=Ct-FlO)^|W2|owt?U<}H3SMqaZ*iVo9V&(s5HT3`7k6 z@w>eBGt`8SzAG2$0TjcLGuC^cRx7B?Thr z55aT{bAv<7kYzSf8($1oj{H_!Zy_Ca@aY;FEj!)|1nky})<|pL0P`lnCm2}V07O@M ztIf^SV0cq_*A_G>K2cJlg$8|*>K_wmCmK(&*8YP*$rX``QytY1t3lAR&Qrm z#0{tQrZ`&>=FyR=mG^WCf`V(YUc5!AJ`g6+nblB1PlXkfKP7$8$b*^+JTZGg9&*7k zQT~Y-J00Y&5SpFiE;|nOe!M2i;LxGLHnQ?lwJ2ty`~;JIIsM%@pUvW#cV(h-rU?%L- z=D2^?LG}M5;OuhMJ$O;qz4P+p>Bd>(t$~m8>h52p-uM6G&@Y5-Ulf1&{$cw#YA)xP z8za}*?{t0FDZnVUOy+NR-W}CBpm*?ze9qHHc;fL4>LoK{xv;10EWkHvfO;^KCulpk zBnrC}CE74*1c`3ZCwGIWcL-q03AOGyr_Yc?7}Gyw{S-1jmWa-s&^z+K%nv~iYc1#t$oox4?jBpoSX{RQ0}N-SsVMuOD48CWmj34SX>9a zg5Ik4_;2Tt1l=aDB2PB-CiH1SrBKtkXF{`6@}-@#U{7N9n>i=;ZA>)#84jBrKubSj zb3K94OQ!}6ZgC)0!$7blp0Z>LtulfYBWgs6_-ax%GLD7WGKoMIE_Q>XkC9fVf*ZY) zgr_Nk%mfmkcV6*AvIEaVG3Hkfq@YALfSk6?kh9Q5S0+R9CeESn%zLtMXM(H75Zm9` zwVVyP+QxejSI^ld*TzF;-5A2v=ZHC1u|wz#_2pX-Xu{|TO!D2FqYejmGual9E4|4G zSN*k{p36E8q~>g*_p_$1dBi;mIXoYXS{-Fy0LH!WDM>iL@;Ze=K=jr#W?t@s;CmlR z6qU!&-0+F4V7g)s^$}*QWcPV!b2$*iQKE=+{C-j7_C~AT>uvl#__%MdB70RqUVqWN z8@M0LjhHxT^u+n2iK?&kjc~UY+_!l!i>gQRPSkWzUCC|Rmtl*QNdjpA) zC|&z}_?s45r*I(rnC!!g*Wi&PCKSyT;=2b8) z-)Py=qbpB&6^!0Suehy0$W0H8W|>W;Vv8G2{&`vtXZM+ZseKoJle%y6I&b~h(npwB z)=LWQ-YqL%$|v&7U7Q!`HK% zi#;%MyWZ^IB8Kb{pryks5Heq94IKl!gD5gQ9e9inp1nxZnuA2Wi~7)cR~6P79T~kP zU6U31bv7k5ir865(`#cNDzVSgqv{IM>DruL=2X6qLt2`+NIG z8j>~d*wSU{g0MWh^`LVePY>EmobGWpV?pWPgo6i?al_xxHwe$A+}??|oO5_!X3|=WL(zjD6AMnOWVo7BI z>=0ly>m#1GdBFNf84d@+Yzmka$Ck;~GpyL!Sq6fG>SeFxNUFYZ_- zuDtO`u!G8osyym`38Zf`*9woW|k`da6DrvU+Fi4;#l zWPHeX`aTOYJqXK0e&WZQf-jB{hgx5v>LJN@lF98p!MDc{u!}namE1ubeT3mN1 z7PS9^Y;S@8@4Bm38Zw`C;v=Er*ILs8^TLb^hAzbW9#)6?_I5+gSlBlm>d#oGK`Xuq zqV_T~Grm19oZaX3vj#|#?t&f_J8({DT=Pb$rqIVY!wBVq*s|E+Sus|6 z=I6!hZO>7;ew{Rhv&#P#`pT=_((AS z@_^yLHQ>lnfetrjGvs^9$YR^R-~N>7&Wzk#h>Q3Um$mqFHEZ?Nw5#8{CE=}aEYH9d zA9ec5y|wazG_F^LDN@S$YYb2S1jcYiIzI2Zc#~h6aNV)@Lp>R&)=w5h2o^U=)=b_t zU1&TTXptWGVGQ^0&WD&(Yu9x%jXXXQ35hd4VNNrgQT%4%)%yY#3X;>uLonm-%5`*d z7X1@CVp@&W|r*ehVpnl5Yndg+AtqJKtG zIZ>N!2H2saKaq3?AIclyxFuJ@R5F`Hhvwj&vu_L6`k>>@h=AL*Z30QD8s^QK??s#{ z-n2M!1;Q=CbmwU{U`oc;<$;SlGdOTn8Q3hA-;5tI-BLvw4lm2OHiEPf<2D zT^t>x6ELt1ZxoHwdTOLb--rEzV#K`>pdq`W6_@v`$G6cO?~{DJRDT7m)+gVWEdY#F zFC|`}T(d_zql42oqyp0(!WB(&sRNyc#dBPVmYmTRF%i=JlEWQ0kxBkUTrq| z(TsP1Y3;?U!4+h92-eaGEwy@MN&Kd(IBC26C92bl<{5ZrVqf>lWQUH!CKOKtc6bN``>q;@Jvu@{1oJIJG)mJ|_{p%}QOld5<+WV@%c?GgP;7}44Uqf9c*s@-UdDU{8ChzhpyROgVCJ)?EP*trf)Nz(%q_E zzH#QL4vfsS~D@S@8~8ZW0|i?mEieHi{mUH_2{@)mqFE4+{K;FZK380jid9{p@) zY(8XqFkCN9r)FVBx_bbmqoIxP9lgfqzwcX=?@Qbg$D`ci%1;a{b8r&y$@(j0wJ|t2 zpvax3rT!)0P$rOilz7&8v42CrVIp+-zh5b+G5K(!K-58j-OG^y&=}O8 z`|GWJM;e-GLy#6@;Qg|rM%+J_3RSet`I2nhQ$PWHQN3S%Zr83kqmk156YJ}hMUK1R zl{F;EM*LToSlL}on;n$}k_}Z*<5e4z1(WvuJF_*yc=DlGGsei5LlL*TC&TIPYr93R z%7Tj+Odo+0f_Zsik7|}H3IDY-pA)9)vY@|DR2@&-9*vj_i?%^b84yH8DwTg29efOM zZg~n1>Ot)-_KsCty*s`YCS-9*3S?V@?5<=upkv|Lh2LmKxx32w#Jky) z`R%A}j7!@e>xG5$Kd08k>@o>6N~=U3`3V<#4L;;iXBno_oRbG%oL4y_LT18fL5+KN z5j_cUQObp9hPO|wI6{uKv=U~!hoy@?2#c}OyqB-WHpq%`l_qh7i`NqgGS$A`Y2*qy zn5!^9Sto6~Xjvi9fO0hWT&cayA*RkD^~*&0Hz`5uA``6oY|p$b>4T|{;Y)iJP{x4d zb*nU4zrcuY@8KwNHWJSOmw8VEi!Bf0)_Amxk%yYEF0 z>LWARWBqN+$PhOH_m5S8nDT$}D3{MKj=Xs3a@MpYy)wNz-J-??#o7G0?rhIXUAF7i znQvx3g!_@YAQwu*f^{4);h~^;?`x0FsO%xKO5XX*;Xw ztG>!*xla?m@*ExLJA9!7^t$znq53;K`_nDj^T?K$`cUTTY02DN-zaJuyN+_|wDh<) z{i;*k*xeNO1;lRU^LT^-s~Wv&lGOU^`p=$BNs z^C_d(8O-7MIA%w1K;qld_qFveX4`P}=@GIQcrU2Y>R|Cw6vyhyNY|I4%{6Xw6O?~v z#;SeZ2~*~JH3AUiP;w4d`L^1bY+Y>aIiG)5zK&E#4AGf%L! zJzW}f8K57SpWC(mCdvA1vIT+?-cT(fZFk^=#a841UZi60UF>P#Y}RCDG@`J5Worg= zS_X8jNiW*|hm&CmU+hTI(uB%vtoU)>@wYmcn2$@enWqu=WVsnMo>d$m1Q+WtPzGz+ zyXZ}?@cb{dNitvV48K1l00s}!5oCw%LC0~iUZeLK6@1u>^-L)tyw+JEao((C{h zsjXq%_u?DN2Vo!0uVAB8je(y44$GV;D|*9Q%-{Cw^-JD#?UO9{sg4=rFengKY!o`Z zibCskBb;@Jt5n`LG4O4R?E5;P9NH{zOv$_B{*coCDk1Qs;bZ*Q&|UDQ_6dBJXz6s5 zH(oa0kise;C9X)0+YA|Jz^T;(4u&z&4tu($e3rvs^;m=HpwA$>keDL=9kY$W@+w@7 zgyhx|#;*-ktMFz-B40$bg;-izuA*_E`P7_shwFJ^;$dd%1t$V-eLZqMv({u%N$P|w zl;AwvRbNHqokor(GrvNYWI04fgpH&;!$CC<2>6@$+Ym0ekG95*TI<>Oo$`i~hLt{| z^pr(HJ_u8dMcG3$!A{7vDcYU2&n$hEpiH<4%_Uq4cF+k#dLw(A1Tp7%AI8+zRso`c zTJlA7r$?Zu&zbC`d{;lzcOAb0IN^n-XpIWi4=_ttI>zB(+dwg8KtfEr4uTk}ZbnFP zIQ-EC^VmRDQ^r4TcP&WTzf~CN{rK~98`u2@^S`=8su3DqWAwoJszPpfj;i|wH z)vP!_uw~I#f1PjLyX_#}bR9X8k`@?ySfaO|e0alZ!NlCjgmb}vn>U?3^5IUi#a;~+ z-BmoXj5(#=4y1%=P^SsSFixa^=0~Pz!a%e7eigm1lP$4keF2N(iM~v8YX9EYX}cjU z>c_4)0a$)Yj}myY@!1D)%q6si@qg`f+3oV{{gp&e6Mh42GpxCvfOSgF-|c$r1|C4W zH{|w5>)4L9>pX2x> zk`SVb2LU{GQVc`&DuMc-KJeChi?67@R%SfG_^_l+Tqe(nfKb1#P3&K_zg~XgW|R2n zLEx<=A=3(e%TD5+VnJ&gezJOoh*lBq29aP%f$fJ^Qb}y*)}Z=ke=PV2dvK&EfOtY+ zZ&_dGfK7L?B|jBVSdmvzaT^_FSwGd}QK_(vm8U z!TQFT$|WZgCqU@vE*)4if$O{|DnA*1IE5G*vKzS&+WwQr073opYp{sn)x2m2^lf}q zY~3_+)=R^~;l7_}+Q6T%s9OJyDy)(Cam%rqu{(%z)P$T#ysP1zG9=aq2l5#O$BDX$ zl0TWdSN52RRIp_!z~287$~38&8_IF4Cbe**X-MIAX4*Pw?y4BBiare)dd>M{$Z?Jo z6Pj?Ue8UU&Q5^hU-%!M}8zFmdEIq>m`1s?qIG?1OSVhq@<#+*n<+*!bMj6dk zp3jNo-(B-VzP75tE+MhVB63&Ydn$U@1X!ETGFV!}cq@}pNPyp$UrFA=tfsVrNJ3E! z_JkQ@Z{lm1gHfX|B$gE+@ONZ`XUi({%BMAwMu*8YfNCcId1Pgm_yP~pl<{9{9pvG^ zrJDB4@VDNBy6FQJtL9rXK4+c%6*qe^{m{AU;vqxv zgv${82dq=uwnxPsEu1}Gu(H!1+Fts3Ez}Ehmlf3a;c{c>hu{6N1zJufL8%?HW;|M^iLmh%&-#GPIt^^bgiRl*N0Y6&Wk}WFexxe28Nr?**Mw; zbj(isuf47-m_OJt5=u&@C1_03q+Nr$>PMu zr~I8;heYRrZ(`TVY8`pC<)xYFXv5FdnqPS9156wCH)g|a%=g7-7Vp4$lL>FrCjI64#XCg7_i{=g zx;g6epGC*kx^;AV=O+;+H+);y>}-@_>M`b}alZ0LGCIpJc#xkpx-j1Dk4EaXQdYN2#zQx^%P zTK`9n1NomR-KbLczRAe1^O^Tu4jt4p@5^}fi)r{mdc)8;`rfVloFnF(wkJ`tg^MW6eC#RfF#fekM%_^Y|SqL$<Ay%Ak-RoL>eOaa^ z(XMyhwPnXfbZVVvGirtq zhY=mi*Zo%;B14W<5Mup>gneo3v79py^T5T1(ctA7`h10(mli?zc*WcPUmXaTTIT_X zi(y}cjiL8N82Hfgsr%Q{fuRuA{`o`m`s<0*zo}(`>l`=I@A4|D8LU5Qa(qN|EW*7) zdSy{Blc_{W`=htfkt|1PVS10N{G20cds786uTmmbfY##1Dt->adnd?d+=7#KuJ28! z@9^NP=`uK0=vtOWD7PfRu8vc4b}`8X8dEiV>}9gpPp?142}n|jiC)h%!F8B)0H9JH zqk!!airC^nK_ohv#If?!^_PE!V^*pTiQ%3L@_v04h<$FbQKlXZK%hGnLI+jS!zM1R zAkshWT=eq|e@u6IE%4tNN3{@mkQ$6xHEMIWF;Oee!BT!@^mnujZB45i%%3_|V5n1x zt=VfZTa;%3Lv=B(-9Q0V$>;Ugya;{ItEJtWp9t%~-1oVGvUe-bt~;GDv#;%AnqTAk zKL3d<@*~O>TYOV=`lO&3YBrFpSU7`2p@Y5-$6#5i25TM6nn(DP^lX&p*k=@TqC=35 zkO1$1pzHbw2hUNMKUu8_y<6-mw&waTeC`l#l|w}DO<4)6);9gA`Bf(An^eR$5@-{4 z?rm5xZ!fz!H^OPi*1nK;Z>ECe-{2ga)FAz0KUF3h$c7ty+OQ@R7t4{>f@0dFo=1pa zR(JHMi9Ur6^!FdN5)CUczv!Z>9{5uzF6Seyqw8Y_ue**hHsl-E7sso?@g#R7Qj#k4 zCX_hnYu75m?&hJe25Ucdy=8F93EdNSLa`BdTUI}0K}X>mx8{vm3ETOJll*`a`T21d&*-gSi0uKJM&aN@Mv6s zJKVZn^zCX&>31C*IZ%@424!HSSaO(7+2xa*nd^46&K0Wsl#~ z=c$rBRtyl&Gtqo*#PHG+Eupe5oR3)3PxYWIdj{%P;3FFzZ~9E_$4Skj$`p}BA8WWv zXRgyQTIt=mdjtQ(>Xo$#W|NY&DkccW7`csW;E|{F`cn2+ru8>7pF0?tDHFkC$)7>GO5S9>fE%eM_sxYoWnF{uIW4zlCBgE9wT*o*u}Jtr z!0!1RQ+MA@W~$iW1bVs?@U(R1r%=>!IlSSsY7hg%^wF>(XZaljq=4v_2yd#U3 z4UEqw&(6fs-igKmL_H$<2($wZHqC74k|FFIljkEgzruRwHa0VpZAAIv5B~BRa{3`F z#Y%zV+n?|%(0(t&Q1BIK-(os|D-#cs#@&4#c zrvL32{55$u?UK>{zq850u&sAzW?)6p*8;&xYTBqvgCn_;m{7qyP3zms8s|viXGo)A z9f?~NW2I1Qb?IQLj&SfNFFD8W6;cMU30Ngj#92gd$jgnP&N&2upl zD=Ujn3PCS7s1v^_P`CinFDM(P;?nT}xEA zuMz;nEwA|-VQ<4b+DIUMdA=nmllhG;u4W@p`~WbIs2XVljLeWT8u z<{i-a^J#_Y8o#jGer+pDjsFi7ji+Vb{j8ulYMofIruVUI!eJD^0*#JT`KOLW3-D1$38imxmZKNYmdX9sYti5 zPiuuIlt(#5I1^)!tJNfc~2|#a1N)#>7rjMv}yUiIiZN94AC$+WQLh%l?y-!o zD|)SK7s)e0D9>HYUJL_}kvmQsmE?essq9}uOABvcg0@JZj@*{HtD$kHdExTF6Zi}; z1O19a5*|dOmV$)6pX5$R@crv<+Hoe8u+Y1TV4OQe`jabj5kIZd+l(Vl=)uNU5VNe9 z^N{)Su8znMX=GZuB^y79kBD7f^1Bf&!d$u`&!NCo1l)A|!q-M>4i*@f)D*syi!WFt z;(P}t;}}{|Sm7dL64lTE$h&7yq~dw2hYDZnt<L#z0uoq|2Zf-&Q<$aogveEk@AZ; zn2W=Zu)YhDoV70D(95cuq3L9rn_5ngOVjdCDxl#O=)H|wE=iKT#KV_X*=fG7xgjMv z*TY1q*~byoc^@t1=^(1J0`2C?6RYkOLx1uESTAk<=Z?d_@+$ zGq#R3bJMY><7x>SITz5AG2v!?qNLvKs+L-ydZYJtE%Zu;_@A3kU9MM7Y$8sA)kmox zx>X7->I(M`oQ8d+@{}^^53qD077}r#sK;3-eG@jXuM9b6HoCd6`#C91HDMhM)VG^t z7doviZqm@x2e#Tb5^K9m+v2kjs6V%tz6o0-^mrk5iQArs{%qJi)7LUndUf-V2jSC1 z0can2zI8wL0Kgw#UM=rHzl#A=?ax3LX zal6&J*mRUt%W}iFhJN$Axl9vywp!hu)I5T)(}W5tKkM-m_{FWg7fbz`+0`(XTZ9Rj zqs#S&WD5*8Hj!lY5v!>N?2swTt5&@iT!o*-KeX$0Q;j=oabrm+hV3Rx&#Bd@OC<{o=B$qgBJC=z2Wi`7;TLl;RV%n<6O~V8vt#-4soAUgQ$8R(`b&KUp5g?C!frtv2$1TMzz3T_Z zwP&&GM8H=|OIpjqRoaR{wtK!_qprX)x~JCGG~F>(hU_ts-sJr{w$zll9@@6r5w@LW zDmSHEQM*?wu7=O@|A}m)|34pg`ayrs_GeeOjGnjjPVs3GJrp!PIe+|co5nLjfY2h= zd`sqryU*{Iu2GnGVe;SWgx&_q<4EWx9O*R*pwMn5ay2ls$|x98@Zjk&O7=$fM_rs* zi_f98GF!+Pzi(S$@bT=ylTmH~{DIP{R*073PP)fJzy-_MM8biT(6!W5Ht^MYp*A2z z&Tc=VjR+Y^=dO_-_%a{7(R`YDz>9fF`Zv#^d-H)d=S;HD_i?11y~bF#e(FW47SfM# zt2nCGbcQe(`>T)I6ZUp&j&PfR5M=i;GunDcLrRoDjonKs<9cD!-u(BDU zOf7;Rz?T06?_UBaGmybzVMt9+MjS94U-!9#`I+P> z;@(1%iea`ZT1;Qr=Jk6frFB2;yb)=K=f+D53u5w9clBxbFJwLdANg zV@#zHYQx{}c7FjSAMOX6)ScE>Tie5ZZb80k41YpOn0p-+Cw`-T(?cT56u*tnE=XK;+T!rOTqKYWsEN&B?A zq+Ut;Cx(dB|KG;GO5>5?%>_SGyJI6+Hv;i)tJsLoVLC?_UmkJ$)q87G%DI`t6eIe2 zW<`pc<;LbaLTF7T>BNEJg+bj(=f?PUPeYBh}N z>G_%*YPX-{M;@=RnF`t^cC?bn3>O%sdSZda);^R9^PlNHfXGV(IH6{CD1E`TvOj@ z>vzdRsInzLZsxf;>?>3^? zF^wq$ZQ#fVK5qrEptz>GFX8r%G;%G znc`q&QTDXX5`jyo^rkfvyTG@3cOaKX-R8ds^^+bk?8w47PgJSwhe>~10yI-lM>2hB zCb1t8%3INKK5-_@BTLEBEC6GqasE7_T5;?u_@t78yy4;Sv@CL8>oiodF;`goYaIL@xlf)K9rFedT_gw2cMf)nJ-ex z?s~h5|8b5BTqoIhJL4U=O>DFY?dl1KfGJlG!G{`~9A+b-MT)a#+Od%<#>wLXjeGSl zZ}O;Y_4C>6;1ruBLWGf<>&x}ykQiqO@L1r%Yil*K`E3YQ)Zm>`ujY>pMQz@nskGk? zK{d!CQ*m_SaQwHd8N)WXYM2i5=>YA(OD7b@;*Eh&Zd%zgpeFZWto=5~8%>L1P=zI} z@tZ&_kk{RM_7Qkm7slB0C^JyW z&*r2!L)i=y*uWSypM=pwe^CX6`nM-pdjWMZr|9W7+KUNu+Vu6D%jHj0IC%5=eK@2m z@-5(12>)KYmcVCISkDgVn-}+^Ct~h{SKrP2u8VJcW4IrhbSun0%n`D@tp#f#rJS~K zBuLsIUPblnTj9iX>B40Q?>rng42kV^Dc$JLBeU<0NJrJznt5$yy*4Ell+`ncq6i#l zBIT=rmjM4rC&4D1?f&Ov9=`K4Zi(ZCX@AwM;d>HgiTKQIRiz(muI;iVhqZTGo1=}M zRv_Guy_{!`8C-xE0aV6{D^NO+2}pt*^kkm*DTt{s_C>q|aS_?XauV)faLwb1_~b`) zruW9nB`Hj8-pQ7Z{dJ$tK&-IbQD@Hm!o_kY#69V{7EbdrfX7R{qxW;NCP&7JX4jOe z&7suKvhfXwHSc9voWzQY{F+H%AiTvRl0ATVm|}xFs~U)sjtC%8z33xUWxpRS2Yyjd zR@d(F*iINJt7!Zdn`lad`7by_Z`F>p-o^wMWK7m53L$FRfWAq``J|x^(Nf`L-WwMJ zz=wik$Nr&4p;4B@sjEHf9&hU|@kaE#iZ%6XE0jjSvE~=T?X>2quB(#4s>BM%j{&O z%f%9@gVcnwac{n+y^rHf_;348{@;B!QKhjE>xOtd8>iUpq0v+sv* z-N=}USzLW?ll`~(TZUWuuf$*R0X~3hYZ+0qorgVeRhykB&Nhn&G96KwjjFD(o8OUQ zTtV3h=AuPBH@pa9*LR8O{g~Qw=|DEEsr*?yaCG4~@ZGSh7FtQpjBgUZbpVzRH9!O1 z8y|8H)bzMU)^BaDL6r^!sp>oVVAdm4>nEHJ>DIP;Wk2X9Lbwj5?&@6s*A-VMIWt~9 z1oDMJPlbLZ5bGO`w||>nO)7MOu0Ok2r`y~!9G~qW&L&?M&78g9Wg2uxzx1d8y3HNWVojEyiKeL}frTYA{n)IDAh-4E z=B%eJG{!Qv>5b$ITW!>y+1`Qw45Ge5UYDbW&xP8L@v7tH;-40pt0(kxiokP`QsRxF&uus4qA^JQRfyGAvBpgEfrHlg-ewX6o`2%xQUPi z!tPhgvOL6Qd8mCaY4RDN{Kq*+)sdI&FHdrUW%twsd~&~wa(%Gz^}p=_?mnX0*y7mD zIHMpQbaAPR^8A_WU{mAEAKX$z$@kxE^T@t%%Ejuo1~0zK=hdq=T^xy`O@_KB!dQiT z!A!{U!vFZK~JDM z71<{OL6tJjw%$EGWxn3d!24UT0rM*7vk-AkZ|+W7(*_djIhR1!B8O2m0;qVVk4Z1G z-dE!jU9mSdsHAVZe+BKYxW^-PV+*;@<;@Qk==gB3mfW zYM8kjDj^XC0IM=~&770G*xv%7rA7YHw7$D2`A)2!MX!6VLy05MWLYV#m+{I-_NOjK10&73PQ)@5?d7|o}r+4punw14@r?11P zW{?0so>Vw9aMH-9_s@cNL%AtQ6*A|gm~>losD~m(Y1AQ@7}Ri5#!MITNXqJmXpCuP zb%x>?cNWnr*mv7U$QC!;SG>SG*%eJ@%y2M`n14Rku<3t0e=$E^(Kz_& zhy~|CdS&@;m#wB%lIT5HEerUL9Q96(EJ91~qdziI)D=_65sNO_;ZY-WS7CU--?VnW z=(;SHjvX5^MAy?eB1<4Np0m&DdSt$ZRX`#XM7+~+WF4~Hq#B{;njNr^EyL`l))YXl z&x;g1R4D}eJ~{urpwG9|<e8A`892WiC}MHE1(DYD)#QP>F53&RL{ zgmENzX^ASQwoq-KAi@i};^vIcuPP_zZFh zE(H4N0MHSH{0t0RCnsHdhOEbI>{_CELzxahcy^eFwoWTZhWaTt?qXA;TYqcKoL9bG zQ%^7X;a8bI88Ky@M&!bVIhs^te`){cbM(-C3(vJZZ};3$F{extgB=vN`*d6&{7z<(9hSR;oU zpq8X3OxlfJ#;IlX*C@2AvYyF*Oh@5A)V78>7DsOirNwcsKydx3xXvT2wpU=}jg*+S zeTpKT%PmKfJ;Dcza`rg4FSdOZtEkUrIl>Gv@)2>>of${{mAxJ0ZEIyMt@;YaCg%GQ zxS!BWuG@@Zy1=WS?pW>G)g^a?j~B(D>&IyaDtm2daJa`VtixnhlE5!WNI~r`E)2TY zPH<~5&ld_$r_JrL&>Xg; zD%>Zz#4|fBSxBGB@bC?5z(DziEszHd20}J9F(ecvnSO;A1_3-pdi-3}KB1$?b79l- z6z>D+6+k%316{UHZkyZ>&%Eq=>)!#N*ZMC#L-F&AQ{`GlM*Dn(ZZ-o(xQukeo2IU& zF)z2cAx-SSnzvDKFYTtoD04S~<;Ow^)Djw${wPr}-|&dM=~HR*D9&0NHnDWOM2=CCEWh+;BIPSVPVZ zGQa6_&XIw4oZ2S=-D5V@PjtrG z_3dsyIl9W3c8e5?=U}kq-R<>PDJDEX9LxD3>=o!?Y|w9zsl;%M7|Jp}uo) zW}VHq#)`l6B_)zJ`kUb8!*+A;YpP(`W+xVO&RnjpAa1FMT?%-Gsa3Qv`f=q&vW~pw z*v%nN6!L`V*V*A#^$j-Z1jPOB-MHsA%7jvo!sTZBpD_`D@U~%WG9Y#p0^y%A0uB4< zeQ+)Wtct1yky>6K6zH9NUnh6i=Q6qV)L2Xq?-iiGZarwJ02{~~#PK@3e<#@%w4|2N{-l{X* z@(R>M{0+CdVu%?cp3nDdoyAiNXUTrOF`FE_3 z`QJP6A!24v+M8e_UyVB14D@q&ztNox8&}@pKDf@(>e2X1*c}S#kNa4UI>a9Qi=V+e z$Pce)gy{Jikz7|KWyxap*vibo{0loWg)4m>A+uQ#t{tx2M6w&`T6mq&^G(%;b=cteFU?XDJPp{~Xxv_WO*y>HYc^$IIps4aWe|-^?gE{6xaZjOQOBAvg#6he z8x6M`>b5SpG>5k<@T3t0M};+BX(TD4Tm`dQVLb&aDR}0QRiP@MXU}pKrzhh%NQkmC zsN8m9zGlrF`a6jSxM#Jzb95&{;LE?cOB@ce>>E)P7gIfz)&yGXCl_1r*DHgLisTSN zzGMq78+UYK_gYqSQBbz%PhbNhlz5x;JgJiF^;&DHFzyqkMewDluj5B}Mlp%bgtsiI zo`?745a7=enGTz;*n0Xa45q{K$z_X?Q>xX%W=)-m#EpB)7PI;MMY+dkjC3Ge^hViV z5S3j3Fx3rW4uoFh(G{M4?NoI7ByZ4$c=n!4p2^-ZhPG)tX%=j>25?~m36NJ!w$UaZ4sO1 z!OGP`N@i>LVhbd#k@sm~WgT*L!}r4ThQUO+fFd(zblSYN8%ebrjT^@=K@_BVugM4vF=O(wnU!q>j z8g~}yF@)YkQ7=*I6$qW2#EdV^{-$6=qfMhm8jh&DGH1Dgn0Y)^16;#fDH|j_OKFZ# zq$y33ADee4rn7dP6zG9}>M^}*uc~k&{gao4?)gvAA6jugfn9kV&+Iq<5$v_%}@MZgi0cewPGz>OEj zvmX+EGD({A*mbNG+mT-)1)|r$KFoZPCWheSkqP0TS0d& z#)h@@jNVe5HzOjh^0L$XiVBc*=~w;7y2C1GN%3PbqHO$(o!k@M2AjVdF2kzYX^~UY z*@kDT+@ZA7F?M;@zdc2)wl&vTxEEfiPC15v;IhT12JETB1dk*9ob<^am&CLRRMUr! z*y79tlNgQ{Omb;(H?gH!I;1yY(O*1ZB-_%LBTaajN|{R>C~OfwaSx512~lf$ZEZ}} z_D3Ga28&9kXK~L{-PH=W6msd}{hH(-gGh`X`8MTFdwB(fV{^P32;_S30^L0yN5Qip z90-Z0A}QY%!x7ileY9eRaNySy~Nrs(xGD+#g-H&Wx~_%3n6QCeJH%QaRl=CiuXgE z1R!DQOt+uYm^YRd(7&fbW~#r0S#X@~+oQgK;qB>{JcY)4Dw|D4eq#=*VwOBMFh4i9 z@IFV~ZAc%3WFfoLrFWP$2%F`*%VgcC>+i2;Qgi1sJF*(A{LbqOV*ywmMQ(@*~oP=|u9G1hwp54c` zSgAVpFWS{pRoA$eAwWlg$IW-9E}lpLuo%wIwX0o!?wnqOC%-)j{Ooh?b3aY%=tmdC zIfZ^Ov0e;QB`4Hn6ihk+3?fMyD$IoFEKo)>txQ^u)mxXf_nm*~WA1%G4fzUib)7M9 zhz0%zX`ygW^*mmi=yrU2Cishz=%i2m5%xG1)|*Vzsl|D$W^^U8RIZ61 zq37p73JwbWe74|vH7KrEq#W1U#-Mbqaz@qTRSonpTEB1Y>US;pDnvNOdNLMz06S+p zQ#}4nUuzziZNW@X7m$L3QsdzSF-Lqaky4v$Cpufl)=Mz9{VNaaHSrqq(FO@X! z07vbIp!3Mxo{4Low5Zk2uQ0ulO=YSR(zy*z(3q07s;^Ug zy=w8b13t_fNWANY%dYg7Y_v$A!XOv`bQ?vzs;B5vx7^s9Axl&CwyYDsZQu`d*e?&y zD~_ai?k6K#)f3egB7kZmNr^s%UYoV;Q0Yje`qSqGIIR${o3~adS|L{AHyQnf`cF+c zbccvbIBQ*BjwPH%^d%3TwA{{=KS8%UB(eef*SvkjZ!ys{@eRcfaU?6T;{jfpfsk+w z2aH)>yh%}CR+dh6t?2PxPAF*ztwRtMWNP#1ewkqiw;aO@YFW>Xp`wE>JDf?ddQ25v zu6aqXPoIWIaV09GnH!W^;oOB?cM`3x#41iy4+v#0u4s7d_OD(2?hTvWjt=P*tXwaD z#YjZV?r|Bj#q0%lJ$hY1l+?MH7YZHLO^0vEepn9R)*=ktv;7rw9&xV)A5c}Y-}Qh* zTQA%}F#?4-JQ-zxCUeyJAAH8EvL?9ms`9IR_$hA`9`NsH{(oR5%%LlXe)o$${KBYF zBO|iQe84O$&gZY@8)VH%!>)1Q)_`xBDisP9I>fx{&{_8I7u8G^FF=hd7LjeD&YDnc3Q-?rtLws&KDl~-Z&)-Bznis%swr| z7Jy<9_FQSI2kU%V`o_?5N&k6lduWMvqUZ0jw;k{^C}2!qjemo`Dr#u&U#19%bI?uH zHQS(OycefHPjH3&t?^sn$Y_l$mZTM1#9nRmIe>2*1OD&2Qwah>gt6>rH8&wRddx@+ z8~JQD(ml%e)lm_gA4z{!g}X^LC+rl5|H$6gggk@246dObgFo9j79$9?LsZ8!$V5{K zE&he&>5(6nmG-c5>Bs$d0k3%hGM!h+(Qiy07mq2t#22D`!n07pOGHd5uLYMDbv;1N&E>pU%YtKcn~jfj*T=4ByF5_=<=A1tyhPfopm{o;6oqMLv}DOLlnuT zmM^4xhJRNqo2(;C?oyv4 za5yckb!dEcN{#F;jMX4@`qtx5%7ZMJLC>+dvb_6GrU4Dr$Viv3}e ziLWDXjzz7!Dyz|PByJp291-u_z44w+X&lNH6eH#35Z`%UJcL_Ip^eJet9HbG2Q603 z6=g(l5ucULNg!&tdy? z{0QAx(?nfie(F&T{@Kd0L42yq6MM6&j?UAJ`B#yH-}|?C4zkBo$4;XwD^Ncv=gqIx z-wAZXk=;cq;E!_Ymdv1YDK z{PV8Axi+Ky2RfCjW~2Dmp74yLVLt}`HlZB|hUXjlbPhl^BX<;%b2`Y-KNbcYqTizB zL$@gf)ezs&Q_PKG%!43vbNHUcRR;7ePAdd{0@$x3jE&;i2>t{=9R1X^e8eD%D?|P; zGjH_;AKXGP{WKmivR;-#8%B{LW1@WyOqOUB`JLc~M1B-GMt3noMye$Kc*d3G`T+l+ z?`m$duU#9X^Sk zH(MxWEr;lNP!B^HOaO-`W$8*EiqZQPPTN*FLDs{IfqrXec}j|kGE&AnmPTm%JEjkq zwpe^jVNUJ&+TTvFSan1NtfdsKUs%YO%3Ff&kEf5bR$90sl~smdbC6e22K!L?k(e@f0QQh@{zIKj{9B_0Y zHd8l(!1XH~<4G)__WG^#YW}yy3KCY8<|P^?I!Fl}owSc}#Hs4+!JxH*tAWQhuoIhN zH#?iY!sCDx3|0Lq9HTvzI6=b|t+#w`p{NFV6RjVkc6ot>q(XL@+K66yIL=MKFk~XR zW^Z8{9JX9s2Zx~xXdXzq)iyY|&xOj{<|UnwN<)0Bn~Q6T?SM_a zQLfa&mUs#C9qI(KD#P(FB#K%ik{LYvDv-zB+l)O<0xQ5c|R=-pm^YOG%fj7_%(manJzU{*M5>f_2=&CT-3ZjGPNZ_-_Zn{ zhY=PChQ)H<);Nb~|?AI%yw)DohG!1_^}qF1PmCN0EEl2Cz=^v5mw z;a-?HOKykUlMh}V5wB*fTdh3uoy*6Iq3goHb>V5!pOpfU$v0)2ZGF0WS*Shlgv~Ww z8!b=2Kwx%XN8WI9JNsJC#mRpjS^w`F@n}DP{%}dg$72W0cEp%eM}L9Jj9zHyBt30Y zLW2e$RK7Uw_U(Ky>vN1TJ9DGA9jZ7yBfxxieb%`>8BsPmS<2!S81Ya>tgC1(Rd;n8y?8$cAEYB)WEczgx2J4evd;x@}S1k2MYa6L0Ij7o2q~MXBA2 zJ!9g=eJ+{)-O$`<+Vd5ITpYIYl-yb~u1}zwclbBm(iVv_M*-`_3SirL5zSK1XytquJ&!%BY zQNT&~qgEcP#(?E3{uKH`W_n7CU+1^fdA*I%eSO2rKu|q<*X)a8+lJ^*MWsa|bds}G z8nNJn3wPungK#E4mOAPtV=z$*=;2q;yS4=7+z}LA!Wb(t(*|E^jw03@w2pjJ2T8%2~z3E%O;7@CN zAlX!y`PSD@#_iH>wbeA8s9@jqFeev(mpeNv@ShXiPnpy9Q1cd(v;^p>O~xV-@i*F~ zRkBA@9jX|Xcy{0iWlicTm{b}`YM7{F#q(?1i;hbZX2C+CH!EIHGOa9ZImqq;Ku0ZQ zA^PbAw_>zq+1o9Bk{EF8-jGqR*t@E$WZ&UpdMnZ~ zDL8hh)Fp}(jU!VBs8d3!vTWm#a1wu0ad0+>RxdKsFDUB=(Qcq4=D{6ql!=&?>nl$9 z8wT(pAV#14NQ0Y=q?RrXq!ROI@%I}-Y$2zvuC;=LK7;Ecw=eN`2P2}cX3uztYcRwA zhEbq1|Lxx_CwJ^R_hb6QsvgmKW4A+4)XqQ`WnAZl=YwMNu*@$ne#Oh3&0{q5b{rrO z&5p#Uc^>j%+;zfSh8*~Ojrl_L~g_;`>Q~KEtPLN;!>5ekjS4O>u z80~(e&K_5?9}#^}-2$VZP@PA0^zv^nv+~^fyzli&j7ZXZR46DawuFFK0g@jmKWWf} z^@kZ7psAp~>n?$5sAV7HFQo3DRd|A=oG0(9mX!Kp@Y~s@A2BkasA9YEY zhx;eY3nF#%N-_nXb;1ik)D!H1xdQ@ax$()8nohgf@o+SeX6&CXV2spLOXlv*|CtE+ z(JfJ?lC80%S@`Wb`{?x-&kDk4xe4DA0jtW#2_?Xtsbg$J4wrRE@&a7z&MssZkJORPKYtq;~yay9FUWZDg zQ3lSS#De~c;ZXP3ng+?pID!SXUKjUkF10|`Rr~=7oAKeIN7NpK3*B^&()&%(a z&o%f}WJOlF=t)Y~ZCwzj>H}#~0j+=45gMqa`$|9EvdKm#b!eITo7oD6(<3(pUkAk+ zg{l(1t~(132f4s8bWfSRZSDuoC)h_)#GS%+6<;I3MLW!~v<`2|&$iv)HY!|e57fu{ zn$S1dQ#45&JoT=?DUzj!1rbu?BUEQa$}B{O!%pZ-idZmmj>6o{oiYRyISQ|w$nFLK z(`dZHbBc{R)|PFtfRK7>7jwmC_0>b;0GveJ>9{6HKecfiv)qwZwT-#r;mwWm5xtnU zV*=*|-&ndA919b~>qc?(5cC_i*Y_vtbIZWAgZj6zVw3tVFG;QFnD7FdrO$mAC%Zm; zE7E|;f5bq`SbvhJUXpp$n8L25b!G4Pzb6h&cwVDe(S!`XLroZrOkQ9LudG?KOuns~ zehAL&X<7SYU)e|BD$6jdxTQAEi$eV#k3`H3+2>xKkL^7u&V1(fBoAj6(skfk z*P&~BFgCIlS@}Quvc@M-38sLQj_3D~fA!ccCc;^U1fN8M(cX^qBQJu8A24ja&P8J(8 zwaeje;q#GE$WuTm=|M9A16*cZZF)oNsTA3DQ(9k!ABG7cx#)U?5brSc0h3*IUjCZ_ zcqlPF80KhKI1=OyZd2sJQ(c%5jidELB-PYrWnhl>xey(SoZYsfCB;o8Qo72N4dS;e zz7{1%zQAR(yV&z#01EFUB}6l};lc7dW zTvun0;?I;}*u)^_O`ZvYcfGzvsDZ+&2p-q~nmX3Znp8$$P5A^-1YposR4%^p_ldL1 zdWsm2d@|+j*x_prLFFy&k63vcC3+(L_z{B@8}|oT2u&l+eJ?d1*j{V z!6G316|XmL`HtxeGTClO0@+6{=LR z_%~6+{0>Unh2dG48F%$F1xDs?xwF$PJNJ_>FgI?m6-3rHEb-p69RFClOeJ)*dFBT@ zeC>lzs5*qM4U##D%OiQPSqwb~dq+a+EC4tj9mCNln_JPFIt3_1KTO?5KFsNB_|`GW z#4-$sE4eL!S&KD1v27#B1Z_GQUMQxT#~zu!1t9Z*IN;bq^xDYmjS)q+36Hg5Iu&A) z@4GGxxA>fPt2GQP+Eo#4HyW%3<4EUCluVSHq8X>Su9kesKY1{;+JBN~slSnqOGb6Z z2gC24*Pe6t_HB;9oO5vcEI2>65^0e&*Z70><=0j_1ego21?Lym+|Y;J&iflNx?M?Z zt%{As{xe98b%i&a`Y7C7EhEyO_4=Og_P*qf|qD@|k**RtF!;2XX>(?T}=)LqJ5ka8_Hjistfx0$^anTl(>< ziKgYn;l%s)9~x#YqOwCO=a!64RBD8@Gu`A8je}`zOlt#3(txNDCH>R5g(ch7Zv8=J z_z%5?x50g-{O?1g$HOcjQ^WH|hF~N2zA(|JN)>lK<&Cf1ru5B$emvph|K>j4DcC1_ zt+fB6>O8!fO1NmRA~FsNc0@`X5z#?GKxt_zj*N()V?m@u0SyjK2oTamR8*RRNGBo+ zDkXG;Kq4X?5{i`2f|P_3h#?`6{xUP)duzQv;jVShz31$+&u?2ar471P(%^6h_JR?+ zIa#R93~EYb&kW_nSR}=Fl}@-9$Zd79YL;_oHv-s4)62^HQKJkKZZB-fN55{pDdbPh z(B-%*CN-wSV~Q|5U}hd8TDwTdYC(o8JnL}FG1H1IM`dfq9x&6>&>7jUOA!Pgj@mwO zd}U&FjOxNM7;H72G<}K78|erz^XeKDyYUC>|IFa*R*xI;S*kF;?yncpYU%0tb~m?O zZ-x8D?GA{S+lS&NL`$8bjK@jxrD_?DBc5ST#lpN|* z-Gf*vj{~@|r|zN~y2U-KuNJL})JqbA=JFFR7O8R;J`kO|Xa5)u;y*x>; z=%h|$X7igV)ll;umM2Jld{f*Qc6%2;$+7H{+A>R|2jFYpNa0kDuN|VvF>PsU-STCX z0!UT)5%AL5esYXQZEgdt#Tk>K5BHbVCA9j?#E|9Gedm}kiOU>QMNaL@WlJ5H4a_S} z*dH!Nbc=Q1a$o+aK*JYupRRvjeln2v1?oHf$q3_hm-V;eurSGQ#XEZ&fu0BV z_Cm`agK*6S)zrjfk2RJy@v{q>f_d_N5Wm1dT*q$}jeR_u>DOse-J$A;Ptq}~WPd)aPVu^+OrxPPa|3@d9d*Sn^JKeM zwC*R{Y!E|`2+r~=-wWgT$cQFi-fE8CF*L5f>FUgdB{JTE?WBgzTU~;NL1+;b|fNamTgUkiBT_wOU_LO5DFYb)$TqkET`>{8FqI0}mBkLxEM#j>#$35j?N z?Ez8OJb9&vp8=-BIKg~Mg|aB&y?K-NLt&m=F`Ng zU<5r4_`EcNkuBvfS*%vpkh>IyR3_aid+EYFzYMqZH~;oWc*qix-@_PXyk}a2LJbGk zad@d+%I6lIJyzIvp197n1z z0o!k$E~~73s=*pz>x-fgl+)sUN*>B}&|zn7+#8JSxNXR7?|uqn5C429Wl$hpgC*c z^46+OV!vAR#nA&LKQIKEj)mUk9N|-6kLNCkzQRMroGDQ}|8a9X_RT@yPwx0Y!Z|DS zv>j!`f(q87KDtVrfP7Fd;X=IX2jgdG7*``JC&=;m|1o5t0LA2Wk zbs5V|AW}Fkbipf8QTD#7lzeQh9E#yN`3rUg$ZZrS0Uny#WKT@Z!p)k{v6qA;lPCA< zv7u=w6WxCm7gDnXbpKo(?XBmZGFSK`6p)))UVxuvfjItn;xn~+3)kYS*#@S++aEJB z*LSwjLfc$ld1)cKR&(V98-?>Z0jRafk~Fuf2&>RF4Yma^_Rp+Eh2?bgN3b*J{n>9w*I~zqG=MyiXcfAMB*3ai3*kF>vesi7lyB!u9X@NyqaaH zNLLC{oSW6jvDpRLl@Skv!H5{{7YJDK@<8$4T4Y|$?BX$xQKmosH zakfo|Qe#{Ir;0?c3SDF5qWQGO+AUcy3A8=>ZYHl8?R0KHMC$4xe?D#r__*p`Vx*UD z;Bm$;-bpx)jE;ETBY2GcJn|E4j_jU^mm7CmEKeA$y@$)(`<~@^QHDCB#YLFlP0H#r z1MF#Q90ZA1P8O${SCv7gc*c#bfL)EJU^BD#A#@9tbp2Kx<$)kfdP6c$3hz%Kf|fDa zvCfcMIH`WA9*#GS1=5r!+^&Kt$J2d>s21nla9P*7o>6Ong9(V?H7+=Ypqh@!DhfRc zvkryfAr6>T{Ic0$lUesdS54l5Kmj#iMx|=`nfuY73GQcP zZTbI1GerN-(X4X)jKO-8;bBAKj?x{pEM@4K34Z@!E4K}+q8j_jAiev}jlHWHeZSW~T~Az%GG=42=V=X%r@&u&0O zk?Vi_(^>0FF+YE}57A zrS{72J-|Mmk+WNUIO4@+vS{+<&QMk#i8sg4rHR7gkxq&Y3i+>TgoCf;gfB7O(u&FX zYl`2QMxS*MO=F*dqjB{I#+T_{&Z7<47hWq#+SDg&QzI9KMB!*0re1mied4_+2Og<|f?4fsAQQWvtI-nA z3IbS%rDFiLkh0d_pq}Qhrdev}BO_W*kfAZqk?$)n3xa&vn%f`fVi^uqat8>VrPuR3 zF7y)&JaLgCnloEC3E(fQK}*A`!AdUNv|riSoz_NTf@n*EORa+VB3vii5Vb(F+6$z8Ja+*D{VF)OOuBSFtK^p-`#7%mG zbi#fMCcFC;7&=+~7ZFX5vUbrbZ_8re5)z-)rx|!IHg6H{CnWsPQ!0f8aCc50xYjaO zZgKq{^F>Dl>zsl?EjLTE$b++}G^7?yVT-KnzsIVK+JINpyzq+ptc{=OZk*csShw5MZLz_Cn2z52USZ?vnL%K zOVk%fN7yjmZNMN&VGj8`fPUJ&E~J^6JN3`2f`$G!g;n1&)F*v=cNXD%3VQG}W)juS zbNq^x_g?)PoA2ZNuso5tL(jT-K7qQiUcK<(*wBtbFwdl>7wM_bx)T#(qQ#G_JFDM) zis1dEx?`m?xPD_=&>Cw}_enminywnrETubajEm76dK9SNHsx;O?n8s=l!tM~6#H-j z0M@_7IdD0bxBX}CUkW`zUoy0)E#7x>|FD+Uj%`qqx}&T)(N6>2bNW12Fvh-aM2t0* z7$Q7=c@F$sg$ym-u;SuQy;DEjRXXyvQ-4uF*A!XQBgdz|#i(&>t^*XN$FbRJ-u#bf z^CZmsV=LKl}Tq!~jPZxBjR4H;|g~8b#vZJR1UV%GQ{zo0SlF#c9cC zHPK~nIgw18r-c}5XD!esm#e39+K8W`LyQG&-iNeC_y-?i`D4N zAl{(Dz+CZs%|M{I43p_+32VY_sDI?SI~TU8u7WDz?;@_6vToDErZjtsPeo62%s-`M z94fHHPxW4A3<>xgbTN&MUP@Ym^4*cp3{A`SoGx59A2UA1in@k0!Zd;k*!cScYT%I- z<$IM%nO_P5D^39r`|N_kCkhBDnq!NF>M}QC4_o>LluG@55n>}5kzYQV38-#;YH6*Q zyUXtl@ZUGyfYS7f>s2o@D;WvQv{^>Ux!D<}Y!eV*Z5YOQug@I<1M(N6Lr(!0i5Qgh zHvp$XdarKHp_w)~>YE=Jnoh92;h&hRJTvnN6|Y5FjLxkd+na>H9jcA1;B#sGps)Q< zr0>N;a(3qKTmWim#(j!i{UG*PT*5+Va((rjwJjYGAK^K@aTr`3IzCl6^reyYjF?Tj zr**|bII2Qp<0flrGJ=jnBc6?05J!33x(oc+!y}3TPr|fso3@yf%PLFZV94@2e1(iK zz+ZCpu<4QGOOe{h52loHex1XzE%JK`7RO6d|L&KBL|7_Zhr(P@lRvy63w53OL2hg7 znH||-n-pi=@T9_KHAVB^* zwGR5~U>kq%-6I5nmqSUU@2GU?eeV3$;J4S`lRLEy(q8^7ELEc(JdZP^kmG8@ zEb(ei@~!pSVneo}hxkG_y~EB_ljY@T^x{iOtFwZJ@tlpWf>n5&VSRmIC61R(meJLA zxZbJ5^hV4dM|U>eIsPoSquq(AFu!eLed^HOD_9{?1#Px|fc-oy z676xWA_m}%OoiQ}Oc&%vRR#aR&20~oJU*YfxVTMWtl=ViKd7cF9%q#Gm4Q8;)BX38 z&B*m4XyUn*-|gt}@IeHt=5{o@9KJcBH>+LNX7PTBR!KOR z4zDDSVm~Z;zph0I?&$zb1%=hoN3+0IEtE#J&_9f#1Bchzj9MU#mWWP|`|`9EVPp++ zgg2sl`}$A`cU8*UXvqnv-RqX&ygVqNM}zpyxs;CcTH?MdBY=$+fr7U& zkmc^KhVT_$TVYD++PBk?%RzCR{@etz=v(1m1hG_~v!KL5$`#c=FxZL~byyeTr&(a} zn&VP6Yr#gHpP3EawwbJ3`?S8EFfAaY(=~0C|HOM+hFvYWpaft7kH1B@9yhMl#kUka zvsMH7XeVfdMtQk0TZ#4GEcz(7V7xkp>ByDDr~&;AK8Kv$lndeOCI^{Ugb;5+K2Q5+ zYmTQ)Cis!Y1yhMA@){S{9jOVw&i#WUA>@Ge;|2g$dba#yu;m}iV+;O^3B=|49g2BL zn^5|+PC%`iI~+e$5(*AA-PFyg@!CinB9Oe1>-|2n=|#+Bp-Sz4kv#vqp|LDfYVEB` z>Af?tDv_1^<guA__W2Pe<(>v^)=)TXvT0ascs*&F zP7+Q5P1V^=suvlCUM7dwEz3t5MT)@&0iiCUNh?52G}k>!j@!`?dU<)Lt)v3pDN4~2 zO-$W^Piq%!sWcX;EO*hg5>Q=s(WhGKDY@?k_C=kw3|$|&duKz-Snk;tm(IGR2^X(~ z@wIx{>);7Ha?I6~-+4%T^+f-OHgxsvKF!`KFmt__1DUY$%ZYW`1KA&~DWZP zvHW-%%;^pDEUze=agpN?B9&_$P3XTVO@0XrALZdR@lRr5k3FhMbDzcWY`fTJcec4r z7Tz!(pEqSKkmASr@0PT?ndNU{2g-R%TokScI+2Vq%D2q|5y2_hSxW%Hk)U%-qD@tM zL9TN=81R8ju|hWR@s`M1UyE=^VmO;$m>1Qn%r`0yth243jY~Kha$U}0fc-~g_D=js z6>~vRy0s3!^S2)iIxpNo->lcya6`B^in5yF-DX2Gqq8JgXKP-B&}054Yyw5=4ASw-8k7(O0DmC_bViZ`<%x|!ZVO9?wgJ z9jbAiJg%W{`Lg!S?lTM}Y+4cLZpHbwZIy1CSNeV%*oohbm4?~E%{MSN+CsJgn*Q8oOp0*5 zlcJ6DZT<+Dal2cm#Lwvr4*6k-_A*0mk+ZdLC_R2GZ~n!YRCPcjplQa;9&&1mJWzjO zT}874XkZg`EF8!T6MORJVYP5?;T-Retu|Cqm75;E|ciXy4}(C5bKq; z#k|bAQuiw;A-&@sq7#&q+w)Af=Bp%@tIL%Z%g`buoAk5Z@2B%a-6z~aO=$6ujqeQH z>u!%pL;|57x}dQ5d0J~BP=*|iBnOv>H6=}2#HSy@fMd$#&Uu~rL93cM?4`MywQc#P zbtCo~pNPz!ugUNqC&PnUn6>W-HD=%yl>Y3)f%@|dK4<9~WeleouymI{*sx+O8G2-D zv#2^>X$Nr&4x258W%!Ft6abW^hfYxOOB+I*#w?@2AJ^&y-P;$DDxOW&o98h)gu#oC zqZk?UY&-MsU0vBiM^M}QgyqcYguDEd8LSnAnDE$}Dcvb-UutmK+enyp#Ne;K8Mp1m zh(u2nI8J;`E)f|l9iC^{FWuBxC3-v6t#$vLY-}8W{EUrbQ+Jd#14`{Z@h8Z{(87TTx{k zA1(1+CMM3)d}&(o%XsZNYH~p;{}j9Oq?U>VRUP5!*YKp0N?ESzx6fMvMhK#;55kUQ zC*=e{xrH~-HyT3?*!`69see~mkpB%+UWNzlCl6>F-+L+jow@nbw{r&&2kkK-b&2ny z;`0Jxm3}H+n7Kn$x8a`=uM*90!)wAv?u3-&k3`cG>@)XeY_eREHA+l*jA9%&M{l-O z#P%NvQpO5uCF2*trhosP)X|)V@wuo#ZBGwoEBgDJa>cWjrdTJjsDmlUT9)Rk6&NJ| zBI{q!XI*M?-}R?2mK?(96}pyK0_JcsJl%4i(DEJ_uk$-9mw=$idhaLvXI9y z-*z+Co@yX5|7s7QHRP=<)fQ115$6COvbFOBpqQr?VteuzW6>+jc0!Jgt?7*M%u(8f zF!tZ5iz3=IJjrxXc6&KTrWVcLfE2Ur1BY2kztW|eo%=jR89W0xo>j5R$wv7UwRe^SQd;*ZsZsng2n{vX^Tw z;?A7>EJg*!ZpA9!q02*~lzI`Mv-zp`TXNo+J}s_Kkp2cI0HgG9udR zdoyv$(|RUs&lglq^vQ#MEp%@A@6l($<}oYz{s)b{_W<}Fx>&SK(i5? zE*}{9s3%-o)m;CebhvqnDO!|ME5)s4rv8PQA`^*D!S^a?f7|Vpfd?dB22$~0Bf+d% zKAk>z1JRdZBCd2MoH|w=4Nb?ilf0r&n`0XMW#BlT*kXXxlW^FvaMOcMT!e=V;CHR+E?C@^%o2*LLW=rsJ~%e(jcb2qcWC6O$X*h7?B6+mZ!qqhJK*U7=fZTwio?N zUigFo~xwl;aurrM=1K}y`Z zu_37Kuh;A9S1we0{*ob)-NyEfFN)QVuVSf=PdPoKM&S?VLyNX>Y#W5f7aH)Yk}Ebl z^V*_4f5Of${jL5~wb9}5rA?vhh1&P2$9LxVk%O=N^XorlFMc8z)S6Axt6VTDI5|Jn z_acD7^n8H(ttGYjZqmYN3`7jGt+rg8FOvLC+|0HT{7|92n+l_;6|a8zNA>}&VQzud zK&J8RX!bRF{p8b?$ptJV2UFEg6@xP3OBa+ZfxZ?&HncJUuB}gZp894!pPf?w`Pv>X z2MzUIi)TJ3p$8HlYY~IN(K)4n8IHm}Hm@Rkr4BNXf5IuvbH&Im4I9Q+arJ+@OUtKY zGIx+)4+lkLm(%%2<*H?EYCrqh8v{8V;~knkA{_$ATWLd53XD!Ics5MnzA|ZRrjs2s z-wt0hRfN2LCDLPv-XXrY-0odo_4@I?1y$^lk>Hdmze$j122qaweVS{|K%lb@U5(pW<7YzFmL(v`_ftQ)NMORsf?8Z zuqlf2ud2|maPYg3a%^gf8ZjbdnCEBVk5wJ3CUAxP-(>VH6lFw~X!}r~5U~`D#inQm zj>|6BmEWMES4T$jtC_Znv14%ykU5Z1E~b%j+^L?tG3$;{%;Ng-kWJ?dV@r~PPD`9J`&HK-7VdV`JH1Q3*4?j8TNpI@^RGnX zFVPQ6HiS03^ZkJrbRsERCuI15iFeA}-W!Fg4UAkdso@HaxWX!sd%@ab*WT zJ~~$uHnOM;ZgYyQsuNwtQaCmEO9TQo!3lqwqcalDAe;NzRjtDuk9<-czTOm5tvO!~ zzD?!qbiC`oz!c+6IAkQSd1z{vf6IN3Ro7e1lNcYfo4VRXrgw z4;ZIR9NT{Q-u{*~R}*xqvY>u%naq5_B-L=l{as-$UCTpPP`8MaPg1vM?zJZc`7Admew|fs~>#5g!@2~SY z1aP*kpWy&b9Ub^;=j@v)9fUaonpbav9>%sC(h*n)J5tI5JR;+Pmj`Wx!eVHHj;sQrV3ts!3+68F)Rq#=& z+MJe30k=>luNlg*GF|2OQ?K=Y{A}G)T2ypEW)J6)^SyxO&r829%y~Wyte>|aBoRKA zC);$M&qLiFHYwTu!3r6Q4j7>jIt*je~s3zhiiJRT;_wr=Sh&Hu=SOtKwoBCjir91%lhgs zo+XB@y|ACx9~_Dpw$*JAZNFiNT&TFSG=0lRYrfeS=~WKf*sVm)$*!Xmz#t=PKhnHx z=i7)2KA(apS=j1L2;Zq3@AF-+Gqz5Mb=bfh#!QPG`F2+YviFs2XbjEv^s(#SB+R-q ziwLn*B@YnDRcx5d+?MCjf&C$D; zU}g;>M_BMFL>Wp54X(D=9LI}u#`L##nh`b~t=FKsLT)jGLN$<6q#JeinM1CKP3@|- z7PL(Y8k1K%wEPq5T_MV^HTUJyXL6f9!5!1->=Ek3483VuRBih~4W~v8Zfi)&rX`)M zD5lMOj!=x+2WvIk+kRgKmn;6dAqc6yM_PKx**IqG({11xfOf?6Xcb`&qnHiTOynSi zI`q(8hFJP&TA}guuA|t;O5jtXhp)Pog45zc!CAPxqM_r%@2DdH$%t0CL0={--(J#f zjjiMj!NTP0=8Jl2Z4G=Tk7-WYPxI@geb#WAHJ=5aZ~nx#7a@e#n3O7}ia%}@xDm}C z6O7{&2pV60SldJPce$DZGU1GE)pv&daBClve^z9vgswC%r!3k@Onjxn)x~OQY(lun zvK5Xi&d_2)+(wWqJpt{Pkeh6gQZkyosnq~li*b0S;S)+F!M}>O%xag4F-{SO+?jsv z3xjgtuB0CZh~CMbd>m?N9PFmJmWn>6Yip`grX?fEtUf16EcQ3*^YrjJPHGb6nbF)G z%{kS+;^=yqJh-Z;fzMHqJs0L%OUhiDfA2#~*8Z0kCJX-eMvSRve0)b;gZ4IcuV06g zjbGS`yVZ+TB^yHDzqtV3tCBdjfv5fSrBSz*&*lMio89YRR`;H@l)V#-%};z>63Gh1 z&BzI-s}Rcmp|MvHMN=QU9+lr;7}B#$s9~4@ai6Wvbx~E+v?Y4 z_qE(8Yb_OObI(Q%g1SLnVJOSSF@5mb!en5A63&!xOIHzgcTJbdni`gZ0EO756($D<&&E+XuTm&eSDW3;N*%P0MM!zo35Vq0p_;9hpU z#6U-hJYSM!bPvxqJC38Q9*8rw6t8&+Cz05l$~eyFcs+YHi8nzSXh$8Lbi=S(SK96836XXyiB^kzP=*u_)?D_)0(M7!h~= zNtrF9?JO`f$D5yz5D2alEguTv003qNM7faBAXnOCwKs?m3aqdTt%ICgHPgWsOFly~s|I$GwPC9{hH3g@cZSA$xf z2RzSs{`i&nx!-rYV5i`o_*~1_krmb`FV9S{OVg0d<}Re^q7P{i1c}?eM+OM8gr)dp z#+TYSVo1-BgW~N9D4MrnIS{7wRZJ4c_$TE*bC-9*N!YiDMx!2JfoMOWPMBu* zT8+IOMDIk|9}UI7v91bdZ|Yu&wmS!ZET?fLohd5ygs188MZ1YBNYn0-2xJ$HDGbt3 z(MhvAuYtEo=S{yk!o5}O|CIZjZ00h`tKL-GU5YEci)4(mWp+b?z$~#2=_0El$J|DA z4&gMtbDq%v;fhwr#;`Mt_T}M_$@b$TBh3=eJoTC@#96^D@8b!jn9*^j^twXuV`=gl z0RPNchqMC<@!K>t>?{rKtr}Paa&;k4hPdvuX?O%Fj0)|pZo$bKf6V$(^m@%sx-7MVx)YzojpiLC6xVtDWRIh0GS# zZ0p@sl$9CQj6QVr4E+gnLtA>OKW@J1{txUPMLB(%`71zhJA*-)2n0!YX<|wnf2a#v zAT@N(SXqB*enBAhrv}3X`$C5%34=Nd`5DfIl^z^IKhHvXRPk>c1^KUyYS6g;J7N9l zx$QSLKm9dR_4bClVGW62&L4;DynNbPKeB(zaQ~osxLrx!*o@`BKfC$V`P1mGcQfVFtSR-#)#w%QD!ySGQJxsH2H&v*sT1>+Ne z504d^-9WTC-b&!;ZESTZkrYO+glveHefC=3n}1@^wE1h=7ukWA8&(ptxo>z^?*2K> zu-B~Z3S;(spYx>higNM7Lj675Qc8p$JXb3(-o-~Pbs_T^(`7GQfX@EM#H9T0|9n2f zvS3GOtQ1}mf*wt(uS`DAUYPgVZsuslhz!M_(WP zLJT~`LPuie?|JYUMHDewUe+LefM4BS4-cuB+-9B4^C{~~1TU)7EyN9^b%bF34!gB9 zM9#RYvDy_T+)v^6+bm~t&izN632Zhqdh#Y7`@WvG#hso|TmFKMy!*FZsmScLV=aeY zuh2Divm#BmIGBxUxD^Bu99x-3?;Y}^m4xbtXWdEzvCrlmp_zu6XwO$?%84!{-) zdDXOD2w&nKWj3~x58+bw>o6gFDM11J$}+fuW2#B?GWf5#Q;Va9)G8YY$mk9GYtZBI zDEG^m;nC1GO^dunm(My@JiT!(x^}^^GlW-b$8ey^ZWGr?-CEq;EuQ|0QTi!LnGl*m z#3IGG$1vd1zml=r|CsIek?kqg4}Yv2xU=b->a~Zik#h|Ohqb<|f9Up0+32@mJn>|A z>*lI9(6rX{kF17TbOX`SbE+*r<1gZ0Z*xv;3aUsr-@%6J9c??J{nEYj+hY*Or}rY0 ztdPBpn38#^R@KS8?De?z^3~LZp<5UIfAQZ{*5&bam&5%Hc(&VwOBSF4Pp*$BOP#z%Cj@VnOQPK5MA^>EUrxh(@% zwH<7~>TQ)Dd^Yi)x`gls8-x64aM=fF$nlmdX z&o>dPyF0G$A+r}Mxo^08?cy!|Oj-Ix{4q)lkw`pIgI1%OIGeZa#ig#QWIuwV?m z2wefO9TK{z{KX>X$R2E>=5p=};wQdYfbENh>l{DID!yAJi@L!Gppyy5@l*2XB{u+r z$3a2lnI5lnA)DngG8lfeQL$!1m=8?DZ=RnHMeYqc3cbo)9;d$A z?u;kuLWaRTs3EDMewLP8CV9{Q3-m{}a1y*Epp^-2QzrM*)z)Z;AHS9kxKwym%|c@) zKSK|jNH}^IE5t^ynS|pl*e6Zi^_)%FBbOwvc)K}fg?k^2naXA*5Nr#J5i#jR1^ggt zOa5tNsayYBijciG*|^k+Rh!#47&LtN@;T)Q`@-gJ{`HWbdZ*JZYxld$cKZSj&s|H* zCq1}$%hcN5!qel(4VV;OV(Q!X`o!V5B>xlgEXO*6EyX9#Hhae_1fcyoahM6Y$2 z&q>*^BQp!jP5IUB9QAP}YztS6<<-Hq8OH^U3*^6sKG>lb{(z$%T9j$3gKoQI(?hAd zWd0rEJgPc9D0FsB4(i+y~2%ovL|C@!VwIh|M$_hx>Pq{QEYu0*Q{B8^zkH7PevVTGs>uYM==RhZi9S78R;D>wNr6HR_9Uh3{4mkhGe?jZjcEMo44(%`$+* z4ls#r0sIdAp-oVRDbhJ=%=OS8tJqYgtsl*icbH0KA0cwLAos9sE?wukKce-3oSPZ| zw2Ni|!5qN~gA#?GinmUc3f@h1;zp17jseI)3Kj|Y2AEqVz3_}V6jHWiVs6Q#anms! z!>hV!z8UN+;(H>cs6%f3n1ne3W<2L`MyrZfou2 z@`KiIV=HlMZ|FKl_Gnc(_7ouyZ1Hmqr zANQ^{zKbnswv95s zp?Ih7^zP1-Eyn8=8!5X#>n&dhys#I2*`V~XI_x;cZ6n1fQ_ zX%zL=xaqF&zr3)^mgA=7-CcTz=)0RoBXw;b`Kxf&`>*5Jyd3*Phxpm;+(`9I70pVt zIcaA<%8Y|+d++XepIO0JHTZ_fg15)K#uxpDtI#aza?iEhH&XhCWv6G~-3aIq`{o(+ zSwH-r%z<}xhcG#O3)+l7Gppyn_ItH?0Tm1)fXE>F-NFgiL&C$JDC&(d)2lIl<7PC1 ziT30kP`h^YuJT=jy9#zycMj#H=A*`cu79S_cUIw|65+?%CmSc7PyDG_;q^9q3`~X5 z@6cg%hBjOPqV&F9buZSi5L)|?Y+47cvinG2?Fu!`Lu=ciEQvIn{hOj3C!DpLVoGZ* zx^32Z1Cxlqjn6A%T&x#ZznT(Fo;;?hDu|{20%KdFmYbbmZe-~F@s$D~X-P%=8BpjJ ze`gCWmP!T+^(qMbM2^2NhjK;Su}4zet}(N2%%DBu3{o3Mc8)bP7%@(|4Vv(7@tHL6 zn|B_xaaQhWr~1?wjvn{w!hXat)2joDR{}Jv+8`r`fXW~|yS*u^vjFu;%+A&>ITDCOF z>h7JH=6!5pLy#f+-wsCa-|u_GPu#A(_4hY=JS=>8Z2geaHU(VO!?R%jUlV6PPxE&U{ILq2K`toBjY%?&8vANypK=^^kyj{AzgE!i??8}~S zPF|N36I5+DCi!EdtxfZZ1jxdR&{LaRftQJZZg$K}g0FO=-cZ%abZCiv_(mCHNh9v| z1~N_7jNFRL9SEn&Tpe!B2)Iyr5SeGw@j*n9|4AJ}n1; zdv;I-XR3z|rhm>&@m1QheM}FbT8;v<#Y#>-1MuY3=%cEsHLv2z)b^LL5 zv3?Nmve{pBLH3UY6vu{R<2HJn*wya`BX;c+YoaX99Un}$XNsiR62ur;O;Z_^KI)@* zZ3^>*9Nq(x9w9DmnT;N%sk<*A143$bSZSx#o0>?e)d=&B`K+BY-`@QI?#~N1X30l`UniYO4RZ z2ik|j-Z~4vU~VPDkrs6k3l4icD~`a(?z`du-EoeF={CHoc>kB9^FjWY)aWjTbyj;6 zugi8UogN{7aJR0MVdWWC>$vYAf=*pM<{7fKFD(L&$y&cEG&2=1w>0iyybkpFpp#of zY1W^riW{e^A6FYm2fU?gHV&lA3I^fF`c){#0e!34qbrYrC{4M|v>#z(9us>q2tu0f zkUnJcF2l{3p^$ZY#}p@v5p4jG%}piDOTQv#RiF0Q=2g~qLvT8vt7cvnT~$iktsgRI z@#AwJuO*so`FdWi&_H|cf+UdDdCH2_n}{i z&w{-7#NTq;~$vN`;#BEO=0 z-FZc27qR7#fQo7Srn0_!1C8!%xOEaJ75?*|D%J=6vS9NgEx7pxco0knjeJx0dg>K3 znV?7FeD)!H-^S-?9*w}PcihC7ezP(;Ftpjct=105d&zXyaU*u|Ta_=cm(>*2Aqr8V+_u^=WNse)*`) zCQ1{vXStHrF_w0TMrm%!T`GL!2Xc%K3oqtzKss3oz~L^`Z-n___xVuYi-@>c#<_b~ z;rvuTC0F{IEC21$a{0v(Q3}XOu`=E}euw&uQ;e{xG?Fx4L+y8+y8|A(l7VDD6Bl*t zoAo=YU&oaMF>zfdS9(`HQ!r?S$gk(2b-Q0;+j+;$uZ*64^UBC&GePee=bO-wN zXLGrpTu&9n342TqK(F-*3%(P10^xq|ws;1#V(vnNWIBgyQafXI{3k&+&0&IRwr;UsSWC$fH09kA4? zPVlas8XV#UZO|Hy$(84dxDo&QPXx=TARtNZw><|6BSxa60-aoR$?hXEsAe-Cm9!2>H&4>MBzm`QSWql@NE$$s^Iq zY$Z)x**t*q2(qTPg9!ghg%j(sPd~=Po#<%#@AS&ajloT^R>i#Yril8VS{;X*bSL#@ z5(yywbHbawhh|3r2gU&z#W?O7d>J2`^38@-*9=PXWbQ7ijyT*I!Ct`%JG1F5Z3{=N zkn_aGvL-sK^Nwe2o!4WZIJokVWFd-bv=+r5O7ox~-s~kNuoXSFI=5L{b|yh)PKB@- zX*FM?`AQrs;N?; zamqP6gqbCgUtOxHjur03b&L>DU0DCoy|t(K0d5?C{t$Z6J+-UNA{w(b%ZWEo70!nn z*Et9Vy3wuq>dZ2I@9sPg{vQFL@~!?k2kq~f+>sX$b?Tv=gSQj^HRdDF3D=e4a zBy|fILKVH9P!5s9qH2`=Gv-G^>J%)F5bliEv{uW)$y?ZKRyQGSYO84xipQH}YqzrW zR=L`kLX61z!qRn0CX|o+lCd)dD)#NdB+b4~m+(!=*awDjT0(>eRy&+LEUdAbUJ+GAU*9&SU`?h3uI z$eLi%o4N1$^+x%DoipFHVBh7_X4<E9&xvtU z4l%iWrL7O|zOyY8GCOcj7LW^$&X;Q}S+NeWR64ERnB*>h^I+}7KE}Vs`~w)0bmbR> z^S%9LP4Jmhln4r@#Lo0jQ-_kLM6coZ+I3Nh2IFep&AY~xtQ#7SA`kxxSz-^~^R8+$ z3g zi2FdkG|djdc$qFNu~4;-#!V`>h$;L&n~BUclYVzd-A$52H6AR%3|Y)1)L_D!pbR1$ z{8lV%9T%$g2-6b*XCZ^xCQ>die_k24Obi{|wA5nfpMIVzNbIUq z=MI~KIFfKhSiM}>x)2B~O-fE!GS$#!^Ar^U_@el}7T6YXpE9E;F?Fihp2%~rYAC)J zG{_I~#C7IV$I4?)IQ(j6;%m0TeZq^nglx5(t9P6Ej)+2n1b z-8UEG_h~xAllmgev5|!!Mbo?daJ6A3UF8+)wzBrKaqlPM!+x8|HZ{^|1;8j!ethm+UWWF z$T96g2Q8P&UbkFUxyO2aMXzHLPR*lA77tTy=@Fu`QH{BgZKwJ3Xv!XwZ7&Z$M} zTpKS|%p0z8JMFi@+#qzZyh~_Mra;_w(9nMzRvYLF#h$>29z1k^Gw#BRye&Dkq0hJf z5mt!1bTOfH`EVogFMRnl9RDr5l2PVWxAx0N*Z|=(rP|7#4-NGPdrwKPQ3oQr3qd*P zelIX>a4PdrZY19cRY5i;n+a%E$bTwYjiezzjNtb6@$+C~yntC65WF=L)dU*7taa_h zxhCs7+UPqfCC^OnJRR3FO-f_)?sISELGbm8!ji~fvJx-O>Z-#U2e(-IXp?r}cT#sC zJ)^;rpZ9E=Pc?&X+fvK=Q4f${7cLDf;T{t`m%-}0y}Ivpd9sgruc1gfT9<~<#9YPB zW7K6AuU5e7%CUUuxr7rk?IN>j$Ix{tQp{W2Ge2C}2IbRd{Y1nbv5K7B#NRyGYDShl zD11fWBYv`prrNgU)EX}yB zaN1$nuS`2MBXPb(u^U;b(5SPD+p8AzsEA~nE-W+kb8nT|U7pFiL~Pij*}F4tU%o8< zxe=x^{w=26r?0`55hh{Wg)R!-g<%3XQ^)h_GuR_lke725;;k)Z39T6V+>FXsfnpWC zRGY!HGz#+97&w~^X4WB#REi`KZD60VO9Pe50?pdH_$B4v^O^(If*`uw@8UWURSwz2 z9@3XFR0mpJs(=bGxO-&bwqOog8={5CrFrRhmg}R#Jl?5}K@=zGJvJpO%NI6xUwD7<;QnKV+m~Kfk28Q* z1wknvnh8Z-<4^3}9h3>INwH3ebkGJmWGu+zlj&+MyFk$n^DKLSnY-qtlrN_c*?(+U zvrIRY zaIx`8p8P%&2TyX*xlb`CNBRXGORf#BoF`NN!^=4fwNJ)?kA%dfrNS9eD41Z=#~pt< z{&;+q&G^QxWdUpj>5$f;0h&y9XiRn{ob&>tsQjIBrE|^1E;Vr&y9~N6GvDf^`#T^m z+4f%1C0F!fIrtz^)C|vRh;$ONpNmi=@Q~3g@cH?v=sW98Z_GWtQ*2I*c%|y=cnr0m z3ba?8;WhqxW4oyO37rk&JdiTB(Y!_LvDULv?UijqR=~+!%`3Ff>^Ee)bU~sPVD||N zEDoWnzY+xYK-DkRi+ScmnMoYnq=n{Rd^edK7s1QMHg}>+sZ|%HBX_}$Z5`$Ambwq< z_%1;S=WqQU#b1kEf}=TDfAG@m>A<(_&Y+een*w`g}^^Jby?sIXoXbG*%K8JBdXFkpf!lR z>IfbIGyoTjSRqX6G~<~0IMd}Wexe})_v}vU2M^ZogCc7@Lr%i_{fUnlH$|{uGppyB z#ot>H9{y&1A3I(n&59$!#IL% z1%$Pt4IIKPPy8#Ld-A_Y-QwWNcAri3wG(^7-5sJ<3Cn)(@_db6$1wh>8%_M}x$0(; zv1|A9BtP_2Kk(jQ+e4BmQS(-;S`COcNJ`Biibkyb+}%dhK8APlWQ% zJkl+|oNK${y~q9eR0fBg`@j*nZjeY!%Gn_38U@x3#bj*7Is5`f!Om>OG{a;ZBskcG z9NcbYiTgfr(f2d3{H^~`?T?f#JyTK_S9oBX5*oQS{o&Fs(z7r`<$v0opjY$5u^=Ku z^KG^=Jr-8Qs%8;c$daq3r-Q#e1qXMca*h9_16H9vM<@>UinfQ73P%90Kf_xg63fo! zqkglQm5_GsF8@~0Y_s{yOOu2{12u1bQ0r{k@95RKdRMMDBa0UFl#741Gd*sLdb!30 zewEsk7pm>NQ%R%wgU@k+$`Jii{O>5*z%iWF^pDOk{SzLcmmSk%ng@ov#?U#W_K)^DG&!2-Kiw z1@?9`Hdt)yTt{zN3OEJD1hdt2LKyJC24UG%4LC zLK;oz41*;Ok$OgH)ALYRYlIDD!rB|BJ)I4Xm<~!H55Kaf!NC3TgRJ|$tea`y7 z2;R1K#QTb8cV2%omI1|;&yCrc4P7yB(PSc_g+lxnX-ED?=2s)>@6Uc*`4}A?ep3= z;)+0`mYE@VaznB<|ACI=?nYX)2fFRJVqi@6{;UrAv3jH4v7rg*y`I&VzBvm00)7%x zX)acQvI|c852wPeE}hx%inwxrsKa=?Kv8z~&@`!?5FiKH?h%Qub7qr+D)-hBwUmk2mG*@j@-!GdFmOPg(l%duMon;3EmM_%+v z^w@>{IH>hcUHU|_;lS4X7toiW-mx?uIU%D76h0G|2)=Nl^tA1C0n|b60V`kn+Y_Y; zZnDT`cEk0i;OO@(iGJK6las>RbYzPc{T0D9ch~!sTyYBav2@~4nj?zU@ymD~#S)%@ z_kL;km~RcajF;q~XlFf^)aE3xrqZz*N{5L(YOpo^(Nna#5HIQ?321bH>ti|j_t}VZ zHf4c{2Yx<}cuTJm@RXOGuO}^`#Fje98b~(4!de5KK<tdM2Vl|GvuK{d|16fasX;g`$E+6ow(DIq!nWP5;tN_l8m zgaX+=(~bIefG$2$8$_auOl^7G&?~48zCqU(WS(K%ICo|&AJf?-M(cR}e zJuy$jfpn_`<+f951PBHwBniP%m@Y)WkKXoW`XYlwX^5OC^JoY2MeDwN#nl z$M>EobVmId697l6Lsrm@LN<4)3&D`6?IC^#=X23@$>xn3k<=#aFKWhQT|SmLU&$|K zD#BB6*TFQJCsPA&uAW%-lhj|7==@=9POkvLJ-D3w1@QBXeP3E^IpH0DPq4Jo&6wh|ru~$Yh#pql4Ws1Z9s?7|B z|8u-i7XOWhVQcR{j%=(ug*8f7l&x9l2bSPg2Q(J1;;#R;NpRZpSh2~pQPuI3^C^F= z7xz?Dse_+#(+;%U=T3x^&Q4E0txYPN7#s1nz@Dh@a^LO~FYfN!f(6s~XlC`YA2sq|>^;W~mrhLX>{Bc5W>ilYccCq@ z)nxs}5(>Qy|LB{COQuJ}nbHIAShd6swWYeUrGIgCgQw%hl#kNyI#%P3%g;9`0=|aH+rs>@i7VZ%rCeM*dTJE%`r8z)fxK>% zJic?9)}AY$<3R?qUQzCSj|mkFs#wFPUaTTvPX!(HP9-NJe~=hJN9* zdCu7U5b|8h+p5qHYBX_WCt5)VS$xHWBAk#L=xxvDKL%*UnQM4SMpvZXLzH(_oKi-q zWK1QzFLkr{fdL=`g0UHue8rwR3&BWyM<<;}G-A-*GsAQ*Bn15!cqx(?ahfRES0472 zIA9lK{h>nrlkJsxG#%o{aEmXJ>qM$6ysGJnmnf+^bXm4-1s2#xCzUpiQia)pbm0Ix zHOK=t;j~T+HkL5+l7d)Os8~FxZ)6kw0!)j$bm>z`xV6#BY?VnU#;9)}~n?NY+eU`KNfWNB*}44CVg5)P3Oh=!Rvd12=LAq~C~jW%PZki3iFJ z*ZHJ;yRd%a{KfTQBKbYc37c7^$>O~B0m)<&hE_5saUOhjGzfdsa{dwnXxG~u9(xtI zX~`TLV*S+TQ-0_v?*m2V7V{VO**TA7lj*g;;#31moMnqH%0 z%6reD*={+sr@qTGBE}e6+E0MD>gMVBSG{f1KALT1K`S%p-RnU`WNTJ~?Ek|g8=tb8 z<6>+WNI3;2L&;xhzr1^jz4t%{Ftp*L7Ic69&ClU^H$PZsUs$qjm7iCgI-MDL-9=0C zdUf*&@qq=)sSB^1oI>xKIsqTQ+6(1fqQED2+Oi-&QWYsQy)M^)ey^J(ftr5t9>uiT zTiZBer_Su6xhHzeraj|vywVji7US=TU2C1k=uo~5E}*N;x^$Hdywa2G@vv`H$dq5>_#}N`=zpQ;bvc8*WC6u!+aD|R z?a;_$J$&dWoGg-jB&~RCuKD6p&-S>Zz*3!%)Eyp z6wi|H{a}A?0!^j^0q&UQv|-iu`C8PfZqgZVVyskW(I}@csg;$`8@bFiCt~>?x`mLs z^3j4VY*v6GqX#1^c#Xzt!H2;RE8l^vhR@J`&SY8m-t1{!+VF`1;+Z9S zPl{P|^q~({zOt87MUD?RQ@u`PkB*(Zej-_gYEfQn?4}LXaQ=h;Z*M2YX6s~6W-Dwv zkW)e_Rn1Qc)nv%F`C_}j%zrAr8nDmcAo18hSt5#mk5c{Jruoig$3HBtQh}A}Vnd-D zKK;16b9#CBZZoFd+%baav~)dSJPWjxrP%BupV0S9=%&w@g%)^8cWStm0Ced}CYht( za7=o#)7I{dRGaSf5;u>&$4Uo?qk6?wbdA84&%qLqqT@oDB&_3lFuP?>t zYU=(y=MNO~v>Wbk`OB~r)#B27vK6qktsF%n zSxMDdgAmnI3Du)~MEP$W(~fW?rZar}Kyf(FQ#_wd#rhs;NURXVRl?>>?n+1twg2vY z(Er?K4WyOfs`u?r9rn|X60SLQxoVAd4A zkFC8)a_$V!e7`N|%{xUMtJ&aiT&FuBueHnZG{^|7M(H3{O-`5$z%ZorJGr1aci zFGXfxZ3-f5=y2lARbiVK<%4EWw%{uC&;!#O!>2H%FG1a}U}16m1n-xSm)CyftH0Ls zUa<4#KGX*sXoxuDPtl@nxPgKX7A!8;$M_?`e4_)Dr@Vaj<$zR!{<7f8_5@CH@9w;# zrOD7$4{))PltGs$59#6YBFnhUxB7{pVSnC` zL<#!URxT3_mYB~_#;!duDAD}xj})4XXkn>gwvPps_$3lwqQ@?1K$ll%-0n>jP4|i3 z`72M7Bc78H{3ka7WdhF{$l)q#b_Qs_LLF21W zFgwjy_vJ^0fQxTMtn6sPPHKaOsLc}^_M^|bdu2S2Lm~?*M=<2CLDs$`alYIZx!d`G zoEpJp^NR@G=tt+6kjAC4*n!q{v+V&*3fk(C(FyGfHWO~T#0KT`4W(;<)$r9Hez>4r z%Av~WX92euNK!|@7jMhisI{2lL=9BE-6%JASfvAyC`sg6X`otd^M6etL|NNMPA<=H z`#eG`D*6ZwmC?g%K_G_Y$UI;;qHh$jR-YO%XQHJNl4p%**rdbi)gzdFvGI=ao9GSd ziHzwj^BJfU@-FGWcg}W=$v!=X8o+$ZVb~HBg)3j5|Hu}E(ipWGx<;L^X(JfZd9 zaBvL_vT)D*`tVIe!>y`}c9%Uzt23ja(Z%?+JEh~G*%pW0aYtjfO1Tpl(*6OH*q*l& z>>8!6byTRxJX~UUtwu76{cda39t-Uiyh>~7lGA;H#1f|U=f268)9ot-&c6@UxHz3Z zyZ?yh@)vi61NFj-!3g5h>Vb=4zaajUS|6kA?Rewvi}&e5pA*6?Y`gP(Xtt7w>DLx# zxu5@%mNtBuk)pXoF|RCsC>D)m{FmviQM|xjaMa#(FgLB>wBv-x#NgmmEpeJ-SPV9O zda^lveD$MvVBVg-tmZ2#70g5GnI&5c9>pcDYd#Y1(2`<)8)fZCuK)+$($5|AZMMAA zV(g7Ze@Yzt1l!F$i(67D8C>zy0JZEmHgq#%K0=ml5rB(_OBk66VNty};YYjIx0 z;(Abq*fyiT=YVQg-ZMG%&uH01i+k5hu$e+f)*%L&v8)vKzG>(JzCv;@4?~y=%CU&z zMK@$8%Zh;Ha|hDB#cO^IR4vme8{ths z0ivUB6kTRd>66ePWC7R4CUflK+Y-7zWicQ1w^)B(DetI1E&P1^S7plp-Hpx<$s;w~ zy~rOzV1ha^EtM?|#f**YaC=3=t$4%|c4se4G5}PZmFqA5kY1Ce*$i1Sz;%=`8AsV@ zMPPZJ^@-Xak{^!CN z%^Sh?lTDc=)X%#dW7WnW2LN|renqR%->q!OKW9NJsizLOc0nkt-S%PAqYw^1QfoSM zX#;vX7uM1=Sw%LQ&!%Djl%7Ed%DntR0i^kZ0_mornSWspz5j6{xhjpBzpHcHw;G)U zZVOk9fL#{uUA0;DyBgv5aP>sg{#$QB3s~&e`MZB^cp}F&vC|rtdI=4!Z0#%IDM9SC zeSmG~G|=t&yB%`C&8}pIQ?kqSC%`#n}+?i6tH|hzb>1lFuTt&z7blzxd$@EBkP6OmQ2a-x0 zl6)XYkEQ?)m$^q6V9JjI6l6PIGOoyy19=-b_zKrkXZ&qOCR}FLiPlXAZAlKATgD8qQB{ER)BAi#fkQDJGDr`EE|R$yPu$nFBWYkx zboe(2QY}omuQmAw*GZLS-j!LEZLmT-V=UjyOTbaOf<&8KK>nRYkwf+oODVYdA%d?> znaoe%qSz?%AqqP%+-QLYVsJ=W9z1ibqaf=`8oUwsONjo;)g(@MU0pniv2&uRfXyk# zUaRnQu~b5$2j*u?s&vgr#w24_WMdVcrRhI^BuKYjluV$I01q4s_3)e#QQPPrZNZF-xJC6`H9iuxh6J6S#xVkjHGVhIx)+s$S8zmsY5QcrdT z_dI@j_Wc?|qs!YX9tXZ2OeycQUjO~#lVMJmDZ<)uKcVJK>0Bm1 zrl3$v2t9rv&*YkcM+A$$|9(Ei8TwCDj`CjzKY_)wmJ+Uy0xe&8zjO`j*QLDUdGp+yxZ#wootHp zKb5ueYQ?wZWILU-F28$_MzP?I$i!$dmV4-eZH?oDF@KrP`oB3B%SSWkqkcq*4>Jdsy}kfyX<~8A<&@ zB5>Y6)8>^9X^g$tzvQb#3&Q|;S6+zECUFuKQ;w|I9t@` z+ByyF!3|drUb#xGD$&fsT}Gp3uHx!(uQ}Qq%7TPk4IXIq7i@>Qwr9Qp-Q_0UG?~@z z4qftkoMKY~H_S{u)sTeC*nGO}0>{q~Tvq=C?ESYIXM2YK_?q}SGBVY4F1nMJeVmE2 zq4HcJ>u22SLOo4I2c|FghKYGN!oQr(Cu%NB@2>^y9UU}HN%tn5oNq2HO{=;SP3`Dr zx)R%&v~zEFMeCtJ7!jAc=?4GzQQw1a52|PIRI^u7{H6>G!uNZXgLWYUm3XlRTz)5W zJQMu1eq47e^;?DQOc|!tO#DuzbHmIk+KKM|$h=Fw4WZ{K*%Re?6Njnd>1&1iwK7Z- zSD3FLS2iNRLeC>QQ+}g&_Ab}$GNCuIV+xAwB*AoBq=#@XeNDv7$pO9jfwh2@LCOl{ zm=AiFP$y2ATj>A3pdmn!MpjE~7_s_6KKGJO;K|O)w+EqSHN|!|r~Z_uk;rDM0hmvh z>H`?r6(mt}e;8@!Pp~Z3VA7Rs4+})(fyE!n2uL{Ni^RLQP8pte!AUgSio6CEk!8PV z>IAv1T7(4S>n#%xW*bD^u&t|#K`MkA&W`AxJ}~bgh0lI_Kxd?MVnlS7*d4hCLaixZ z#ai(b_%0FaXuw(an0a7>-y$tEv!)#X^?ZKF;YVLMnvPpWr8|GHwCCsOe)we%M3Lhw z&A-fXvrs3I^9*nO=>ke^_kji1IaRp+)Rp-%ft;#U#4+p`j1c}u`E(tuhE?1n{W z=`%+EN1^f5H8%zH;eV!5tZ)CD^&$Vv`sX)IUmRasuDYa(MlgRE@3MJ(i}^EoSJWQ& z(yQMuC%w8+S_fUvKD$Z3`@%!Rx`~vPd2LnY$!WKh;f)KjAY#|6{Es!FcQNV>`@bbW z$h52hyve?WEAw)vx%FRsS@`Mfq1v!pq%@hK_TzvJ3Hwzp#NAJP%1ZsFoQC^OqLS@F z9?4qebEtlpDr-dmM0{h&$MdD2|EGM?`A@w_9sqG9JTtNj_($q*5%kEfSHoU^9k%`P68}!4nAZ}}iqzNS9^pB51}9tabY$uSd-4ty zi?$9eeXlyn`dB2Uye~2Oxuq-9Amp8CT7{41=YK3LelJZ`G~@Tu@imdym`g8(J2wG5N0IXERh62tg4! zKS1niFfozCf~$Z&0DeznX2+-rJf-r7 zL}5(4r7it!YP~FaMD{AJVNe>G-7^EjR(2*ThO)t@-iqA(kv*fir$bRblNVn@rZd9{ z-UNs|;Ej3@i$AR%uob8;pbJPVml?>fkcVEJ#YH?I7ddV=k=PHM9<5gK9Q;5S)-Tdo6x>+iDp5gd&c3Py^9hsr_*!6gjY z!j{E;z6Pcudkd@K(}-&q!MbClWLD(<8K3yL>_gGhme)fyFG>8@?Dl>{_9kx}aI&|C zKLGcl$=sDJhS_1P*X8G;fI%A)Xe zbfx{rn2B}re~zu;3;O?QReuYcH;yOVx^c(rJ8{kLHA6vb3sfHyOzm$$x91#jJx_dk z?if)sT@k57WLj9NQDM@{kIPE1rMqk~ixvzyXHj(Kb|S4U^iisKxdFPJjej)iKrN=E zZR?8m^*WxE*6EPRiA~C9@3`>!g2#>bCp7WLh7AAc|1ptyV$#v4`1Qx(hE*5;Tz07Q zx6fpz!rm`O-*83$A#O^!7w;l>#e4704~SQ++d%sdp7Gv$WAXSEk3E=!>f4-i2(V6G z=gx}<8$QRwNaZ6u`;b5i=27$dhW&=dJM4DA+36Fq)0R!px@xAIVsrc@GGY%VV=Lq7 zo!$QKrc+7+!Wha`8f|e!F_F2v>D>oWO7rz&%kPEdGv%kl{stoLEyLQOe1P>mJI>Az z2b-bC?zP7{7<)18$Js$Ghj_&$6P-6d4<4k=gv5lT2Z}vS12jm33`+OPT;z<^Kz)ua zvs&keY*ojB*`g7TR;eHkZ{q1TCmis;6S^S}>3zgBX(Sj~^zq0NUKDx>-E3FY9*4h{#)VtOr~vf7CIf!G5@`7FZu* zp)qP3#`>t4$(3c2!ZU%9^2Y-n{XA~sTM2MgPCkPUA@<=G_D#Ur2}%I!4{XC9*t|`d zd1m@FHD}BxAky92;);cOP&s5Hb_vC3wDDFP5$_^Gyn_5d$*7RUHTb*9T|=!x;mO~x z1l5A4JhE3{DLb%SnofG{pvK=-CG%Ch{;4c|S~%i?KZ3H`Y)*O=N4Up7x0uS$3e98Y z7YGLKGM)h_e2F$BrKQ>>9&2m)1NC+tr>;(Ci6RIVygiy=N-Y}@xx>S;z3`JFKO8IM za<=dpk6;E_&g4UbW7UdHDR>=(wctO5KQ+NLe}KK z9)DOYpagN)1~w@BXf_i>q?2^ay*GUdU-wd@KF9Ey&LzFQe_qB1Kj)R{E6zR|&nP*+ zM4LC{QKBAbHlMhY5j*~F=a3XDfLgl&U7O8Wtx5fIhy9wJANGShmd}%xNM+CyKU>NG zakxjBY0@QEYx1t*?Vh52zkw~9by++C4su4;p{DCTtYYR>YZu%PtM1#@f{`Bf(LP4O zfqQ(Vf-Us{aPn;^`;DwDaV950{n1)e(jyM@_O(g*?^1Xa&Y4~RB+)OXfHL7z8G
aL*C)gj%5A~2iDI`{OF~iI=>Nvz;X;B8*mq`udAp1d^dK+r`>U<6e>|GoU-tyeJeElyCNs^dR7x8Z!@g z2)EO_oNv1nQ7qbP00&h`OhhYbTKyw-)1oidUdP{(=Whr@C=ScnsrV5FWQ|oj-^T4p zP3o&Dn=(xU{%@{M_i#A5EKC1G$+J)<)IXhR)J>M92a_YS@k@0?(wc09^S>>h^84SM zVl@)v#;VA*O^@B9BidH)*w2X1ym@?WU5wu8l0BJvt1)+v#Z2ThdHnHJGX{J^;mtb~ z-|X@jNTaniJ0-=@+6E;15J1hy+iN7BzOR!fr6{Ac72z|{`4Nb#LODD_e8H>NwlmbJ zwn?SXXtz~VT9M(lZy4i}*Wu^?I>3%O`(f>;{i;XLrk(Um&Zk2%{~9s0z~64SF!?oQ zd`wh)B3AW;x~$g3zev9CgmdZN$%_4^|J_-Qdf@)H1myFGY(2`M6Q)nARehy<)h`SF z_)A|y`5p4oEOr<<>h!!cI>T#Sn*o_s=yWU0K7wATE@k=|A;?uBJ3s6s=_^ID$Ef8|Rmz>Q86u)bgRmap7u?~>|2%-G#>@itMh5Wm`{T_G5 zsGn4dED;B=5_{ror`|=n8iT4d1`aWjNHud|HP~)HR)|FH1FQ9`pDzDNhPCvC5Du7C){FqAtS^EJP?1<8irkqIeDwNo$?K_ zIAczhN;#j0%p$8`sbbo&fv!Ji$R3P|lDRx-;7%j_wm@E?A7Es)RgATzf*@xXJfO{J z<(EDV`hYR4csJ(FP?*rlJaIOG7D%cv=#vV%lC5wBzvskFf>3uyuFMzyfQc@!1|lwx zpH`94HQRdB=t~@w<&6eYF>b7gDR((FVn^PE9f6?~U*mZ64n|^VH&$d50#WKzpr)eY zWj-nshSOmUiq5DZ>aBR%?s~GK5qj24jn{D{ud2q+hs=tJJc-|HMvkzhkftSOf1nA~ z%zwiZ)ga&hH~wRHG;Mfzy4&O?#&8E?{X){-Jr)Be4I{Q^Y=7s;0IpuTxNG50;F~@9 zYfsl`ev<9YJaWRjZE!I%qBm$4TYJCX$_1OH%zZkUayk6(AXiYZ@!sKj0MsK!l;mB> zyW4jQH{Bi{_vThgR^x@Z{X6;1Pa++zzHZ7%>yFx=ch>K~S$yuG*o=cn1Q)L?_{{bbhk33n{ONmX-sX^ zYkQDA{sr_qU*ch=>&XeR-vmG65qO+hcju((&^E#+=6isD#fRL)>6Qb;f zT+0*VsX(KL7+t{6C|oPs!>HyV3q&oUiYGFd^Qgf0Wp5Lm&&FsFX_&7rx0nHVnTo^- z2@URA{a)98{vKuEd{sZT)6Pf$hqQ~_up(_SxhE`JAop{TTrv)VYpA%^H9)#KdOVr? z3ws7)NQzJ+FnKb;5@P)>^o)0o^1H|^^i#eG$)U#X0OAI8ANSkvKvm#? zh8{cAol)6rkR}aruwN|AHUDBK5n97sLjHvOSSmAKY~EDLg!u(MmbDiT{P@QSwJk0& zkgZ#{aBi+bfF2bhV?@$oxlSq1lfm5p#@H)10YB2>b)T!@<|#au$zOt(EU3LhuIvZT=ZCrD)(0YfZ#D?@5AT{xAT(hYU9b6n z0@zmQ`s*)Ieftc9hz!wqLwDdXI#+4j-YfJ)Bc%WJTl@c^KY%AYf8rVmdu$7T3o=(5 zfKQkBcpSPn=+LPyH(ckJNz_ENy|!A~kcT)^c2AYAjF!5Js#_}cFopDk`pU+j$8y+{XMu?_PyBow>Ibn=%wxW70mPTSFVa} z@0jY%2ccsLlt}lwl_|4n4TKVZJ=j+4g(T}1M^^ZTb-wL4%DV)yD}CqErZpSlUNTg| znpJWZZa`5+iH~k$Ze9gWWdgllB^L881@f-gv}l=Oo`;_?W$iTk6PGUju4fmMsoe&+ zbJF_boZhCcFNDZPW9dQkzhYY>`YTfG+;9_uy4V>GZbvNP(7(C|altTR_f5RAV zi;_;8F$w^^RpKQMjm+?EsCWit>o`i*g#}@Y{WQ3ON?R9$<1?1jG+B51P-*n?*lCyd zsk*i9h|x+2m?M_v5cwCG3zWJD#p^!um9}}6FEwR*GZ%8%YBOb_7=^~9>`E}UQ|a;A zlBB}9&g?5_zy~sC%HabDlcGfF>yi6&tyPep%cKd}*2V{YjL~9Sh#)!PT3X1^qp)ms zaT^-v06r%BV*)55H!T%`CZ4E>rk46C-8C@+hc88p+RCm<{Z!Fk*37$_bJyq5BN*?v z(gt!OMgw&~QI$?5k}Wa@PTX^0^DD7iKM0LmN^YAvv9ty?1~(JXD~=}F0lGhNfyW@U zsT#qh*RimlS{cv%2PRQvDFTknOTA5cUQ=Ji@oyVows~d%A(#D*tlh zUUXr_2VCar^k6z+t*+Q+<-BX4DDy6Y7c%Mpd7cvgPgQGrGkSVk_ePXz&6<^@=R1cn z`?`&-4*WQI8hrlN+TIC6_pL{-bZey-=w6Gur2dWvDj5QhFY5JQO!#HjmbBL4d#*B4 zgrp~~dJ+pmUDlfK_r#5d4|G9>9x!&|j-0JY%aDCk* z&}}(h)paV1*pG9lxs7tG6= zlNEx^8mi@zZbVhdGSZQG28C2-G9Bevvd|iQPeGP#!L`HpoBWH_zSCEFUPHA*E0dr*J_5q#*!>d4=_g{o}b$ znRfl8VzFw4rUk4~ioF`+L+)i+aqLjH=NhOZ;;EIEgH)^EtO;zqUUD8LNs7L4j2Up`LYg;Yl*cz7>D_Q?-N{;Oz#Zu+0Mg7?D4^NF`A zR}s^+){Jr27Vyq*UQ2G_teuku>vgwjo%f&nk)LoQswice{qa8OuQ$?zh^yt0!i#_Z z>QRy>r2UBZ6`Hmi-kn|Rd3DXq)qBO;!JLq{dfl4S&j3YFKbM9wGyENiVN9kPlUDRm zmb$~iCr4Y;aM#02>At;JlHkoX_M{xkDW{f?p1Ifq*V`a(pdRQ+>TkoUng>&oC=j}= zzg%B@Xzs!2|E8&z*@v=e+5F}M5*SE;03l1p)*L*Fbn>Cj5*qx1Ql#IA zp2DT3n7T*ZUN$kC7l#NT6=bD#crWe;hw<=w5T~vIyURTx->VoFV8!_OMn$sEeK2DG z>)1q2nzO;26D8o&N8{{}z20*pB$XlTgWY&}o$dWDaa()ZbY^yLg%jz1oLKoA@HBAC zP2t-r$W@ae5P~JTcT|v?fXv3#G41yu;wywLVK?~CW*Mi6OFB*s#4|*Z=glX}H}jW^ zD)b(e0&2}O0YKfcJ`HIBVq^G1@@)c5oOlKtNfml7?Ty68Ruwi7Wf#}>%zrbXUDm;t zuKbeiD=OI03%^fr~j*#Ipvb0w+7Afy_dI&)6@MKW^`?`)~>$ zCZkXL_4Fk5;I?fUBo7PD#QGjVi}0A^bB8|e`of9^mp&+PZ!C(hh_vILuYCG1N zy3mqu*m{Znb2n&CZK@_?<<=8BEnQkwf0|OvNj_RD z3-cYa$;y8_!O!*eSNqIV|ixUPKs=*=>luRQ_ zL5!c34`3U@OVmNqyF+B#S5X3VMutJHY|C4czD3y#U#Qq+NeostT?(vHY25RiYl9$2 z8WLot_2$MZb-QA)iCD$&D3KS8Q(lM8yB0=h@{jlV`$Ge{fIm=!UnU%rv5Y5z@OuspkN4wy9BfNR4h;fwLoHZ>Hd&hNeL-?pF}vslR!~ph_f-*kbSchP58dBW?oORT zD{?k}yoTppakRUWA#cZ`#8 zUhOV28IXM1%lbsCHI#f;$b&7@z}(f3`gEpr_PZL*)13U?zGUfA&?rPniith0%4e4*UkJs{X(8KOy#itc;Ry)ja#xhr@UN zrTx=?Q_80G%m#hz+Qx8~%Sxj4<7u6bF52g{Z`r3Ut^ZrKXNvl^ob&V^_9QU2fbjGY zRrtynJt5eh2ZpCtodN*Ci#(+jiUuxgLdV%CM0U!+)5z^2+E8^mz^oD6;k3tewS&r1 z=?CkSrj)IoJz$Sx!u#VY3>N_1(3D!U5R)9#UQb@8{80mK!|=L=PAt%n?9|l1hm7#A z**ja!?EW8DZ{n47{>A^dJB_6+Q&uk2lv!DknJWUBO{SLAv{-IbnpkL7xU*$ej=5l( zxr=FOjSDI+sVtf1uDIj^E|?3rpoky}2>kfW%=h;_=ldUU4)1$j_ul7yKAu)rFr^*@ zdDr<%okEIv6B#}%guA)!KYV2OQH`UVD+G-xdyjKiVtKelSAw5o8L0EbZ^TQ^7yTCV z9u?+?o+eE?d5@RA5C7kn5b1AbcGciXU3ok*(qnZ!bM>j{(%XRM%PtE0? zcUf&nxRD;z_A+n9s%8wI!S>KeC2R8`t=do5=+nKovOr?CNZg{+z}FdU3`!E90SYZ%%hFp`e6o#rYAuWpC=W7iZx9{wkUg(j zR$I8NBx<57u|@2|Z0Lrw%4dKITB1y?zPFtiQ$*{=_MPP z^B?OK#o}2Vp?aGTA0a%BRUg-TmZa&Rv-;>OlY@ryzpQS7|@9?EiNKY^D- z8MU;_aQrw;?5owWBF$WY*nQk^;M#o!o&SC$f^uJ=X4%)^M?@;gcOraS}5O=CqhS~WlwV^Q+$C$ZrN z&efopLqaq;l}hleM0)Uj!9C9G)W`Rky(s5XX+~V9?$$-Ny_H_@1tBb`Ik5z4%IV0yNmMcifX7Ce6HvP2J2A(4N9dF4!X13(;=O3=eEn8 zOC1I375W%EmPo|Fn^4Da^& zQAGoCw4){O&?EZUI;4(s^K+xZt@e&trfB!8V}dBHExh9vYq7md@WmsCrFSsG?U;E% z&|_WtDd+_@#+*LpI1hN4q}Kz98$RZeum~>@{woR22}1Q&Hw9Vk&6JFV>8A0L%Dx+A z&Vq%B4K^ zKKlC$uKJV;eb^8=mi5fb=M=6XlfK(CFF|aMr$1A0zWZU-2Hul*4m?_NAr6pNF3ZZ+ zYX`lnpB=-XeTxEcnvjYSxy+`*m{OvI`OEG_TLj@o$2pDcV@_-orSUl=w7#e6Fp4m} zUfOZ6=}I4fF4gTOtj;9tp2uhwA=CzzonKV}kObO5|135nLeqm)SEp90r918GE{mWE zi*TxZhi5ZPN4zh#ftUW6uWo_nDZUQi#_-&D8NP^LB2(JTnn8%o4b0!%(6X!a6LjeH z3kTP;4hC3FQB#l_!oYzbk*5v$nH4R)5M|_hHR`rElfXQdKl+*|}MGOl!pKcnq zoM(3w`4%Ec`w+@};#1sT7_RN(26`CgbXuD@u`hX*nc7Qskv)F|`!O9oB4wU$&g5A_ z*Z8@xm0nAJVPN)%gVYzhEK`?zWAXxg*n=gJipzr(&*I1cvpz_UA0SjoK*_&C^BDmb zxNym73nZNYO2zhQmnFJ%$Z~L}m)_jfO{3x0?M}w|Yw72+^X?Ky)TI(+BBlnSk#sL@W_Q zJ^T9}u6F0iTC8m4^C|zxj+zR`|F&s#4N{UeA`ZCXrb>fx>U32`!lOaqW9w#3=D*r| z67D!(x#VTHZffV5G#I_!_TB+O+?F}d2g-L&&3_Bxvr{hG6;C~k#$i3f){N+=I%${V zRh;c#wbLB^dk^>QDa+VD&pvNJuMZz-fZui7$-HM>dUdnUjdRz(WqCTpm0>mk%{nw| z`>_&)(S601c~AM(l`M7HYSSzHx{QDKXns+W<6mZ#C!?1y@tKYy@^*XeqzMY0B%Il zDT%?1nRp-m`4gw1t^|X3r}3pgqiMA%Epz()`wPQ!G1y`4_df(3gwgvoD!- ztUxx5A@Qobuo6P6EaLY9Uv2>8D_?1H`4t2;<&>u$ilCTgwAnUvSOjJ0U{|WuMG=Jz z#hxf)ffzfVQ;jV_%rMX0rb;GiL0UMxRWxD_Py<4Vw`mL}q`*|!cmB7yJ&*u*?nx_n_J*l>>PlO=U=2H^fVJwjojM z)<#VqH6yE7Myy;qbYI?}ShDQr4+}-u4l8oFIrfW-$Wd4!)p#?KuLr!^^X?P6Gp>o4&eTi5yOS9vcvn0D&xy{|9SIuIY1 zp+ik*++kwXz@M0xyKGn|v8yvMI-eKy=U151W(~c+@Qjk3P+@1lVP}z<>DxVRQu{N< zV1visj&7(h{Cv07a3FZB)PTM#cL;=OFuT8MxX}HPnBMVd#wl$~vU6(npW|Abc7cqo z;@a;X5@6JjtAgY6-|qo`0n5lud@#bHRgjWH+p6;M4LvKOD}FfXUp>#kf94`p-aRjw zMj`$ihU`d0YA>o+J4N`AemnyFaFLB|H{PxFdV7>UO!3Fg!J+SOW5Vz47X|YhFfS*r z)7Mc4MA4+1*oM2ooPExXiMto_JWz3{AI!gEgfaI?3HaVdi9xG-)bjVGd!cBg6}oXy zO@|gvlGjIhVXz=r2!5)ao@$_ws#G3k<~S)?@hO93EnvPURz_) zG8f-Znf|Tp?))|Bxe$G2Exy-y4}$R4r?q1W1>jQV9-vZ*9fjqt14I6w9=Qi+G=^Nz z9IRY!zw7HwdLpcZaR&~JPwwpHKeiZbC0Y&=GbB3!!FY#THp^Y_*MrIc-l|upvf}bG z{D?O^`m^72a8Vimj&z!EhfgY#I8GdtCjlhumDKK))3-54*^XwbQ?dg2a>YlmRmT}+ zZI5|{=QZCuAX?$j>1EBDLuP3`X6(L*S8VgAV@@4}3ID$NOJ!ya-6t~2Re4hKg^BzO zwbkIVaIqDjFRvaACJ%%BP2c$lXJ(^k&7iXPL7M~y##Q#H6X>8#l9O!+9rElXKXYCDFcOTtcJuUtNl}%VuYr^QA>xR> ziMRgMJ27_;Zw97UxSH>by-zf*3h7n3O+7y*5vUtd%zYut{N=AmKR=EvT0yFJ$n*Jy zS+=NI@$;XCZD0k=ANEu_OGtu7;ehe5@dyeY{r*LNRF_aPA_NrPvOfCiNX4f^w#3t; z%DrdQl2K#Ep@P@Rh6Tx!(N1Gm594Q2hgj5Y1cOkI9Fs>gPkiAjuR&nxSJ%6&B=^ML zrFQHm#cgy8&BiK*niF*}4`T^SE2C+m4{Wj$dx%c}(w>Y}!2$OiE(rMl)gD2&gDX55!9L$p#~g13N09 z;Q^J4YNZ-gqTKbv%(ShY%w1sR#h}@5Ic&WLtz84mU|C*a!HJ}L(h#6(GFDdU5(9?> zO!eZPOG^1=hI+oHW}5KdBZej_l_+|&iH5WKV1;;9-Z#9u@oRLcU7`hcprhs|!Enjcj{;npi#yx^Ff>lU_eQUBoZ>)VOV$-UNVNYtHiLFb&u za{UZ$$zbTjuXb1dcDQ99KXvSiTELm5_|)P?-V25+r(Z+bZm^PP?9!>lz68md@Y3Jv zbIAIaaz_0<{aud_1Jt{^28zyq^z>33W_%w(vGsf?JY!$UUOkt8R^))!OPA!e88YPj zB%X5;?!ickP&usy)YY9kMcG#dQFw4A0ReKKyQfVV+pshi@z_^O4XgG2Y73|{JhRt; z3X$G?CH-kkZF-Lfx)zdxKLxah&K(6}zkRr@yFc}GNG*kF4)&70mcE@f4{-4EO~wQz zd;Fb~hG-lPIO=O30!)!D;q$=zSeAs+^yvx*` z4&G2E4#>t>gO%MU4c20((vLJbsD-wfz z$9eip&WEIOvSvnC0ir#mEw4SdP@RaYJ}0}TdMYT(O2k@zQen z3{Oqw4K-kK#pX0dXUggp8;%-uUm1VYa^B@j(cEi8O>AKjmQY?o1ed6_#;QS6skbe4 zS62_Fjh91N;tK%46|SKS`%;re#CK*wuIo10i5cH0L88q{d-U!hw0a zEvS|`hiS;OYDjHNZ?|Tc^nsr=(4|hppghk_r5YB~=NkSFa+-n`-{&K8s@`E?pz(f^ z=4B|gZ$;pvTB$YtJ5<;F2cyC3{dP(Hq5eL@v%8}|}_PUbYttPt5KQ*TqO}Z7BDlULLfUhk6 z`=hW6IiR4CR=B{eWb7?*RFhO?r5(#PwaDaW%BgEa-(XDCFbV?Mru~=Jg6mb@g4-eE zsvyz+O(|b;YNM|mvynI8Oo^u2w{lkOH+#PioXwOsr-?5HTJ~uKkHJQUDJV$wOIE_N zMuVvVI6lt}`)v>Ijo&5gL&F}>55l8Nd*Of@tv8c$uW7&I^$XCJm3^`>GuQFUotakb z+8gur={6~P?LD{j<*$|yd zECiorRwLi?u3$pPJN7I>+S8mqeRnG;Xt2tyqG_bhH@bwGXB=TWER}xxvb?Ygr$+cq znK@M))IJf%%zWeYs7jtS6u?cI@KiRyuvys8x+DR}X&B%bQ`hJ&l2bGyRm24)pLMfen$D{2`wYUvW4&) z^Z{1tpnAm&b));DIATR^qc=;@^;q#&q-k&v2(CkhtCe?O+pC7}Y>SUT$oSce`8haZ zi;^>pA9EYlSxI-nH2f^jY?yX(dYG@x9x1Ez3{X3yrHMoJT+VQ8zXljQ+BJUL6zcPx z*koh8=^bH`%pEB(o^3OnYd4Q*-VYs2M#LCzf+H03br$}b>9V2>5~)NjX4pAs*2V#j zTvO3>n0c?=x?>s|#P}z?GI$}V{y(|q)^Az3-Ji16{T(*^I^wiV{yll)+J)_^W?N)D z<@oAZXtQPTuOEWe=}QKHzXx`gD~Ccie-!8PH~h(Vyf*?o)pX3_^(Ig=)1yh1RKFmD zExyT*CdTTo3ofwD06(w)T5Z4I(CPWw_^2z{#$h+djNhD4oA*(S9&{HU+go#w6}NobMUSEwwhct_Z>8lvQ51UFVy4h~Xh1rXuPjRUjX)aBBMs^OU#`_C zdh(#rRdqqZ`$GhpR8nxE@S7|?p^f$ZaUKQpPCoY%Ttb|Cqc8~^+T1X>p5jBDXjj+- zqTjkoo}CtT6SqjL&sa2e*p2`ixaJ}iZfUR?{ar`4D;LOR^sook=dykv_=EHO1)d{7VHW<+d(Mb#bPz zr16chiU{m$)MPUgfFOiwne%x3Qz_jw{);G5z5EvxX?ElexncO_%u22=zjObg(J-e z2pz3OdB8juDb)uj%1@~DUhPZaZ5e+e)~v=^P9q#Vn&gj1K*~F=e_aTqWC2qblL_!R zU*AI8Do%x-x#)r7<9gPCx&af0Ih4*}{v7Pi{aZ5$-#;$nv&D$jL>H~o4WxwHQA=XY-QJDh_)Ztyr)x;~zO>^>bI z5eagEuIRg))*OD;)9|xwDdV4HpWp@Az2V->a4uCI`Z=&FX_nqi!UoBMf(7VJ!Mk-( zp|R+`WlUZaH?*V$BOXr!nuZ(QUBtg)tk4a^-J$E`QCEw+eeD->A$=Yh_kQ=Ls_btK z*Zp)S-orrcb3OQ+H%83TTL~u2(C5d$Bk~$3d5hhvfxAxXQj+hr5Wxk>g^tvam z|KZgiKx?Gl;bkY_tBl*Mb0tj&Y-m~Tkj@dON79ZHYxw6wu{usz8|8W74doV3*pTGZ zkYwOIZucT|86VuD~?^>}C0}Nrekc2a69n zeudmywx~<8LO~vk1sI=*@JzmTa>gUmv>J1jij%55tA58T`Ey${&g!OCLT0aD@WU5| z7Z9oz6pz{Ik~WqBQWQ;w@08*;b=Xf?jnrb|=+~jkdssP}%ch+0K9|OG+$QnKsF^=y z_BG;injL6n`nPv}I;i*Kl`xXH?F51Lk*k#B3u)hjRxp6D@mJ9&^IstdnBvvgmY z_X-$)>q(c41ck-7-5=~BOg)2!OmPmHr3E-02asWLfS?A=l)@6Mvz2%=Y%HJoJs>{hd%)1HAdjLWdXiu7C5yFoBjUDPqO%J?WVa_C-jQ?UqEZj z?T{GjI-Uv_m3dT_FL0t6YPj`Vc7!6)g+GsJwiv`JFlO))gN_e-;1BRWm;v8$wmx9~ z^L`8$yAXvQ>&&4ZL~u10-)2BxNJp0B+J6bR__%Q*gbRvi8Y0JKP@Hy=Xc{Kz-qlmd zvAEVD`yKB=j4U@3hw*=d!Fm5Hl4gDGz%|sjAI8Hjd4ICY#)ne{aWC1SEk=UD{PI{2 zcMPjxyoUASxbRr>mG}dIjaCp=xl(dbXe~1qHjB0t{?v#m*^N6F>w4=pgu=zkcF2=_ zGd`xQx8_dOOwp1NM$lwm)LN*;DXba`Zd$WGgN#p>H^hf?P5KFO?$;QPZRxjret@Y{ zci0@urM$Fi+6}#@hp{mr-oq`o#T_^?&L)y`azM5!hxT`9QM8$~5_SqtEXE3{?2kO? zeMqC4cs}|hNOv;3r1`zfx&I07?L?7Di7t*SnQ)Pmi?4F&efOg+rY77u;~fs%`s&1q z=M_diJ!<$>AA192xyE>J%tsjFRYtS7&*}0(gzxHv$?mPHZNOfnhSdUXrzuQGHgzFc8%WY9|`Er z0q}4^2nj87LO<`*>HAzr80lQmA4CHo@pRoUXs>_C9dyJ0P->0iC+}pGIgMgAaW{@a zrBf@`7tEjY6A%5u(hTuTyz~oYDRJuJ$-t+TJ3s9(nA-SV@k}9@yoUAj=4B^d!*-7rMiA!f1oiIUV{H#5m?}$I^T6>I5uiC0vT{FFfK$g$n+rPSG zRv`#pSpL&I^y&Vpvm*s&%O4nuNby;?@NYPG<#wAz?ogz6f>t+p)UM$N0T_AWuC(`U zU7*Ah9W-3`64`dU<_md`;#X_}@VrAuBBGnL^4f0(lNHdmM3u%6LpK=>SsZ427@FR% z<2Aox*<&VF#~y9da-SzS$)*k_ML%6@(F{r&zz2R&1;@${=!5^pPcSh~6PjsC5AAr{ zyxW?R0g>_jCemWpOy}N?qMZP71B8|EH0f>)@%z46$o%@261wO^M0aYT^#knmu#|Z< zGDy5PCo?9x5;jx#xqP%WqR4bJQw96^urnjg<^g*m30ro(F^M?(fY6<&=$dD(!dn#vT?BQMn4%=XBhQLh~yn#ImH8UNBBZLbPCY)Og#o7WODlQhY#dg3h(zc2*p~!zZld<<{=d>MA zp3yJYd!U@92ceaJ?C`y!<}V~akhA(eT-Nl(Ox!Ya#yyg^#$u+9bgjiQ%6(%lz>uk? z?jE4ZpJh}jQUg7%iiKLSR7PyUsJzoQ@5+;*Xs&~_?~6yYMQL5d_MmyiT%|o$H-5WR$bTSjoGuJ|? zVYHUS4fY#EYIEK>kFcZ-uP!s+fk*ExgK8iv`+9KdJamMQUMBn8KMWG~E)tqap8u-L z&~+boR4FB|`pttVHOgR(<*^$>C93HJ#S#uV(A{^;IH^5>mDsB|Cwq6cnct0#;uHTU z&Bt$)el=7Sj~MHHhFjeK+>l}Y8HKbZDz7h(RV81;d_JFsyWlAM7K>75fmfg1Yu{YrHFY2TWjw`0 zHQyGg?%xggqtqEl|N26Keo)Kij)kjUvpj~EPm*q)9B!%O!JmI+C+iHF$)FD!E>3I# zpk5FFwbPw?jG=q{fM7!8a);T-_(-W?_!Eia6W@!eS4b_%=i!=5{7 z3>sOhnO3GTTNDck`O%*lm`e}$muqn3=7R`mTDM1GB6V>vJmL|@Ws*tIS_~Jf5vxtc zDhV@vzQk6$F4?C-(Ma9OYHXVv;)#C-4^5SIs%4yLX5>zI*`7HqcB{aj@+j;L?Fils z#}Vk|IfVhKFe|Q4Nn`OY8mAdP4dbeuI%J=_ya$!kT;;8R*)CH(vE{NK!c`S{pIwSLg34%_mr&w~?4r6wfwSRQt& zFeBq#2Wnoh`b!Wa^54-psNuh9KH$jXT~kH-UG793KDB${*AImK&R>r|#_7Yx>&BhJ z{1%;xF^9dL2cK^G)2veZYZIaBttzK>&m7wvXcy0$+WFSu-PDb9hyIGl_`%bh06j@K zM1ywZ*gfV%{gpED)9{HA;l)>$gZr^*O8nYDL!&E6{?YY0M)~bDpBBBxxGPPWaOPrd zf3So#jZpV-4NXL7SfgiN7s{l>93Gt}Q=aw)%u zWC~c#sjCTj(hX7sR`p@!MbGqYGIrb^;oT1a9zqoz)IQ_2=-T)P-DdG{=`vz`JgqEJ zJf(rkT-XafWCqT4FEsJ2d0^v_OZiN=Rhpz2yC%r}(*=;px%8+BKiGKN59W73V;Ab? zP5NS+_-&AZ@dz+Ets+NuiUv(t_+wv8#y!&dkXz>l^R2L6 z&5M`JF-Kig=#os{<3CKlt@q}6`=Hl8wf!_qt5gF_1LWEAVPDCt!gyh^U%qw;4~Gce z_$kktyX8V@i!DzN6bG@b5huNETeY5DRvUQLo|i#em*&+d{($`qbCFy2tAQal(vEV> ztG<=J11}jc?LRya;+wXBimV#2AHJY{~2L+?{w=s>3Vr*b142dHlp^H<B*a>70;keX)r0Lqc z6cQ0EPM5!|TP6}1MW_yzkb+FJW#{tQU;1x$6W#4m$(jJPzp1FU6!loI2ol`^C7iB_ zOMw^QJRCDs&2PjdVM>iWE3c%L*n!HrtPmYV{oFX~F4bEs0I*vl9Pt`KjFZ9eY3`-6cpuIBkt&dI5pc!Q%dyrErm z;5{;a-EI7tFidl^<5&A&sjp~Rxp7dG;j?)nfgZkkqA}RlE_Db0lJf>7nHImcx%EXr zZA$d$?Ft+6Bhw~5{kQOeh1%tXQV-zi`N#ds1B(Aip$gyPd6D~k=95>5$3WRRk$cN) zXz1Qw-G32}?O3=xs>w<)kfxI?vQ@M(r>bkFu9FdC31fs^;eWyE^=&O=B#$(+LmnNU z+cH(w{L6zIO}DZV=tl5z1MuE{Y;^_c%#z_u8mg=)@&UPT&>UiX{}2fOToO;!;z?NP zN4ldl4U<7YzE?gR<-(qli161gbHbg(XwV>4}vcr!JnaJLxkPanv;3WwFeFK z57HeVkjdORXwUFS_x-|NMVS+~3LU1)YPBQzWrDv{Xx88s2;}zMuee@PGCD~&ac7~; zaB?}}?u=mXl#EJ2e&4Fk9`5fO0BEly%C-uWA(DtCm;CZuMB_UURR08rtnqD+gtIN2LZ^*YZoFLb6VbB(gS|+_>U90E z@y~x1`i%efVgFO;3!X{0Jl^=t@E2RdyO!(xYX!fKcHy?I&?eSZHSe$@Hm9yhvxGcL!Gn_K6K{FA{qXW2POYeAug>= zxwS@Df8C6}n&E*s%G;*m-jvR^3D2%V;)zkoGez21I0?HED3>NH{;QS~3!$5W`!bE9 zxPCwYn666IVjuz;PbM)TM^08{tJJZTF@w`-+MTm$a}C$kgiB-FQ=v4^q4yzmCXNrN zKP|<_5R3UR^kuhh*=rHqW;SE?kT4d}eW%42QwFNKG88mPwA$Icxt})E0E5hNejQ_M ze&QwEm!M0kh$zRaJ%q7_2DR$bowC?5DP^GgpsbMTT+H;77WkZy_qp=bF26`T%&l|A zj|$*e-Y1o?8dU!}4dcnOfEN_vV+@wlN=70;6Uj-JP&~?A{6Oc3h53UjhT7>a%P_|S#B`DODftiSVOCU2lAO0TO(ggjEH!KK$W>)5 zPC3Ft^E@m+1L^N~y2UUGr971BL)CytWQ=uiY9Qj~nw41(V;q*lrz4s$Y7G+Em6 zJLy)z-1jmw*RG1TO6VGJ*^=9mQ;|vKh~YrP?bNx*9zIi`h1d}ri0y$s#BYQo>gJsw zmEAUguAWO`JRUJ(zcRtU%#SJULELfDcYE7z^UiU%v zd7QL#CJDc?dnKFj4M+-P_RmT^UuSol)2_*~nLLW<(##a)@R4m-yK7TL`Ri%^gh%j&Fq7kS%LbSHr4z(MLeb|M z?$>{&mf+(5TOgbNG+*~{t>D*s{h!ZA4vy~L=5S=gq~R%ugzx!E^XYrdB*gFf#fM4H zs1xVt68)X-$1cW7H{ZSA{JQ%5Ljzbmu^8^f`;bQ*QIbp$b}vIVNGC?G0!y;Bj=M4H z&#k-CopUJv(3s8dzgz6JYyLZ__+mkGTT!0dywCC|cVV%_CoLn7TK56`Z-^Z}q@ZTV zxR0zAiy(2yhyb9x&$x=acy&gTse8fo_GWWTaE~FU!t~L5eb-=6LN-2VYl8Hw?evVr0ayd0}s*IW!I`aK=V zCY`$f29_trOBnCh58p&fcgZ^xnx_wAHvGV^Xn~q^?+!|R$MXx{GL37(pIp)SyNuXO z#@Ar@pPzW%)(UAJprom_*bUkQc(mW0<8<{U74fpEeGlQRoX9GCuR(|L!`S;C+;TZ| z`RD6=#tTC*pf$HV=W?hAhXMpoiT3jNL3az;wHX;%G*a+>i-`HYvc7Zu9t57#Y`Fo( z2I>;bem|T#D=Vg}Wwd7tBFigs{FuNrow@mVExJJZNsEe|S=_+FkH*CRvk7}#Wh<4YR(n*CFKIWMqY3Sq!}o2`cbd?y8Z&Up8fjaa3m z9K|fkekR)Q&jF=gs<;pOD4ri&Hf6cb((1-rcXO`sF$i_bpM`{>a=(a}yb^NLY{_vT7(tO?B&Ck}{j-x)G+P;nI^E@6pP3YxIVl_d9v!WAOUF`-#yFwdrPM?;`souWdWZ*@AW{vMr3+@7mR! zSN;)&JQ{ni)tz^&YaCeduprdq++r?o8|>-fLNViax1wb94Veb&(&-+9v^GHydH^!? zo*MFVXz=AK?%u*kv&@IqFa=+-5f3S64y2kC3dRba%%|dGYdYLOx9xA8PM@`DC_`49 z_j_anhPsST$=l8OyKDmS>8BGXTENoaY~PWm@%xj$yc1hxthwxdRhc_y^+B}@8vfZq zC#y*3^0WNNki6>^YJJoe-ut($8)UQd@|b(mN%C;Y_O?V#UCRRO4SM||d~DP>_JoS{ zI?vw6=$H}j*B*=r9$Sy5L%&F7y*ries^}T2kg-f$ablO@E{=f-PvVBaY;gi%Nsjm= z*vrPvI8_o_5BFItb6-F0f_%6TMkxkCQR7h!e)Rw@tmUPYm?gFt_4;K`~{SSBu_&)-p!LR;s z^XGT1AFo|9Yo&u(9D^4RF;$}?o#ENGl#F0>X zRwvx;_G$9fQu2D-Qac@*?XaeEs(WCEL3MH1i||MKAj8{7nOpU@_39sYcfNS2Kxuab zr-fM{`(#l0k7-A~BrN@N0IXOI9+qU*A*@QqqR7MQ&@w|S`hiUMo8r=Iy1wh??E4!u zRrW?E8HihQPrlg)$Hrdnk5d%h&kiW9JH|+!wI?Z}#G}N;EQ{&9k?QV#=Ygv_ACFh; zgoQ{7d}FAt4J5DwHmFl;-kZz^oe^SRA@RPm1*=;U=vBFt8ZdQ!SeKQrS?m<_W#O_# zdoQJnqtkWM3SBnsLVt42Yq4*@{RckVmJ+ld$+D?Z^#>0TgAZ&`qh0+HH-DoQSbYe| ze9_fUC>UQg#p?r3@F@3$y*IPnrUlPYS2I@auC24Y&cAe-m?~;%-U*noxRSG{5Qu9b8#9p>v!XUgA@@;qsj738p zFq+fl=wxK%1BsI9Z$k&q))eH|! z|6)6AaSDdJvjr|b8PPW3uh$gRk-pP|%CF6Tl*!>}u7H64XBq}NQXo%bmNXtL%Y=Ni zMyS7|U~b7bwG@Q|=SX`hyIIkB4nfZ=Ai`{GMAi;X(CA&8adL0Az!zOhn~MTJz<1zE zerN$zHY~;i}eppI9w^yKe}!?Ud!(KRNgE7 z!^T}qpy>!OFYp=sIT`<_d5E^MB!1nI>9B?~9nxtB07l>3a9Sli&c3la5?*nryndJc zWBT11HFg~k&HZyAiQ^hg+lp=%~TI9`od-qbTv^eN}903JRvm?bvL3#St?3HgRrV zT)1f1CYKZw`=!k&UBB3AhpxkP8cS3Nw`gn&^spI6z)>Bg(p{XFCW>fM&VBf7L3;y+ z5EG+hCO;AY1n(u$1`$>?m&|(_LaH2tckRMQWT2a_wLraM1&ZJVN~Cup#=P^O_jt-A zFO3p6_jO+$tb=+5j&4dCplg~kL63&s24C7iyfhLhqt zwHlv_S zg($`+{StAc`; zddO7U!R1MX)1E=4O#hYg7C%s2la4Pi8j&m z!4L6RD4w5^m#o^u8s07ECamYMkSqWzr#$d1InyT`urSqnA^07fAir(CJo&P&uT?KX zK4@5K<=1pe7Si%KHZ>3R;CSd6{j3LhjCfRAxyX|1D%7+5$RB$@{)NDwpZK@Y7}fjl zdq) zUM7F~PzlVJCw!M348b;sr5s7TzFFG493hckW4I8Nt^skLFH&w5*V>O3+&?_>zGBJV zn;S9QvpXm-bU_#_*?kFwe+A?z_x|_2BL&r5uoF0lp%syMm$v45=uI1ulp~}j5w5V0 z^W%;um)0fv#bzYSIr&>B+`B>{Hi6rSmue_e?*1JE`rbsWz%isbFMQ>qUE_nwdzRuK z^M9buU>g1ouO9dtSK(?E_&rKS9(H_*pO*%-UVeAG+dEOQ*vZF4dv@XiDGx&;TbBfTw78?V_Tqjzh zXZ++-yjFmy&}jUnVi@~0VqU8{!TP4c0kZFtFe$@Hq#Y$Q`>if_dQj>7I(pSC>kkGU z>BLDpOKh2m)8zJd{j}UPr73xc-o^?S&jmPL?-=43_^#?+O6et)H3JSa@>R#Z;KEjC zW{%ty5>U{ZNs`u*G~t2GdMwXLz!h+a=b#_Pr=8Y-;66a#uil%a(fm-S>1Z=5FFt`y zq8?%Uz>nEr?{fYgmW|IFX#EhbU6TIIK2TFe^VvoXaO<*~2`;#r(e{~r&bM0mOOGFE zau-v7uuY6;$|R?M$+>)pYdjRAYFXibDT~)?4-)5N{-~U)TTnivED}{a36Yi#5>pFefOqlR+qpncO*CIHEkH1z`25R>K~$wR=1Q zCGh++6@=*q9;$}#D)a$YoV+_*rTl$ENWKE%2S+-d{RzsbKKNt0_QD-n03rq~ z-QrX2gBwWJ+213LHqnAqClmDMuA#Fv-5%(Q+6gL?x58xJu08` zzdASRzix)E@#}M~4LsXzCob;(i*#0E@O&ak2k6pqzWk0`F|Z_V!mwE_^6iVl^Xk%1 zv;>0ujazmZG>flw1GIKlx$WJWxephgdpKfutZUv`#eX8Ze=IXzS3iXFqhpgO$^YV^ zcUZ4dw`@!JofpL7!EpZ1Nx1xQgHtf?AG{I%XaU+~byUI6-ya-l*x~Si zZ$2ldXY~eIm5&>BI<>vR(_hTP?$Gh-TjJj{%+VJw$jp}m=J^E%2i-*NawWpr5!Df5 z%?^N)0%>(ab;YZ=QTv+31mk5w(e!EA-%jo!4;cYd>YNsh;KN|>-?Q|V&$#c-T1qPh z{mFM$^JzapjcF(#m_Pp(L>aq?(nY0$nBq7LvemD`kJ~>;8dC*2tNAwZ&6MKrtK%$^ z8@!1$zp9?feRTXokP32iBJFY-gIY7PofKRRa0ZXh5KESV1a4JMy6$u1w`=u!2nEB{ z1q_x8iPl%pwwrf7Lw7dHk2zJgHB`32vx#+2bHRu3Z<>y1!n7Y*uWUvY|Jc=KpC=peh zEEV)@bT*b(tS+nhuX>A0A>;efh~p33S~|+b?sXLg*a2%k(}GW`+uz-`WGAGn!lc@)l##(Wv7{TC@$yZoR3g0APj zR5vcfW@^*7>8^+A<%SK+Y2v)Aigq519UW0*<7Eo z!h2zFk+5%7THgGpeMP7Jk!YL#lSd;f;`i8vZ^$mUw#!#>6DbQj1JMhpTY(vYnSq*w zxqm7P7#@IF-f_zU&Wh0r8?^w#H~o$7%A5aqXPep)12!YesO51#bkK=*o3HP+#Ok$~ zUHz51Lb)eKRQ5+P?zURM#&cu8|1nKE(RYlqL;Jo5rgwd&{96@!WJ$YPhR@nvqmQhl zHYpn8cVQV-aOa##BC2RcWQP-ELQa1hA`<@?=W{ak^~BY`OPyp^D)PnM)uEcI5l+oa z+@qhdyG0*8q!*Aw$MYjN^E!>jZ&sb6-P*8HA5`T@#e{6Z?&A)wj^}ak=csaQLG5aAQF2@JD=0^GjS~aDu zs^V{`gwoVAC`AUT`@{P}2AiPk$BTaKK(8I)DZ{A|U`BT`emNj)vs<1c3NX?%K@L}* zJ1LB?sDsHnU7zW2hqhO3oC5ikoyfWVI01XwR1nh9JJuTZocZ76Uf({14R2+?W6iF9=6pXGrnV<%Eb?UQ8r&`{N1NKzad)&1 zd=9I0oKFZf`K3wssN8WBM`iignmTc-Nm7(!ylF37u~;^t;)A85&xq8_quSZxM`upu zgfZyjK3IP`xa2Rk`IrlQ4BpaJjxK$4uFYVg->%snEx^kS1r0G08ZGKB3Khqk4#vgr zh0 zd3`H!;KL?MTfu7E$IfQT$AyOUWGBlL0pu@OYC!BRmA+Ga>MvxFhVPZSVk*D`(A*r(>4vvOWx(o6R}w>9>O|L z0`YhmO3}nh2ONOCr~D!0fA$-pYp(xEvnyhc9#d&=YHPea4QvlE(dNo%Am2xsTkn0f z+ss+(nOrITPmAxY^@hYhgEL!&nA`x(t8_4>mEWMKzfRjw58l`b6|irb7ioEMHEL&&(0bxgbRmVpkfWi8KI!e zaDtJ`R&n^D;s{B&%S?|ER$@bQ;H2;_ZbhcdeYT`k``(uS_+@}UR?^_ZIA2bXundIorM2*bk_! zF=BjmBePBiba%B9oQv79s1fo=w73;fu1)ZD5J8q@bQQp_>wfNqn$LgfGihwj7N@bj z7K{>G%1;Ra%OSzrWoDqsQtH!k6o{Q{9ax0=mH=ArVVZ9JI_}8mO)!VYU1XTNE#ECL zEt&=3cL6Po#-88}po9nUKJ0z%&oRU@`gxL;Hu{GJM1L0caQRXLvm|F~2{aMX73`umF*#!)uyf*gtoGZP zJX`DyUirIwmA^_ra%Tm~ZWzrah&>zB+2BV&zY~0Z3bdD)sa;&wcOkZBCWC&vGy?w;cvd_%0tTn+vFWM#UFYBT>6oE>nc3Gv+@PXnzat z?yx?{@k7&pd?sBMg0(kwEl&;VOTSBgK+~fqtcE5RViGnq)B^vSaZ0Sz);P4RA*+EI z1^N?ba1fboSo2n?+<_U{CUE%rzX1oJQXn6$*OXH>;}b3|XY@DwyA7f~d`Xhk&+~Xq zdAefvn%)CklKpv9)>ADtAbd?=0aO4=ZiuMVNmMsdI~!}pN%#1ABrDjOK~8( z%uRsXMAx^IAMv5y*oTl=y4-K_`A_wCfX+B$6@z$;*G_;n)X?|?b4DlqDe@6Bch4b*+i>!XO(xM?3G>lTFmj0ojqNfK6nyW_h zmSwQVHZ(J=CO>F6-U#W6$7apr1uxGFxdFn}_{NVH)?b1C>*9Rjh5ki5CrBNBy`m-{vLC2f0fIAEVnn1H zbpbU`Zv+hQUBR9fm4SqN{w}WILU?_MSNUieCs=d0(s?epKcr_k2h?rB z=mxmB4!Nhwj*bvde(Vpr7@l(Tad^~Z^`z3WP?{LqsJSDlx-i;ixO&L2tQDQV9YBh( z`8e5h0DqT)77%+^-o@jO@r&FnLgM+42&Yv{I^Ts`RdUDEvQcwuVm+`;NK&*8l`yu`8WOx@9) zY~dk0q<(%<%#N>dXgx?c4w8b?POWE3sx(zjY^-;D@*Hf47qY6ehwQ_W5^NMELuo5E zsQDeE9>4B6EBwmascovcX2&?wDZ-784KI5ZBKhA`p7WpGjfp2nf=Pvo4?(l{54}!StfC|QEN9+q$T|NGplI&_I z{TUW*9caz*vMaQIg4sW%(){!8jy-wju0S~b*vh1|+mTq>g{Q(lewU9mP`uu8V-NKg zW%;`ET!;9bsZ8OhR=^!p6$VQob?*`Bco z+%&nQr{@#G#06MsyAYbo+UR<%$oPo zgtFFcgH1M*=S=r0FIs=h2XyDf8p4()TmF(bbyXF6ERY^mTSn`#Xbobndb$cF!u&6K z>wLOJb`6g&vk8kfBy?&oz4=rtt%?m>^QNFf2Wkp=5IPbACmjRbRXL8>N%qs<6gjT+ zNw9W$hwM|ejBO5ev8@6TMq?43VsRDfXtW8&)9=ou3!6zXsi0XI(6S#@L;;4HtB6)IaJ^Zva1)H?hsUEK3qMt*hJ z2k(7$+fDwmJ3_Mp-R;0D=()l1!_{SX`f6P+&`}$+r(YL+wd$*Ntq@c^`{9sT@2X!r ze~R_o-Uq{+5`OW(926dFIxmf6xJ)o_Jf`*F&4h18rCUPdQBK~)x)YykDyn&QAK=Lt z#B=W^Q{KKfb;dV|!fk*HuYtX(Kq68z1!@jU16#`>6ps1t(-6@0faKxOYZV&QzAGaP ze&bZ22KA>t- z-JCja1*4_skO4?kom&W1ny@2@fZ}=6A6n*vd}yonXiWjG6Z3}^c}W|7ss%|iS=u~f zPwHEG;#d(-%C&pm4CGx7e^!bpn*h8`n?&vo56sCEpG(#Qt0qe#&e z(?Yo;1U#gL?};~YA>5r53<;)NV!}PT=R#sieOf&wyShWV!U=bUw`V!O**ZT>e}KO! zP^nXwiZUA;bolw9c>WYN*B8K#p{~uHv0f|h`e52>|7e&kbKdvcdt`d}R0Y?OVei-K zp|iDA8s{<*wqb`D#rXULVU-o|kj>FnCBsVw9>GovjdsjDKgLWrcd$Kn6fh&U)Ciwm z^h4J!rQ|F!4eQshQ-4{2&uy)I^y{vzAlEnSL`;8a0tP=?uj)1m{U6jxqW=x$sgJ~) z4G6$pp6#rC1NdC7N7M{}tijpyS$yg6>nP6Q;=^Y@fc>5B6d*Ot`1qhS`@CYm``|&R zN33<5D4hTM{l2U-P)w~e)%386hTw5^_50Yv`xkCJow;GSy0Sjq@KaLwZ94vc?1wE_ z<*IkpMf`{XXf436C6d|4Izf-Dr&NvSecfHQ0sK(iKE4;v(=Im&aV-MLlKK1Ae+ZrB z?Q(!O1huj5wMD1T>DmyEeu>ThaYgms@|A#v)d{`SuqydJRC{R3PrJ<@PC(oQa`~um z6)EK2JrzOK*dR~n&Q*My&Sq*4Xx^vpR?wQ$(-DjpM|@VQHK#dP=V%Lm1d;xtvyZ-0 zqkls#9kYS6JfcJM&Dj}hEl{H_$Qo?}{?K+1R3*OV&HKgTJUYX;r+B z$od3A53iix)!H-Gl1Ynpia{&@*qxB8e9KJaE4MO$wdta}l2rrAGY7wxAw;)@xb*`n z>`hj}$$b@qTWQekJq9Sus``Dtkv}N92DaU1vw4$abX+AP;)u+6$&$yUSZXJgf{L?J zUc^c*CxUEoJFJAjlsFh`%)=Q?P;;aEupLMqxl&HPUvy2$Q*FO1RMfU3BIkGyYdA6% z=sFK`!^gHkg#z2^MgjBms5KkCPd1ak&!tbAj+x%W za2awYq3gL#E(%ig1S&sfWmc`orSijE7j2sw|7R00XKENU`cB1$>DE>~T&0ZITz40X zh`Ra|gn?5kB_oWh9BGXB7rUb0ZT zATx}5X!u2U5#Gu!P}lxf_`}mVhc&grxqpF(wE~5OSsmBde)5OO2;uaJ`>wP3F@WTf zcOI_D=7OTbzRSfv$^zN$=+SdyML9P|YHUrqcYLsS(R{+okXNFc*6Yl}L$B}+VGn!M zz{XRS4H8`^%e=~A#L{iIK0q=u+XAQ}7SV)@3gw#67dMBf`!?>CpIv>mg^aiLGbLJW z+jKtP>^^DUY8D@6NZ9^{RBwSX01@vrkD=%crLHkndx55TH@%{{i9UxdT9zFgR?qyq zh;fwU5`smW6J!H9fV#EVg;{A%acJ$q=E z7C~-2Lr~Mu8h`_yJ6Sn#IUHqT24ttVFk*3kxXfhcf}U%(Zut!50ab-3!g(`H8`_SX zCPJyA1s=Hgdz0)@)7i4MId6me@%~Lr++XySkSR+Q;zKst&^hc0-ZaWfsFG(Yd_wX- z8|?PP{+<+DJ!~8#>A)FE#w&$+XxBf}T=KA?*ks3z-Nywz4ySvWO(;Fl+2}U#2vJC% zw2K^VlAmMlh`mX$i-qlEhl!-&cvC!8?v`lq}UuVnPQ;XghY3 z+z~|?f@s&pj^0=6lFgxA>P@B>!?{zUzTSCa@+EX;$9YP(tFi{+7iEizGr8`|&vimz zfBU>eJHeN;-;7PRg+$D@hEF=iY{@VX(5?R=?f+4|WSqJdfmr;*#A;vsw4+&T6g!#n zbjvQZTc;{{kD_ROf!QvN=clSp?dZZ}b^>4hE&t@Tl|ias)q~&i7j+t!@yJ!V`s;7@ zK=kL3j29uh>>f3|&vF$U-q#&jUtmtE##X(mOH1D^yuJhVpiu6pE9alx?xxj4Q(#M^ zNlwkr-8pp^f%jQW>;j>|sZmkg?Jt~NwZ>D#I!+@vyH!TRgkM(Tz-xeL$BrpH04M-4dK1`CHx5z}e$(Nw5 z7d=}-?_F|Td#PQfC(D#3`sCiwIhN_0(tTUFkHEQZ`~EyNS@T@Pss|s)|K(`z`CG}x z+aq)IHE7K7O@)8r(}%cW#bxdz0rhm3W)^F%ui;ha-`14XcIA zFv?M%Q$`0?99j?^sCUC;E>QTn&u>#hc!y%dwFwHmRpH0GTb=)NOi?XeHtxCS{PP_r zSQF?u7sk2xEnZO{0S%$kac@KKiIvB?R z@@?vp1rZfB;Bq?WqOhqm5S;8@_8>d7-~CLPjS7hVs`|i(G2^AWmB5jji~0j;D^U8c z)O82!#sNbR-j4BP_&hpaY~pcppcDUl$hhExBs!wHKgPyVn#)U}%~-MX#2{x4iSK<$ zzxrpCRFTIx_(`Q8$>!0k5&kpyp3Qxj)c-slD*g-e-TroJ!1;pglZ%_$md6AkbKnkd zC-8xrZ27)q?P;AZyVc8|WEMd_bka4sL{6TgO3G#5sqAx0F#=IU^o{Q8u11qKXRUg8 z!c4x+yQka2$?o1H`+z+hTYHl2EOBpBOXr-dc+2RGOg}c_74s&(n68vD z_ZBkr*Sc1;T=`E3L^b~?bvMm3GzEB%s3%wXvRZCRfu0b>ci;SELm-!ID>KNl33rR4 zBY4)?hNPUPU_tu_h;_^;`plEL?5<#zS4`(!GycCW&ZnCQz8mbj4d{2R?M!zpm3{*Ewa(QlQwl3NfPreT^F ze2(pnESiOz>&cw4#rPgKRlc0izz8D@No-X%cBIBFY{UXXT5lT5gzm2Zn zyD5jSdQ9!GxaaMj{7BTd(4Tx39ip=e2y|sb!-OKrgyrk4?oVCG5ws8kI?0eOhzmK# zZUvZS!#5`ru`YTYwc*83t#4UcVkD4e-yMD z|Ki4)Zt=lTl&57p@2t)e!E$(;_6bx#4+g`UW%HfsnyDP&Jh7QC%<<08v^cS0{hjRx zr1|sJff)q_EYye6_s(YeWhu?u1vi!9Dk@u)s`Y=)kuCT2Z@qXqcus|>t0^?xp}4d) zr%rO#QLo#w=>!a&xBe>{MsBtsef9^00$pZ-s}1rfX^A4gF5;y=t@xfDSA#wu)e^m$HP)IP z!t_>&M9iCjHzT*@1@ZM~1FWGGmC?4VK3gHZb))we`bGsu$&%}Dv{i^(A|?H+MieVk zVK;^$-}*g)N$nlmC}WrNe9X7v?pkB|Y%0#RD(McS`UC}(GhQrB46Yfrwz|iP4X&Tz zJ(SX~t>E3W2E;imTBq~>307a(pU(J@Y0V6Z_^lFnH>9GuGs}2LUe~_lybk)pJb}Mp zM9C-(>4%P(a+=Un3>vVPf5dl=HB%RpLtQG0BV`5l;>}z*$8!YM9+;AJy=(eEMLU!3 zV*Gi-H!*dyYMD9YD`TC}F6k~yw#UW1kunn_5t9i$!)cv6=^khLU68^3&J_jv66^@T40OHU3RUhwWs7N+IRO|OSvb!23j2z{7c?d-kMy0 zD;n=X2}@JPk3ufJH3)-^Tba>V`U3`=X09j8&(YBBSxB4$$eXm}EKH^J0QsMkZ7V!U z?J2+{9o4BXFF?CqH;jbCO5-IS=>#rbsX1m@dM`^OO@D01f_cxX{S)kyS;Ij6_XZPr zu#|2XieCsnXA=0gVTh|a_48BTyt=znh`NrZhSFpAsRZxV82UlGs@3e?Cg^2K-4aa zT05t0+4W5-Bnos*OC}MO-R~{UqLKJEvQ&=-ABB%gXqpjzRDL$oWTJvIb=lAF8cdUf?)HU4;Q^`ZOL&ju zWW0qpPD|Ix-3&f@ej;_JlSoY7(kgu6Wt^{4#RtjGs>Dyq)PgGJz-9ZRiNf>pg69rz3MG}?QhJIdf-AHiT z%@{Dvq$0UC5zwqLVu=ZF?)>V4E2UL8C%WEE>6{7EQ>EX^&oyn8J#I32UUPLdA2_WM zlg$^6Spd3peH+rG*U|sSl?DD6yekBSidT!%qXKE_18F8(L{*N4-G=5Oc)t7r|CHTX z#{I-V76--;$9}-m5G=(pMUOs9*Xxi#i9W<_TvZA@p zyuQVJuKe3ghmg74s{Uj}L`ZnJk{!C0V1 zN{&%eTG{m`onT?Adap*WxXaIxzi!+t`#v;eccHr8sk#)QMA_9RyH>j${2sI&;6~nj z^IcnYPn7CwiQR5009@}9sknqkaH+SAU?=CEaaDU+#0y(!+`5kzNw{M2S840uUc{ml z$$g6H%KHUT_2urV%?{>>UfbHN1i}1*nAzK|>BepyQU@G8Gi%G-myao2z@eZLuMr~a z($t0oodQW9iLe2m%JDvt>Rf14k_|7CSO3pdyVmLE{ zN~8&I#3Zl_%3~T={VVdV%QL5xZcE^lilOn_@8XV3=2BJGL_2RNnbe{hR-OySz7?7d zCb0*S3XzFVaF_Y2r){ksrNBM&VsryfIdCJb1YIcO9#k|{br(24XU-!l zjNTbL>GsGmP+Rz2+M8xvH=#zi;wr>l&0i-x`_u4vT<6#&X(}$oj1b`-ma3+( z8?v?G`?}2`uuIO0SP1foy5L2NO(a4b^%e4GrX=KExW9>R6Hc~oU&OF=S=KrRsbAQ~q1;SNGuV&WD{yU$% zmg^fdWt>~|Z3Ov^M|%n(gp?(Pi4v?Ygfgdnj&E+weh48M6ygFR92bWDBSsriuP6wP z95;sewoT)CE1DA`RI0*TDAyZDCVX<+@33f&=Iv^`2m0h%@uPO3-^TAN0@%Rp1Wxn- zsa)%)0e%syTalR{hRQ)8g(xwVWs^(eaQ~XvOHrjHod0cMcgN?4*e&ACiM`66)1q5* zyBR%)x)NX(Mv+tF?XdE&`SMn4#^&8;1X+bA*c-$3mK`}MQ0W^lgC5ZOiI8b^Uat&D zKQzw(j5{!Z?JLr~FX>ri^F0|pniLbSY?ib8+*ouAL>{g_pX#1n3};`wPM}ZFu_K_L z?s6De1kvwLT5AWamkWG|c5&mkyaU<#by}qdJvZ?dqe_x)bB8^}{BUaSZJ{(Ve#$me zuM@jzDR02}E5*xz{~>`=o9D7P(iHE{xs>g(8z^)GFu!w=8}n_@ue-oyny3HlJ~HQ0 zoq|5oVCDYY_TKazKo4%dy>NI3*>hAineU3rfOpV?lw3MG2wWE~jp{opqMH052DB&m zsmvrJDJwG8M08^RM>0B;^E~_8L^KzE+5)$KXjKI-8UuGb;qi$vc8Bcc8hLllsr_hi z`!DAQ&7IKW-v40xIO$O1Sa^FE;E^Qi8RS-mkvm3wexb8iBKSG#_6+ zkwbboaf8!rhBEfppS2v)#@Mr*F}<>}$EhzsS~hFFjTRLKxkqxb$6GzYyJev-xb!oK zG!^g(WPK*;H{^kOjMa=18}XNia6VbuCz)mzf8gwtVogA)?Pxyx5}>CiV3&L`zZ_ZL z52ymMDwWSxge%x?T4slP^<~N&?7{`GlYE~?q(r2(dO~(`EYj)9?-(`BJ$cO>QJOJS zX8fu$_x&ei<@zr20I#C*#d|c#o9HW#m!x#7QyR;(ih?Lwe*?DymR>ohiv@<3^!-yv z;dd3^{8OugW}bhD23(YiSulBlCYr=N0q)Y1*^2Biig^~TYPL4lVI+D;l+=fhS(i`j z$37!o&y@StAQ^gRIZxh4EgH1vW5J+N`yX6wGmTAqt@d5*Jx6!n=3G@ccl@6}zdIwJ z$LMoFe_-t!dWu|W-FDkungjN~ zb??)2aZzc}eX5me2cMJ0&zy_WROx6bWr^4r>ju$r{#)cZ^`juTo5bN+rai?N=3~*ePKQCT>T`c zjpz<{`PrUYV7|HE#CSZQN=a)g-o`Wwn6%~aM@s4y2f<9;N=KAnT76X1YsrP@8evXe zCrMH7V1~p)i>;9NBI;1c?#LY1KX}!1H(;P6*`tN1+54EQijhj!l(gF(Z=OKdf+;~f zHgj-t%+DR6n#8!VFVQNSp(^9PIsfvhkcb5oK*GH|up;HKeVH!qRv!ruW0B@ zQ=m)GxY2NdI-Y-Y-c`~KdeThV@P%aKqF8n{|6Oi;;Ap?g>*15sS|fqA0|R>?%ScgS zV`jlxGQ(t~I0h<-MkL~PUQBNwS@!HnY(zh;%Um~{U-kgSGW|`62Lw*d6vpdw&wJEf zlpNYnhh=&6tcj5y41Upd8;~?HmkH{;+7~pKPMxe^7QP%l4!yMDLW?QiObGGrGatl^ zXH4v%D-QiLX?*9`MJ4EhatzBjH$e;#!$Jd2p-d{H4($>%6Zzhr6&acP`oWv&SGj5` z9eY#AKWSS(0T+i$n*_xi1tI)z6tX@Y)v{Y}{y^^DPm4&2kLsuP2=>=MS=oInH~J+h zzBh!({--w2JS!V?V*kAI=Vz(*D~zG{2;uH!9~9gYsl5Vx?n9+{V{yn!qnbkXHV+JB zdX=Rs>g($Vn#qrzKHVX|Cv*absN0QBMaOe_%!fKfVy6 zV%$&nc5DHE}HzMt;h2RG0)f{4!dpdM%a!|!PLbE%G3*` zPl;{P?C+g~O^EW7<)}_m0AHFN!qP}=*RhunpO8g5GsIVcQz}5!wYkhfx zZC*EFS~>vp7yz2FTE=r?+BW^$P}u#ip)hR|O&6KlH#ka)6mN!;WO5&@7M9D96<0i_z#Nbe6G+{UOZ2OhoSc4=X7S*GszIQ^*DsOsMBsSt zx_XahEwHs-K&Y~~(EViR8|kE9DeGRLx`HVIYv0`BH`GJZy&NJuosLA6hD-UND{TU6 zb%QKdXu(;;J+NS?(}WZ9gS3+ke{n+%`xc-yRB!SX$I zG#@0N?w=xtpv$-cVb@yL3}q6VhAmaPYvW9ots-)?DZ;%^6(%$lJ;))qiux1H(MEkP zgzoSRNw1w@0;)Det-s!ZKAz;Ke8aI1>lhjWR!eZ9f%dWKmYZ>MU)Lnb$@M)wb-Mh- z82IvBXn@neQWJ3yYmCBR(<|rK4(j2A%;@Zam*WpXQ+>$DT$ktExIUMfCln>##d9bNh$C6M4R z+ZFImc#(%CYoy)6DMplu2oZNxFl{}Wt2EgPzC&G6I2BVbqO#uP-_M!2gEhTtgOC-J zpSNjp)uvGtUsK4_FBUN10ciX+3*kE(guIMa`1zo53Bclt$&=(EXMu%toL5&NF6eHi zm+SIU>{hLSCN~$w#!0c3=eG!da2NNg&~k4lm~7xQ%s$cN8+;RiSRiu0=mBLn^AI>r zo~0$%X7P5by0_Y*U!AL#?*<@={lqGYkgrTli!vQs^ATnFlhN2w?nRxJ zCTS0-M$Sa8ULnIbb1n zEoZHt84}wYJt0y23m1g`A1Nm%Xw{z?PU06Dv?L?=_|`~T|&v=QT_NPV7z?x~3i z8ZG9C>3p7P7kd{Z7dI5p2T*p$1%g!V>uo4%3tGc}w@G3KB1YeoT21y3SGbdZfM_;c z-u~@E-Q^n15smFv1*G+7^$K1*x)T12T|Io6wmD)$k_dv#!#AZp+V5jWVd#iORO7jm zgE^muvE+QkbF4xg(S+tD^)#*<;Uew?*;#VzaEPW$lA8-3m|K)Op;h?(n#9sW`O#yO1< zh2FntL6pmMb)5-GcSq=p}r8f zb9EfLdsU*^-q90l9Br~#TT}s4o<0icLJyS=vvb=P}?#V^x2|5 z;v<}?1LO6t>P9tUjRIO1RH~Eg0+@$3nHr;!AwJzh*x2oO#QB|@)|~eA zHJ_c*NPlkfCx&v7`@TC5xm$eqZpEI)f)nGasy)5;rD=?H`1T_>C}&6END)GD6$K}! zU%pbD?{A~Ctpa!H%*)rap(6$Tdeua73z6tiJs}rDtUpLc>oE35=`;d zs<5PFcjCU#q#3|dI#!>hN@Z8me#IS8=2e1wYPQ+8(tT6k;O0X>7qiE`(o*+UD?2Ra zmerzy1C;NiMSi+L*?+-q!$G%V+`aJTZpPj?Ho<}yxBb%Q6Y2fxS~#X>6Zt5MlS>cS zx_2s*SOn))hUs-Cn|@Kjy`(>r{`(bGUVx)Nh!A7P9`M^XxR}k(2{Q5&`WRpmN;3n= zdyK0Wr5bk~4{M_<-lxEG$hVr(XxW+PL+l*ZJm)&%+FCX3(Y}53YYySSD&`#|_C}6B zKtd25)(Oun;cl{PBGzvEb2VQ})&LKxJaqMa`qoAPm~`^9>{_SE0~Z>GuMTP$-c1`4 ziUcHPLQic>Nb~`V&)vC5pm)kwBk(CFU%L0WhFqA7CqP9lx+&>G;pf<|K;mjrmw;$aq zcs~4X{hm|6pzC4>;&?sp=>G@4o%mVf53)x}r@v39MaGPX#ENuB_DVvd9&SEOAT!1m z3sO8Hwx7J%+OH!l7KzgrsG&rp93)(huDMNDGfSAV5(kj?J@`hIrDg^`+=CG1M6$^R zIkLeTJTe*bZ<&XU82A2EMMZgMhm=XC5uh!9*ESE&XwqLk*@&H&W2YwSB+#aIxo4TF zyqg&5{Z%WeUy82>bgs~M!z}wf9G<0#LL$r!bm8`0k`isO-q>~6;|!U_tp3Xz?}?xV zRr9t6jv5AbhcTMoaHD0TFF&Eyq1E*MC0l7N7EwHdCa<}W;@uLsq3V9!C|iJ&yoLKP z{1llg@JjBA(6`BkrhL0E*=H33N=nZ4TeeK{Q|Xad(&Z&Y6ei3z*j&u%rOSAWZs;g4 zUwsnZvxMz=k@oG00yeTtp2AXXhpj2$5Wga_fP>FLRSFC*B-3Ue0>`b@WoBPphTES+ z>|-ZGeUy#2uM-;8W!Qi~NLF<3lpc5tu2EUEc4+TJ#y+aq#$&$hyp_BIIPjJo7PY-c zQIj>Agw?IQ{qq2QT1rJ8&?-f(TCJ{uUeEdZh9|4v`H{AEz~`-RRmp$~%MybSnbd)xYa z@{M!2iSD6~yAlM?k0|p$((|I(1Hmh%1@B&lb&AQ%6|Yy&ONe~Ind9&_go}c!%x0D( z?~z}}rxdR_lL2Ytb3L_M&adDU(E-VT+-|YB)<~webmxaW?cQ|*kY~IcaLHvT$(+x; zcx%gbh4<4v`C>_!=eWczO^IwnrfrZn$kQCNOJO{1!x>zA8?>Vpr69YTd1>1sMXZ^Y zTZr6=foSe89HvD0Z>M|m-%fWhRAyu*TwvubCVeN$z|-me?UMtugTId$KR+rnpHjGP z22vT;oJ=tnmd@c5aWNtDho}1=tfA#UA2NxX&fTT7vAcA){wM8R)3}BFSsRH9zc`hy z;u#Wg;kn0nlY?n4PPu2GkFG!PdS;2JH+?Wx_D{zEj`5CLxZ|70#;1lkSZ@EF)~Wn3 z8`ZKyGgx6>9h$6I_lhtYJ$EA!%ZbY#BcVpSl7hNm4NS3%ey^Pb-%Wl z#5`VhRfTbVrLvDeU}j|W$Gr=CJr|oeB|2%{B?d5Vp|(Z%&T9>5-ZHxTiuT@y@L-7S zN{RCTb@3yuk$thj7CFWq;8Cg2HptY>*S;dSTXKj~%7VsC(k+`@{1Tm4!Ifpgde=Tx zIF|c8GBa-WQsLi<8QH5O$`k7}&)&EWqFltqfc;mSMr+mNxP4lN%)yw5>;?eE2ve1H zZ9BYG%g&ynxQjB_Sa&9fI5(*H#Oe;Ct+9vuHQK`)KenssZGk3T3%QG>rAZxlxP;;v zOCwx4GE}XxEnojmuX3&d1Mj zB08&qX-8b(%;%rkzL^atphzu|=p%$>E0?tiqw4DodCB^Td;3#@dv0;Eb&zp37*_Z| zeP;vF(06N3H#EaeO$AZrw;NHrS1VlFP-{{`*LcUn0Ocpbaw(p3SN4oPAc}ZkPQNV@ z=*bkXFg8e!+{Z0#8xk6?#*H64uo3 z6<1lNfe&?r1XH{Ri3-s^u&(Mkbm$$BWrML{K)L;Gj(~tDp z9U@14B*@={tPmrONSbf+6(T`mie%M|`Z@HP?9H zxa%tmz8f$|%}@SwNW7FW?9RN4pk=);q|Dp=5B<7?^=QGe+^~#3QoBPF8D$K=(v|6Z zI9?vIoUJQ(b;Qhd%L|wUO=bKaqTW58$;bU4cg(4*QVB5;lCqF98``EoNZ1yGjbT_ygAHlzU%#Y{2sr5?|<$;?&p17&*ybLuj_Je z_5e$`51W+?Z&b{yV3j4ItoQkHG|C zz~O=`QD%h#ODl6e%POp^Kv5giWAh?T=m4kH4!v``x!2UBa!nzl8Qw9KT{JK2m*{z! zbf<|lke9n)fv2FW3-gNQe7`U~TZoZ*lgGd=a;dQRMXKttMRAGwSh?Ilhl6AF7T|F! z9h$CV_KwTN?|un_xr9$2?)Ar(&Z@)dzbz2dAxH%T;kR28z3r&GZ+$;};0Qn-_*eYG zL`rYXeNod;vsIg`982H-$1k%phrgXQIvHct+|T>p&$pL0XD?0$^$2`L=r0>A90uYk z>{C2@#;HegwKonV{ZxWN?>ucj&VDlZB>6H~zE)(i(01=ebenDwVk)%dUAT)`(>k6r zn3N+RpazzKtS zEE~OU5FQ=Y<=E+Zj*){x0;U4kEW1O-@gDttWq5gySAM_9LL8>k>%EQuis5a zARIQ5Ju~!=%stJBD|yi&$~!%&wYf!|iOU(n6~S*lzPTw{%ZvEKzT~?+g2}|hRj0dr zt_0HC)ogN*8=cIj8Gcv zar=<@Ba4{!LDxVAm$R(uy(8Y8gb z5PJM@rR)boCO$Ap0O!pR#`&a6?L5mg1BPW3fY{eH9`=Gc4{dl6EpqjV%a#QJ?!_Xt` zEbM;oHOUA@gi@JW?9E%pb{DfI5h}mU@N%qSnH-wmI;Xad9{q}i<&w$t(AMWh&Uh2o z;Hf)LsY>U}^|a?>@<97tg3@p+Rg8(?8rzM*vJb?YNFm|Nt>rJRD%fAz#=WjytoI7V zlqtKE_tK)RIGJbe3R9=3w95zolVH*_Mu$mmao0-Ziw{5iYe|6lU;mK0{BlaP`91r& z=1;+AnuUWgiE*&|{_FmK0 zw$DN-UQpyVLqfYol@5Oia31D_Or8DtIP>0pa+*@!Gx{o7zCP^VyBY;vUxT|?(|vx_ zSrx^$y~|0A7|ES~oPg0GYtnT~qT?g(uaq&l5c7H121QEVwx>}#bcZeDcJ!%LE!~!) zYB(iw(BuUL8Z2PlRKw%9d?JSr^mEKUPSN%2rezhTFfrWYW{S?d%MtJP6(OT)T?B2f zG}VF!c;RXs$@Fr%R{}}Xow>cfJJU%MYI0&6y1r%R?eEJj#T^VyF^5#Ws}9d#ceD#z z6_;+}=F6l1%S>fnqH4xArWxVDG?^el0GR_pmwp6n&zqcQU#YKtZZ)_bXpw%<)H)e6 z>`(pZiLI|JimF=D52VJ~zDW;Y+#2s8O8lA~vG{`+o;9Zw+pN`(|0?Ami;TRvwcYm% z>^pwvr=ZOfvQKWv&V`c3)QpmmF~!o6)OLIbC15)!t3B?Z=x}N@|JE_mkwp)~zG(s5 zmObh`wp^ABcgfM6f&9J=Ucchm`8#3%Y*YBA>O-6(%4ErN9}C~!e{)dTw2^f&Q5kIt z)02Lrs9dId77=^5T6R*5>W9{CzAC+}T zfCQm=YO>Xkc*~V)tFvSxG4%v`7jkf3C-Sp*cH2jreV61f+O&5yvJ7*NQueagh~rB` zqzh~ZLBin0_<(b(24c>~PJqXiu{|Pi7n5gRVZh4~TKfgkHglqLCF1ZE`H?5*%k4x^ zXO0ezQKcWY-4P>=qx18kmGf&1ULl2ipOk%vbbYn$1BnFH5E%w&#vJ=L{b=y=)U7;B zzTH0`0`pSzFHHDkQ_o)5Fbl_=MXC`&FSvw`sd3#n=FIhuOFEtb2LR^d+K#$ak1C|R zW&I;E`4^kZ7$ zO_7_r2HUGH!L^oQP}CagThNEP2^_4Qryh)BYn^w*R76>Ajj@rp~OFH2mJ{4*8^9jp4Jz`Q=db zpFwmb=MAz@pYfl-;=tSGkVf1*tC%gZZz9FG8Vr)nv4l=os}YTVu(zJubO_9}?lTdo zL&94)aXwPsXd`PAwzUe^-ev_tz;8lr)v&CW-Z@Vllr0m|)YFhuL2q}XXpXcTh|Eng zOT+5%b@E<*#=i7e0%9nkPSB9reYl0nHg@QimCN~U5e^0d9+O4pM~071hDdtQhnrSaE$t1RSnZt zY^7sRF6bD@t84zpoLShAY8-fneOx~e+Eq~wby!l_8ws=q8+0XQelBXwP{rcg%P>T? z!}wBey*rC*!s5L)l!%685L}x$9{pdfch0DP4y1!)Dc8!8M}t%cJT%UyJQB42$2I%+ z;{i*AEWhd#B`nmURV99y5Aa>*_2PZOo5EXie87)aj%_<}A&8A1?6BFCido$L^w2P- zZDG+_J5-lbR`0sO_5buMgaKSPxr{#W`tOz^)vT(BB_nHVu#miQ>$1{~;c!}n+{$T7 z8(Y}VLdmlo>K$;iPSU%!CS#v}KZ->5Fcc(UX=C|pny+L;S*N{h+E zCW$o}IYjp=9TxPIU~mQDcUfAFtUoN!t)0Frms7M^K;e@IRg#Szdx^0g{GaDE2;4&LJ$4ac{ZB6fTv)WNaxnkA@!~k=EDi(yzC9K(6 z4JShxowo?ydI7741#(_EIYj1n?Hdc(xGi?Ck<%;kxAI(m+$+{0pFPrmNC9dh2f@j{ zi{tH*C~jg&q>btLn)`)kaznrvA|g%LoYtXoXKC}n9rd=W9vP=2wQa59jSa`D@S2_?zjwJxT5De&f>S~vjw*LTI^?nQ`pZoM+raT($)zxmzA+iSrCaK zbl(GAC*9J-EK|z5A>Wsa2T4c$1}x}?mVUYyRKrnJ7oT~RBMWr_%f7;Vn)b5cEM^|k z1>vSe+ZGKQG^>Ums}$S#KcKF=|446a%Qx$#}D&_g>*p&rflj9F(WxcfugwTJ3@5>q-*DPlMfpV5~eY5~4Z z_)NhG+*CyC*;E*QMI{dmd#qf}e8z)~d84^grHJq_-Nq|TQNI9C+`xgO9<1KfI<_KD zFopPm_|dzHJ6b5cEO5Nr9<_2;3;1#IsMzV*(k^>?#c-PUwDu3UoE3S(fqXue=arR` zU8G3Beh~QR>2L$C2lrS{dll=+hCBn+qM;P!r7`t$(15f>sMt50t>Ul7-KY4uKIEX5Tc!BHQeA-9%w9~{ z!nHtq9n-ehkt=c*^|wAI?OZ!fp}+$Bs=kzo!V9_1bR z0ZHQ~8tvchPbLOWAg7tJobVAKNmNTsC0E>|Fcj11&^m5Z}cB%7b>SoZXwb^Es_v^cqrW z_QLWcnajZ!=^cNChKml9PRH>7!~yazt#_havz^jn$xv42+C z_dnpVUVL`2*RfhLvoiEq=IwukVC(Tv$^vZmpmw)IU^UJbgwd^3ypnx2it#z(KFH9R z-HUL{D#xR9<@XOA?K0i6Ytj+rq3~@eJM;E3nED70J35o`DRp$m{4t#B4jpK4jKQ(3CBlJOf>>e@wj%eBA>@<8mFeP z$GJ2bjr$~B0Otq^^ zN+b8co=@N}XlJS{koca+Cr^#XdVX1-?-xK+=tm=0zT@Ldb>Z~K;5Bo_{GH{qq^k() z>OLMCH3GWCvzLTZ;~BJAgcRQA**S~ntIb$61hNgyhWGVLlN|t=PMpr4nq*sQ#%8sw z++5BT&3=nahqjjt_ZWv*HhlZH;Q}eQvwYOx!5e5ID5v;%qO5 zFmi-G^;g7Z34#xB&RjDh_Y-#Wwbo2)S8;^y;vm!?t0<<^)o#I@LO^7HWfnDxb`{)( zRtbGfxx@GiFD$aDrr7}w^M>VCZ#OudaRRtl)frinttN~LT8F8I;x3Ln;ii7!EptY&ijq`6K@P}bf)_QgS&33p!`LH1PqD!_i)#i zxz|PLzPi16SNgrVENT#Fdo9OCug^k%j8}QKz}tfxPd^Vn{o0!NT+-2vcKVkzr2vZw zi9_eAdwx!IW;GMNk4-p5YWpN_d?5B4{(Gt1>nRW5*vN>`&m617pTe02;)%(tm9RpN zUBuFA>uUGv;ClB^=iZs^kjXOI@rofK&Y=PER{HnM%uwc&pYLI8YS+|xm-_Ib~ z-)QY?p!{+$*+;aD+r?-P90!5F%&6*7pv5PTw#(#~r*C)A`*=U8!`EEqg{@{h6{!!9 z%uo|F3NJ$06^>pM@njlY%7Q|z7h7XdeON~+Z?4Wfvky7iuH#CyvJ9P_7G;KGB2@`x z=6{gcn2ez9pSyifgj${ZPkm)3_XLYq)PLPnfj#tl%cyz0f7#sgw0-?xNBlX2ezgA|)+C!=qrcdE3#MZeUfRpjpe7F* z2#!$1GYX&qL0-G>#m5v89UE)C_5m|Y>Bd>{;f3PJz#bvb0^oJx$m9bYipOGNvU}Fr zgL)5XLaae@fhkVW`RyRbJm{Bj@a+cw*pE|0S!0WK|pzUdx9NTWY)u# zfum#TyPrqy2H}`RnLU|! z+aeB?P=}J?u0cQMjUw+fy=N%mM<_L@k!%U4s%O4p@+Ne0g6{G*83#9C-$||i$BNh8 ztP8zA>AtYO3nM!&TH6>{4a>6PCu+pReAj9h)&x6Vuai6N$w4zL0mDB@wU^Q9uyZSJ z99r0IOpJ#RbSs6(GCxT=8n=VfT#QPszw-HI1{gPtz+Z#uZ1d$C4KRs;_yTZ%_G}W@ z++_P}{&-{l{9BEOb!+)TRsHAEgms|@Mk~n={M6Fn%t`v;cjJyMv()iK)={%ea6#h1 zr2$yyElBhPQi|-7cfloYbj{gvDV1-@`wom)M!Yo~x@v>!zXfL4po0XXMKlz*hhiTB zKm`~jwx>Td3k{1k2xm9^^Iu%;&{srd$(3#K`~@K2Y3Uu#wAQK-p0v?A>V0B}?)>BC z?W6gL;mR7lal4aiwXHQAaJg7=xtlJrw0JL1i!jMYK0N^Jd{K;e3qAe)kY8gRxN3-w zm>U2KpRj2U+r-e?!#6b#&jC#!0~XZOsXRpq3pFfH7(pG%BeBwdzQtrDLOJ(hs;an_I!K*(2WRJDpIOJ z+xqS+P8`2)NKf`ZQa)-v$qcf#&SO)%gQtF;ID(sHfYW#unoT5Xrb&Hw5J74~b#48E zwCG-h%sWBM4OGEmWX%L=^*`A^MbI7+%mzLVf{c>?4}fSE02Q~{nu0?@je)$Zv|jwy z$&_1H+D}GL>b|nARHjtlX)e#cnx8qQwxm!EM94Kz>CD9);oI96IZtL@y{KHEX zIf>`-;;2x#EX}K$$;@=J8@mzu+fZ^7+%FV3^J(T8z zu0H`ba`o}WEUpVyDN;RKVpbMbCRYooP4GYEB2iM6^09KUY{Q?g>)mDHy49oA->_c~ z4JBd%`6RZapvggvxqJ@VeNG^g39`@XHn(@xy#r$?UV5~vY?qA=uh^xS-bzLeyDxs? zk!%Ie$2E?`jk|`_zC{&;(i+4&w%!ju2|f%6@GckE*a{hnEzcF+NfXxu4utKdozPUD z#>Y@BRw%$%W|s->uL3)U5|W>SGG*dF`^)OcajvasTs60+$3Mpo{7Jl#bz%?@ywkTu zJV@Z_xMdo)|Mc-V%IUzojML+*K6Zss%|UAN;>_&hQky>x3T z+4W_pNa{Yo$KLrSaT(fF=9wLxr|HpCQJ&@a4NLhCd>!8pz85I7DwO_O2Mw^( zK_874c1+*ic_#^d=iI)rRv_nuE49{#2wPv%`)o=>jeV+OWN z$Os2Z+}Mv-cZ>tV_K))~r`kp~6>>OpxP}atf-~Bva_(c4GdE;;56!5zts2t~4&MK4 zJ36gl29gXCmQ~sn&qK5RfjR9a)y=0umI`A4cCuW7@DQeH;j3_U4kye%;8a(xe8BaE zYK~;f$6#9!fqB_}n#x7s$XT@Ed>N55fh#fXdcv0YTT{^ycGXVZg(T8e=ABn2+<&t+ zal8q+@;v>1cs#Z?>5BFO=S$fO_R%9}R$a`eVF|Ca>BOCd)n$>B;KR5wdz10&#}>mp zW$d8~+KTiN(<_)5!w$pO%>T|gnmnYMIk?h{V&fQm-8luqvg>@@fJX1xGULy6 zBNMVX&ZQ8wNORO)Y2O`*?IAnP0jD2NokmRDDxd3$k>eRD)q#r;JE6mQw8Wxxz<`55 zTKk1Wx2v0)ZG|Qi4%)M6mrA}DxHZ0Y+TtE2iRbMca_w^Lg`xtlgUX^1em!#62;?^T zErq^8E3~i`xNi1W>gC4g&yae!);vp<%hZ9iZY>PcTJ!DBWpMrFwO%ah}J9>t)P*(ENV{>jsE&w5;ahmS-;i4AW7?VbWVpt@qs8 z|5tiPpDP4$X>sW@Y2F;tT~~NQ;%2j$Z|)&m0M7lKo=4( zLbpGC11t-A^%bpT+*r;Tj)l^yq_HJ12G<-%q$M!d6b9UVW+aMi@u`}kF8tngMRUMszp%K);A36M;OG`OA03*4sAg6r%xp!sRZnR{bjhh-ui^HuK9=1aS#sv)e`ue+kFnWTfLH6+3ANu3NLNcK9~a%O`|$DUPYNqXajz$I2(wKC@l&A z^%6>sgVaK?%4)w729ki|gOD9d9_ynoHY**{p{hdQ1@k-S4*JgNRi7y9$107alq}Lk zzi*-N6WYHw;eqqZa)BKHFn=R`|6g8ZkN#DRK?xP!y6GCp3NgY#mG6S=!CrLoCM`zy z=)YIsw{dtIEFpYXr^=5*nV+U29#AjFe9z3#yN4{{ zc{D;+aHDbr>D(wy^u269J2Yb7Bt2DJ>L?vDa|#*IYiBuOXT;6g1>?9!=A*UnUaHloUV1N5HpnoYc<;tN#3o zSk(KI@iq64!5*hB+KCs?<|!@KV|t>F13mUfE0TcwRg6ARZ4b|{2`qQQ(IxHn6QACo z!?TBPE%^AXt!~M>fXRdZc1Vg3{jVK$$A4bGL?b0;2lbUaYjSb zwmkOWomuVRo)+mM1<5t z@U^zEH#r@9z#06{mtd}0VRYa!eIQL?=X2Zn3)lrzA)Bb}i}q52B_FeF}khXWzwN#(&Y zZ0-HF#1{FMZsm04tyw|xfMppe1JeN_*Wo=jKSnN;J)TcWzC}7wKbPJM_uVv8hDcMJ z&8`2{2OEW=e{F=5gZji?vSfq(P^~hDLY?|bTlq)NV+HvN*3Sr9Smg{Y_vP8@mT zIW-W#9#<;g%M6LWf?I-)!}KJxpjU3b)=MXy+YRuJNSxTpL#Ha?|5|KM-^bE^@n09p zYXnQLx2d+7HAQV8X8$e(=_6tF_rvzKgF&xS|B01r9=Z*6Ke<-53qP+X=NLbO4-eO~ z$#EA|^EnLk;?C4v)g#LJuXEx=>)!Nv9OgKRwcncVc6!(ZUaWBpN5a5yhOz}^TsxM& zDOfHqc*+29Mk=jbm{dC?txvbEnwyN(;TuDknRdX9A01H7Tx(x$ngWvy~Yz}L4t zwTZN@k#kLGg8?5H>$qI(fZUCTU7guz<6CO9hT>n-f#X+PGQj-%cLp$fWib#qU)NCj zzS-eQ-7N-pW0-D{=Y|;J^~ga2dGbm5c?Bm?l#qRo-^;dZ^Tz3b!@w2K06pROthgh0 zFo|=(5vlhq2i5cjvUX*c_WbGx@?@$l1I=Iawb+~Sdvt<-;ZsYy)h8n9l3PmaKV;bi zR*~7*j;O}B_5WkdQu-qKa4j1i;zmcUpm$8)n+M;K%Mk|>G^!>lrZ%Vl9LgDLiBir5 z-B%9Z`0pd(ZQ3Ez!FRc2zoV3;KDIg4{*Qc}aKD6xl*s!p6^2^4#Xjp(dNbiacoUiWBHIE00b`HuTtW?I>g~Xm?O; z$cbq0Og)|PPoS>;9M;+u8a6T?9+(U*JN`Jsgi!Cib2?siOxe4|#A^j60FRX|6xu8) zwx?MHfsNK6-li$GtD5LN#paB~-(?6;3#AOe=B4;S#>dJszyMP0&_ zKo{hX-UA;vcpKEO zRVU_)Pi2Vx{&r7!`5SbLuO31J^9DuUqaX$p#}xpB$lkjz7atm>d@m#20vrq9IaU`{ z(i|zyOmXVfs!Ja(9+`RbLyRn3J3v}ZG~5<(J!#Xo_Y0{LUS!51N)JA7yqFngI5p0X=me`VC-uDdL&o#J5Bq#&Y`@(B&}t5bSug zS^vVc{&(BomxII))>sZZOCn$wG@*QsRb1v`UCC*GRJ}bK>cbkmeNuPvSwJ2meeRR$ zyq$$}v?=*(&qQd=c2sjZa9mzU;vgtoYwrnNhI=a$9jd;(7o^(n%w( zI2}^(l+Cvzx<4rZ}f+5!|u6!o6Hx-QJhkzPPTv&73! zikf*~u*$k~_75LtH9vj;y)Pp?qA`LLH1EjbfrKEZ6Wu78Js`V_^$?7HidJgo;do_q zV+^W4P@ZA(a8{(*2h+7JEj@v?wSoR=;HjU1bjo3-VS*b7Jqf)%WzA-h-#YfPY{eyO z8PHWm%s9?FKs%oidW}kGNU}4p$EL1W4ZItcFd+>_)E^hC9GbX4JWTxpc~GO__zD3EsCc018YB>Ryb*L5_?}Z zU8#cs>T~s`;0n5E-3T?;v8|9aLz1dXYG1M~dNg0Xo=pT2|=CF;?bKf+{AwCaI^bxC;OhbU?~(3U7vFv3k0w`&$04c}NU3nxyL zsrdYv9#TO&cW8z6IskerTfHO7eA*M@Ns~R5tOcIOy!%)!VaW(BYOvr5)`9b0ZArS% zn+8fSR*S*LaI~;{?%Xybxw!rkH!_27>l*g$c!mydWEFl{!2|gZX&R$$PqsXoLW4Cb z|9$q6nWyG=PTr3BPyb}|6dU{L8^aelv^cLUaXnEPJ#f-ZB0yL>aTLJYCe!3ZW9MH}56JE7loCK_Z2!3tQ-o^RE`^ll-Lh|ZsheX} zQ3?LE=P^?GnOd2d?$Qh4K&3C~F{Xt&42pByAFOgyGoYf09ceBaKz6+8*Tq@(O@WDx zpo~n=^89bSeE_{IaEH=Df7`IJDo1BoyBYQY6zx@kmq!J~1v=yA+9r8DzrhO!f?>tl ziG91w9CmteLfM)L4J@l?qB|6!QxfIa(&+2In+J0op|VWl*brCGaPJC}z6BSS#w8%^W$z(+#QAq zHig-sId?^t-`D_;bwm5o*Nx~}hEk*ruC_f+t3h_B1Cu5sZ&v{QYU;l&dDz9=EiEf_ z{jLj=4cOAY`Jge&kO|jxv`mB_M&H0WA_k5!$>Gb-h9{<7#YJ*fl88KBaQ(S}P{k$H61*!R!TqB=zN}`bKW9%DR z-W1-e4m?k_=uF)q1FuCXBfHq}vCCH9Nz-9(dQQ2pEI-~wv6H|103Llj;PIGnpu}QH zTL)4rZ^H}ZIhNq5SalZ{{0ciy%)$}EHZ&Glm~&YDUv#^=Z~NzeZ+dR=d^t$oy_SzbT{gjbh7x39c5IpK8{7?bhqsC+ zOhp4fxibsQ#$)oL8$naTW^;7$e5N(_#O5&f?FDY{rY5L!;;}riC?>W_;i`?=%--qj zpp6h!b=Yyl)(kT3;2+>IK~6tB0nedZ4~srNPi9n_4ZmBuYi(!^ z5?cMO?P6G^dh|Gx6!1LJDWjp)JvJrJOjIY$g^iRUKG4wg`0KLZd`66S0Qfniptb%o zHc(j@l~2^K8#1P`T3dCId2R#j*2b~VC1C9r0VR;-h2mCXGGynW@J^SqOFUFW6MTG( zXQq&rAFb>qd9P+H93^+}vLTrIATSFOLVY%yJmqU89^tZ|uE9`LpN-{a|2dkf;$foaC2;E#`QjR#u@%*y&b9N2xVP6L%tRYK zKT#fSiMLPwt6=5Tqo{V$lA$~RHU+lAQR)T3{-T@wl->$i06QQ!ei!9n_cs?L!) z3T~PHo#+8RIK>^g_} zg49-wcrB40;k~6`_HRO?p5^`hN1tuF&+Io<>#)_un`Dn34zYE z>}vK+Q{_iT%!5esB?)q7IxiB_wN%uA!euZmIzQcnL)11f*l_etDx7sHNV|+^`c65< z@hB~MlB9ugXWnHDsqYBM)8#u-m2>j0QZ`>=S4swZzT0n05p=v3;vhT89X?&{W^A=p z{XWCS?P2lvW`m0+tqiH0)LF;e6S*@Tdl<@26AZ8ZxbO63SHq-d8HdAs^A!OQsW);UOBbc zFbFgeYnXvH5^3ztOQXboC1i_F#_0{BgK>HSibEolo z+pqoePEjXPwT7QRTMc4#Rgvi}3F|zC#-sP^ZiN!GUdAQ9vB~N9J)AJ>p3zD7Td!|v z_2)gZk|U+{1IRK-PIMcYJfs0oBvZWXZbsvAw1))f*}zB{CnFB0H??At_7bHUpN<<# z`bXNf&afcIBPf62iAUUOZ&|;?A-@&5`)Kb77JO3w0ry?$d>OZk(3nT;J-i$X15RHnjaz z$iLAM*KQd7i)H6f_~NX&8s)lDcc9W3ia7wN|Lo|`bCO5{l2qMRzOxc3TD{0yelJG6 z5FWB~uS9qugKN@o1P*`RSAQNJHP4aY?Zrc0k?vc!2=Yep_^-obsc*M^(v3yL?96IQ z@B*(Nvh^BrKkORs9YQ9&L&2vTSq%b{TVGKE1S_jZb4=sPS3Gq2)AnB3jfXGc2%eoW zBHw0mmuspiH*zIzXTVr!NWliSdQrU20f;{ae(}ICgTh&$a})J;`?RI2_M+@WexBXk z8P4TFbe^%v60r*PcGdjpuEHm%b-&m%(}^A)FG`0#=BdRr?eIS*AmEKt)IcNnV1_Jo zRHX4@V9};I1WX8|jI6BO>w038J|~{1>5Hy}O0DI&?5Qrv&m+Mtl`y$T{Yb-4;DPTy zkR0f}u-j=7P)fg_ZV^Ka($;1Nqv|s(v8}-1im8nO!fAB3Hn!0SyPTK^y^5=G2!(0} z>3Gw`^W$i=9}H`TRH$0ypik!E$5Ok9cX2iQQ05s8!_{HduLU2cdxoAU zeJ~d0>cbY$5}~^T(31c^L>h{WC#g|6L8zN{*RIxN_tf`PZrChDEZc8h6t zeOQb`h=YDsL+G|hy`FSXO~`qUR()yKuzz%wf=8zyf` z2;0oZ@=fu0jXwe^@D?&Hns)1kJGGyQ-1ri%zunhcYUBNN=}JlIvg-ijJE!((XL9vI zo*npdfc^~pTVn2lVYhwfNWD_ACP9}q>pd4b^E7c1@-{$#Y$3ImH(C6IGHQ~QY(tiG zl5@&RO#HgoP=exLUE4UZH=Nkwo>oFOo)(zMYcmojiTYLY#k~5KCiE}^g>@*H5L}2E zz@a?fY`;kNJVU>*V-*(nFb^;3J??GNk$6~OJ0~MgII8JRt*I>r~+BdxKSZ z=&*h1AudhZVZL$%2H398beWBXcHpED4iRb2Sbu)%*+{;?oz=CPJ4CbE8xy)Aj7*#D zSJ*{!PEjH1Ju?sR75jmTo7(dM=5H^mZ{7@tEIjeKW@pCT}>7J%08Wk=~jnJRaL}>l^gtEav+IJJf)q>T zJ2+~v8C&{!tk1W`#{Q`fKHl}ouB^=2=Gzv#uiKx>@-FXBxlPHRJQF1umiap<+Y4p*^U->64ByFV*nA8mRG*5LQs&LPKfd7SQ0vSK#p z53*uVFlom{Pek?>vz52;h>K>ztb+j(4A93wepR5-5ng{RAZPzlvwFUXz!E1+GNw2P zNrUC`!LQNe#QzaP-`S_+NyAAKu7JVl%603}J=v}og^0q>h~Q-zrw|5%Yn;jdvzU2Y zr+T#v7=@|5AS}N-W5o$jllo(}t~zks`^Rc+>J`MuT`vLIK54Y|ZdngU-=S;c+p^IW98$ zVTiJ_k$Lsd)R58&4tf#w3`?YR9a~C5#Skxo?%Q~^OQaFRdE`lc5AQp5f;5Q38GfRD4o!J5r(xrH94c=21yVD(y%coY%EE{~>0@A7WeuGa|{h8KwE)i~5kB;FfgcB_Zl%&OG6!qEpLs-<~M{nzEdgZqnH zz=3X_J_86_AI}M3*}dK8xG_1q8TxabCEreQa4zmKc7IfO>-&ZFcS>(uJbjr`;#I$o z^%#sH`bz<7@P=<2K10o+x}^$a5uN$0#MOQPVpw(9axqw0XXSob+l3f=SWfJh_TMV| zu>g>N$@C+{(j8p{@}vJjX>p2O+sv3JtFiJuF=Th;4upz5kx6saWb zMJ2_vzEl50+?Qb~Ai-ukNN_a!35g5txN7GFu>-z}>S@q0X9LjF0>m8$l#gJU*uA$N z{i@CT=W%e#_S4}zqwjRX{u6tUI0~1EPhFPB*=>Y2vJSvw&QoSbw3^Vo7?&Y>f6{_> z^TD8BTv1Pa-Jn?}Lwc-g%0)((9XChV;#jr>{j9(qEqO8_B~n0h{jQ19Zs88ecXI8O ziQ?u5KkV%(#)A@_t^qEwC6JYjGHiXcvDgz?41u;EGPN@K%YQz3H63pz6G54NQhY%H zby~VdGZnC;-G>Q`>{icW=CC!`U+_q^A@A0EChcAau%`U)X+S=Z{LT|II7rhv*N>If zw;pJh>~ikD_s#g;CIX);-S{iLpN7r`ESoPoecjJ&lFOQ_TTYckT|u2T8uaY~j2;QK z%6(JBb5XMeE1H3SqO=0#d#fLl_>r%p%JK4jO`!d7)j)n)!++>e!GPy+qBwiywkYfH zsV)h0V0H$=ZS4y4x#xJ@VoB9=r|r?Y#*ydH?TYLZ-W^#R@*6f5z>eqW7=2<*^nF+D z`BEPnR3Rk`9mK3q&$!e6i5+P7GCI%$=7=fEr7ww1^(Qhxx{WbMI^o*|dILWHEJF@R z_5T|(-WQU*tfIGQqbYR#)XPVm;p~W^_>toCW7IJDun!P&So7ox_-RxId|Jq`{;4g4Zk7P zg~%J;W8R06Kik^OX*iaXzb>CzKTj9~h)hL(Q--h|p@6;CO-@GxJH8~0f^xXl* z*?0Ko&!rHA%v}Cq@7mAd1gqj8r$2l}_I$faC5ncYVq+wBdgIKO|L!kdV4Ebf(GvgK zkJq1F1?I?&MgDdtjb7bAI>uF)-$b-jbqRO%mR0ELvL{o+71PQ!SQ~Qi2!2uf%XnBu z@l4(|@6C1PV1LNF3r>sW%u8`Pc3ovV0Wb;ndt!VOIw3CUAQywzunG3H+x!~kU#H?@ zgR1OEr*_k|M%$EReQb{Hmy_;MHebi3TZrYLHNP6(2TpwRUF3$p6qO#TZ52IhzdY!_ z`!v3=6y~VDXmqq#>d5@_O#~7nm%+*+rr)B4Sk;8mR(E(Z7^(-z`cY}!LSr`${1tE| zZk?iV6}#dyL>npJ6e3Nu(OUx9TCDz-LusGjWNK#|=x=t;!6)VmT@MFCe&~TAjh$Gy z%;xnnro}{i-VzW+;VgSkphY9Ceo%Pr1@Iyn_c{Vg+X+@9S0Ihjt04_ehe(Ua3D41z zXJdV?u48_nv@u4}Rh44|B|BE-BETAF(Bra>8jH zc`h9rRi6}#l?`^K=gVynX7$>uBaBl$og<}&XaON^kb9Im>pYF9+{y^>l>_NmHHOX#&n{q5JmX1cylf4p^?LXBhb zI?b-Ykqok34w{#$!rF)0P1VG{8Husb0>kpSi>ZJ0#tm(Sj-|GEh-{Fy= zo;X_FVU?eTlVrGR&<12UD9*Z(<2ABXtw*k^25+0u8)jWX*jf9bwHnFDZ!L;uMX-n|Ke8GpGMA6!QGvW-R6#&C8<2DhyjGnOefl=PmxE3VkoeZBdkH!q_@sz zq0zeme2%sxsHHsR_JsQvd!nXIM!}-UYo@wvfnAjaA+B)%%c;EQF%V;CSwr{pM9MuK zUh|YgkpgoFf@F4|p@hZRte!@}MLV+1Bm2|_Ms%S?7>SF_hAP0#jX5sknp}J8brwI* zKG`dk*QS?TzcWokt2yY=>kV&HS2%w~w`-(hO{K8q) zxZ`lA-O18KWw{>t#`!}Ik`4)+Mc_p#kvsB$mI+^rX9PYdJZ=FQB^D(T?}vdMs46%* z4e*eSiAXotU$^8ue1-do`E$NK$r7UXI~$=U<~_Pqw((TB^gCsJobPh^<5&6=Skn;bJ-}lsj8%>?40t$iK`h#dq{uCfSLM-9 zyS=7-c8l_6?dvN~9@j31qId#Ws^b4=eeza3w72ZDcTarNSQ7drWF(^F-}y3~ zJvH&k=4m&fApKMfiE=vHCNqHj*i>c|^GarBU`Qn+D`;l=j0C43g$o{}q|;IWrYl(s z^NBoBZX3WfnPs-geJD7j&G0N&WpYg4AX`ZvSajBtz zLy!o?uW1MAw!j4Oyit@*su5H>r>M?~jp(U%rt289&)xJ?SwcRAi*FGv8Z-edo?N-6m_we zp_tr1Pci5UorMMYrsc>l@I(bLc>KDM2U4@>^EPmx&wS;@%3OD1(LAAi=a$bOsJ(E*?HIit;ibNPnG#n=U9BLb?t+F7S_G#0d zg4!_z@7!zS(E*Egr8DOsFg*-V4+u^PR=sU~&NbjmHP`TY$Fl{2od)espxXA*1@J<5^z%lj4_qR*; zjidKR$TTqcpZ*cZ!^;PLHGreFFls65WSmG8tma|I&7z_U8*% zH(GuhsIzEZ0F0mJ^!84LJ>dg(ce7U;{d#9Kuk$ZkXD*^jc2Nt5P$~Fjo03Sg9K#ANsNwsuO za-5s<7uXP;L``bS?W{&ZyvCg7#Tn+CgG2Ai2Ye5b&~2MfMhm3!b?7aH;yxThC$zGe z>~4UFSmZlaA3G$L&>mcK{dVFP98Fk!bptfptpnLTQq@vKc){}BXxL-zSwiFKYYHv8 zI+z8M2`d*9pBIo@4B|)FiWRB9MLEpT4E>zJi$%Qn!`O&e5BaZfgm~Wio(>BLxxjHT z#JBF(2R+rp_dW*#PY*8sOR1Vnsy!vMka}l)ufHWw5m?84T94C7Fho_cn@^E% zi%z@5 z9Az5e|B&AP_VyUq2-T<%?|}2l6?ZtK6r7BzRlGIaHee@r*{Op1&v)u^pCF7W(csMJ zDsuW9#66f<#^BnL8sa_M$LBzHye7W1Tc9DI@i@7+e{g$l z+$`USC85BpN_rK%m1=<2ICO|l+)pqT z`xKC;G`>pec;E-lxtGX|GxGwSGfLi8XT$rFBjXG5bur6uVCKvb-2TTORsjQ+J4H3s zJcCyMv|E_xm6C!nsm*B}wca-;G+5_qKQ*R(GxbQ3(HXZ7DM^?foom#ARe1RQdFAqr zsa8Ze34hTkoP6?Da>?Dy=>lRh;uYnhyo&pA}20NJRbGa z%|)fWERxI3W=AYo-2pOY+vxC@DYjm`Sx$#faz4tD+ls5^y^CvmL^inhAEy;Pgc8ZI z_A?GPB-aBH=g^VFCynKDdoEab@=UX2URbf)pVOdME2g ztKQ*7qlxpsW_3=s$B^sslQ@TZO<+6qP$^BDUA&%4zF;9EM3+;C(@Zx-FYg8Mao%mI z;1u+*aB^16GwV6NCG!-QE6!{-^8Uk}la|())JZZ7w_Q10$(mbj%aX@e-I)`yTV~oV z+AmiguB6+Q6*k*3#RAR-42OvRF=!_&h#p3fHR=TiS#0qIX-Dl}+b8Hgab|KmRieWc;7nz7`4AcS@~^=m_Jmk0Gwvis^Mu5&O6k8IB4K;C$g<1 zNNFZ6nc`y|RSGp@nB-*#5j=-kE>VV=zE}$cQAi8MJWyW5=htf`wdK$}vfwQSa^xYM zDJU7)so>4>tmd8Nb|W-)hF4)~(&ccDqdlc_=)Nw0s(f#a;Wjo{iMyzX7BF11sT#Y_ z;AygJQEPxuSJizxe~=PLae3(PrFfR9qp9Cc$zuF^dd+VOcb8h;riSE`hP+a?Z3G@6 zv76iP*h&8C`#A>>;r1opA@mjl@1?wKa_K`d`hhkQu9$MwJWHrk%tZmUl+fjp!v>(k zg(n|J4mIu^OnF9p&2}yxC-1+S`ym?l@@vlWEUlLE+I@xB{pPT1M}|{O0T>(Nek4&j z*KL&5X78;1^*~MC6q|fp6Y}+#!$S|15PjhTo`)yLvUMXIB4h2t+QYLMQJrwcUQDXm#gDgx8W^)7~O84qn-wBhX8*dxUIWnp@3cb3`Y>o1x9cp=J=Zw#;XF})JtA@`z z%cXFNEt@*7XAztzI8+$|4aamI!#q)OVZrn%|uz9BmGgaKt3pka}3BD+sA zAlsfbTSu03wzk@TTlSu?TQRhD`((KLw)x<0`szKW=4n5AN!q(%&FIysc=MUzO?(W?+}>|ee(G}QA;G)U79dhPjc9`?~L8WHHH&}!G1jLxNESJs*9ZbOn1 zWK55d39HMvR-^eptQ39TF9n>%S<7z4J;fT%*ky-8ZrwA;Qvrj?hsqjlR9Gc~p`XWw z;Sr&R#6W`2qFc_K&Z<-5s9bWIT?HMzC$9d!6h!IkEoHwbulH`R&%Pj7PwBMx&SW`< z>28?8(aAR$6FSS->`$Nm;&7wjL0;`g(z5QFe%*ez_KVoz!lA~c=@?9(e;&PmjC5o5 zEx_Y@sg&0OZmT*P^YkE{C_LY9=HIaU3W=Agvm+GTvF8AP&#iEeV%2q&^C5=ya+b z)`2(--ot~AlFfpVF0pS*1Kz+qHbQiR@G~1 zp;0^#L2Ioc<9Bhg^Kd0HW}$Oah+5C0ucD0`l=k9cU={biGSbGcFwF@PUAO|e(nmP{ z;D@`eQ`KJR(}m(UwV_E8>!Fl~z`7>QrtJnaLz{h1zSfz_z_8aE)ZS$ms)@P0uu;Zi z?~)Zz?G$?RQu2q|8tcx}X~|%}3v`LSdF&(Ax;M~w@E=k`m)k~!u_Ghcj)-M3Z*tkv z#|%7g-uw~lyyi9^njO1zdtyZEW(R_901DAG+n0S_^cge~9Y?xH9^x^fzZm1xdaOUd zHQ-(|T%ZiC--~24);N#G;Qx;D$p27H*NuCD!TPm&g8~Bl0(>0&ODtodA**_6$DMMv z>Erx0DE20TJ^m1IPF|0v_Fje*q%~{uxMeEnsps%hDLwwx3!JSBYyix4Wwx}yg)Lqo zsoa!%#IB`qwpi$F>N{6mra+M9(BJM`!lN`}t)*>P%BFw=>@-|x7`is`NS;|7pn4hw zwj7=r>S{U6196Pz6fmcR=@yRi>(w4h>+(;vdJHs;4AyT@V!YNSFK_mp_7%gW95J1J zfBvrKezd?+;StF8H|y5hknhI3k+YnUC{O@vU*_Ime=!%N9gGLlMrnpp#i2NU{NZtE ziX5adc>E3c^=e128lz7hX>L#5_^uYzG$iKRGu1ngwjr-IXHil+j*Wx0_-NItzK+Ch zg$WrYfLB>j1Qmq?g}qkW;x@})0QVXL7n}}c$5=O8Znsf4mHw?0-^JMW+&%UZia0D& zNUB1niKrb`bh|4V2BIOb18WVvL^Py%-Z8Y8x6k)gQvPqP;qpyr*&cF7o^%nxyQ9i@ z6hu;%$3`J3;d?-Yb{#m_iwjdR5r-@5A}2T`31Yud@p=i@fL$>7zDe2q$k z&_nj?lpQGm>O&->L3HU3c}(3rnO67Fj8!70^LR+j7rGyJ$8S*FyTEb=IKgsK#n2pS2(0T(aYI6lm?#A25>ZvgDI+(w<8aUD=mc zqrR=yZYhy&UfU@SJcF6Lz8lT>nbNB|=Ttl2-*HvYwUO~ImJ0Nly1Xz9HuEcToIW2~<3Y`(wPt@L4>NC~I4)WLnXX2=!ac4YtD z-j#Ubg6L(tI`R8TJb-1X1CQ0pP%t$uV7M4)nf9=>^OY7DLflZ^e!pZL@NP3{WuS~* z>#T<<%F>=)LeBV?TPK#E4irB!t(ww{7WpH`~mg<4E~qJLUW-PJldof)Th zOVg+2WfLEKDj}_=jB%j{94iOeFp_eJS4XxUsdY{T748?W*e z>7&7}T;xac9>WitNFLRv|Gcc_9wQeh1wGV3I;#N>L+WSs4q|;{1ckI`3zMKzlJ7aT zoa|bOu^WW`nP>lwp+XMMkP)D_+HQ?m%ami_l`8F>P5tee#C*Pesj&r<4BN z8Vkiu0RRiX6O9Lv4imY)dsVdDbEM#9*c4y(?g8K!jo zopA|}j9*ke^fz|xbsjU1Lby(eGH6Qm(PI6IYno3hlVEnH%?{Q*7@GkZmyGp1ptOM{ zYU0?yZ@H{dXPaj+Ui9EN%<9l+c-H7BzDc$yg2iN8BkKGq7;Pl~>{>-opTu*uU@0~q zcKq;5TnyFof%Q3(Y>U2DCuUZ|-ijXlK+}0CH8N9qhUMi2_swdF9rXN`J2ObHRG{yg zjl1YsH{TSqHR|TyEvnyZ&RVc_5pxk-?t<)T-Nq%siztg^x|OPpmnVB z{FQAE(iN3;-#FyXUF`ZiH)L1TanSr8Ga#feh|EKU68*m(C5`~VHi+H#2(hZf{q{qL z^?ZPmQ+uUL%QzYpH_E0XjRSa;*6*2D=9f$Y7Ob&Rd#;VjH%5)y_uFwG0Cq6Jn%%Z0JKC({9&}ugbB~GjFVNqB1`*%C0FGcI_6| zo}%=8D4@Y>zZ>_D%?!+qBZHS%OMXn;cqM@ojrx5XsH;=Y>SkLF52Q+>)tFDK&MX&5 zMVWkZLw`)^EPw*^=(uV9Q}HEB+kD{%i;MPYu|%oi`= z{G!U29mH%!oN-(wQ&r^jA~Lko6Z(k1^=;BK>sd#Qxo$Z}ra5?3NHVk~U-Q(6=_6r^ z*{ulf$-6u0u$Won`TfeCsKT^KKkI~Gf z4z5$DBry044V_X{ZGH2)Wt=FAn!k5&)mAeT)5D{Vb(_aK>nsd~qMG7%Q5epw#w^CG1N98IgoDJ^1v?! z_dTaSnYpIzoA@a90ho$O=vM>b!nZ`$WFEW4%)JP;fhVJc1d2Rzj+dB z$;Zz5?ajvcF#=6R_i)Z>L2?Gh#F&qDF!F?`%UDh!t=;PPPFf`i(^})Hu z!N=rc&1AugA-o4^T9faCbvukh1g1^nu55tnCD{3tob@OA!UZW@$t|Ie zg3q$c7i>!_J9y|z^az|#(>8&V@=H<9mA6tc>D@b@zEuZ>H&^|0((cpR5NaqU=o*Fc z9>hEyKq?;mH8G$5+%`mU7mzZ}-v2DUb^1E74^1zWWw2ERj7s&mxsPfSymU)Q>;%Bc zuO;btBr!JBHhuUOlpPj=xDlfK+gRrCVCOw6>-3e92~x}JvfQj+FK{|KJLVAWjniau4Qtsn)DEHM+#yf&*}NV*(~muSwzoudx(Xs}78w58sC zZ!b1HQMFpIE~SNYoJ-+#WcDjk>ro@@m3gP?X2cjp6V)e+O$tgPpbLReeAi*zTXZKt z^HW&-iEna6KeG}Mt+LJU3?xV0az2Ev6cws+#Ie&xPLOhnW7S(|30D>HO=COgvOVv1 zWfBLJWfHffRhhd0u5*Va?%b1`~50T{XPOPYV<(dad5kYs{*jr2cr{U~gN}B}g-hG*FJ#6U^dd=!eh3nc+iiMZOSA zfNf=pT>Rm}ZyVFVY*?7`x^-9epr*z^iUt?~{AhmAolQ0VZZ{GP@emH4;jkosBy;Xo z!=lcJXhn@AtH!PZtmrp^m6M~zkp(r5h0{8Y)FAZ0b;Es{mX9soX_JkcLZmHCw zDAI$s*>tMt&At{)RWe%_N3zJy8%kC8!S>k~(0tPFBf+7r0Jft@IkD*%;gF5m`A{`P z^KPAgljJ~^y1Rz&>}Q;hO0%rvT6KnlZGA0-I-WF6f$-MmDN^GMmJZ%wbM}L<7A~8m zTX**=Mrw)Y?N1Kw45~eHuxr|LxkMN3`P5iq`DdK?AE)A4jf9eV87F%a-x%N7wF4FO zJSVKxM$f_SOK?@%#`|z%wF44uX)p*86m;wp`^9VED;NF7IiBS$BYHf+I$^PY=8}lq zFst=y>63Q&Fp#Twv12-s>Mj1&iOvPnD`#Sf~|7=eMLFdfh zV7}p0VU=bXzybc{AWDH?F|O+~wC79+eN+vO>rs5$!tP?uYq4}c7%9~{Yc z>Gz4;PbhRNo?Fo#IK#Xp*SUe8+mBg}MI5}EF?=rjS^IZ}&;>1@5g8bPsOT)QdkX}d z%744xX1}~t4~@tTraYYYT}j$uT>xFId?Lh|#hv#g{|2O&y*(qx*}7(KIB0(i;>1-$ z`1x->4F3F1pUv9F%Laq3n>xj?6Ci4x*t=MUmLGXEF?#DpWL8;aq zgQUTM1i%RpYT*gZI`2-!$XW2}xbo#Ll{NdD2!)^97iPlG!G~wh`7r+VSaAf@78ipD z@JCon0wL?*m_H^=&(Wg)4X`;wp|3gEdFrP!UrwDh9@|v3Kj5EQ_?7i0>_=DD=rMLcb7oDh})q2Lr#aS@ljI zahagFcoaMCi!Vo2Z20LM%B%$P99Sdt#8{p#I?yyu@A0YA3UFVy89$n=jP@L{bl(9q zd*R0bYj$k2m~aShYHps(h38lfZpiF&9kT7dMqzNV1*Bq9CFvY$`OYGzMo|WuaatbR zG|W~t2})PP{`~#yty!W-j%vH$@{C2>81LPrgTMoICxqZo83u$0Z$<6CB=Y(&MX1N0r)qOct+}q?#{`!DzO8sx1 zNc9ZWyD|N9TQY|ZF~PCDo{XJjf#2ZTGS`{+9roGxcmY**|90@w4<982#py;1<_q{; z_u;-FYjKS)N7|V?jwi(qZxbw6-`k=ehMW8sx=uP2Gd5etN9HebCmjS{?LtGTL|2C&F?t6Rz!ryGPLH;Aq)3^6X}*{^j9= zZ3GdUn?Ke6EE|WH|LDFSjC_sCE~iK~OZt~^5-qKxuTnNgeRr7C+DVTuZ*|)hXYkPbF~WaeWNEHEGBckT!RCIvig1 z-C8s-2s@uXx_6j+B-tpp?v&+ddYF2|-|Sn0VDZ;nOlsW($NRYW4BccYiU5jQ5KA#E z?}OV{RX(*15J#pg@l3`9@&?S96jsyTijWZMzuOY3*L{STn3DYne$KFRtbd;$*?sotlI5B0y7w)oMlwD(CH8*6D(iy%rMooP!YMb-4R4 z`@JHWBnY8b3Yq9+xov$W3 zRkJ$^Xyrph4&%|KE=hkVh+fZo@vvj%Z@@){$6tUUb#vJv&&Spxf-PG5jqwp+4>^6v z-aM~$j+-_sbb?=i|G3b-&xvw|Y1%~sA&>G516upUqywhdI|S8sQ#-1NiGe(YA(uJq zLo7qHPTC}Si2t<~hC*LRk)I?A_PmP!3S$Q{+SgapP#Q0itN+D3t9&}w)4Lyq30KN2 zlIqibJv%z;*UglCKI5q1II0itx|5I~Iy}$C9A0c~t(YC}<#Ov!JfW>E7j@k{a8b?! zm;!w~{+7;1FV)xfU4bO5A;I-8L7TCw#{+8X^3$dA;&GkHh3d`sAVmapnX&(m0mxKxw}(h%wbYgM6t&OoK4Vt?iRo+7{@;%58dl-R&=Cv%4ZgLiotZ8jFaCM30pD(l$c6cI z@i_qw1GXD4h=xIYpm>)))RbVYs5Gksog zmBeZGtAK&#B~m_0kUBUWTBSNQCzQ^>v9eyJ_425_pJ}N8sP098Gsk$J zx$PYChz4+BK;uy!&UOTm7qQyMK16=YE0xcVa^vi1cJ$slvI;K%{Dwl{i7wgJ0Qn4+ zO?jK;bE|`v650vMyG}r2v~o2+~@zdgxg=m7={Kf5K+m$RKJdx3cI74l%!o@P0z%P<$?6xb8lkgly zhA#8NmmdLX2O0KXcwH_q+2D_>pB{NAdax~p$!pSHX)d)nyufiJz(K!;TDtc3?_2Qw z|K0-HmFGWFUI#@7dDpe6DmIjD%_toa*Xua>&vEr#aE3u5%2FN79V{x%^_D9pw)%85 z4@gPg+JNXReS6X}_#xN#4f}e9-S@|@Na!lZ377prF3rBsPYig2MU7r>X%mWmzV-QH z{Y>X^U^J9|ntl;{lbb0$w4CM$b(UKx@EwYedZ|S>p&QfhgFpFB+!&DSlC}COO;dph z;4)J>uc6p01iZTtY%?+h2wv!?Nul;e*5hG+)Xi3&C0gOooc4R1f?a5}_Pvs!=8vkI zQ*Q;)pu6&NXhZE_I)2#I7-%`0U+Ppl8x{#nqX#QCD1V{OupBp8>X%Q~Ry_-jwfOKq z?R8&zOrRK=A3BFI?yc^)mn7pB4>-`t(fcmOhl`dwI zb*dh3${_xbsewmQbNST=7jh2j0;P39#MRP)m+)6k9^z&*%c=9AT2Q_eDVTH$dwWSO ztoC*yR`c**PEsjtcHH+>KAbUQ2o}#zWkRtd&>fk3o6L`*^KX%#%FlE#95I&&j}P84 zjI=LVsm*`%VX?~EnGJIwXk0)Bn-YtW8JG25yET3No9r)h+SS&q%&oBX0(V_FWFT-5 zNnEdWHB2s-MEsMTXNDM*|$m42we}mkDd0H zkFjx3Y?4urpXDio)#kxA-$HMt{A1(C77wy}bB~wrjC{-^2Q3cy)|20I9EumXnphn| z28#cqkR1o}1f6|B>#==+cExiM*WigEBMI0>Mmw2MFlbk_ zIhCNay93a1>3~c5&w%TZp zFH1JB!YZjjCbh*r-@7>RO~f7Sg}~F$b^j*c*Y1pQW)k}#_u#Qwcr7eNa=>_?-+%V0 zj+_+fX7@jG+JcimmPfS~2i0fHhudhuDpBRnCRlXaiE^Z(%bEq4l`lm@1eHI__FBI~ zC_{5&K}D5nFXekN!+;HJtx<@q=>eUe!5rg`X@sx|gln)TRU;na{mHPk4Fu^x30Z1;U!E ztTcH+Rnu0ULLMAfi(QF7L+^0IL!P6Sec|NB@pk`By%!#rvN`|kN_V`==rRMIU;~jJ z8>TJQ_pB{6U(sCfH!FZM8^RQ30s>-0lZ_DWO2u}cf)w8i`%Fl+#^6q9tRz5{qWs?` zqUGg2D@HEJmBux*2H0?a%lEz&wjebJ)v*3pvZFu-nx>)H{&?*%|S+ zH!(F4JQqM>*l-<2_5zEoOTu5PwWOd2(Nv<1@@5<5H+!r3k>91~cAkyEbhz-mopzma zh+9j*1+*Q4%vmA7)eXd=-#j3+?3bW}D?_=id0qrx$Y`CZ`UmhRnJRl)bD`EDhd_mO zH~s)v=Xhew4iPoE<-Cnw2PMyGd%W-e3)%cf{EZ-mU%Dd0r^0s@aO=u*w%d8}_0oE2 z@nSJpCN+v!b>(c=9IxK_Ypu$8Rkme4CQ#E|+3ZO#F4HYXT{r1~?W0eQR)_o$F8Xu9 zBc?{eEV@LpHs#9flb*}vInCDO_kPG%9Iy6p1QoPHXVVoO^~5x*C~b*ucA>HEpq6K~ z-d(TOfC=a`OcUF_tNEqettD04h*mkFp+k8b5c-B~*;kVh-=NB&<(YZ+B7nlaUwvYs z7}w!hb)rP$x5i_4f`1~f2DZ*Z1J=<@3|s^Hu{$YuKHk_-FK$Fgt&(-{XOjxPt}u)p zyS#|#l`mQ2uQ3{;8fra#X~whaUorDyYHq4-$inz4BD(#& zJ=p@-X&GR{b}HhnxLM~jWe8DB^RZd zt?Dd@u*1rwZW)iB!tSBq+)15X1$pSLrET)|`EhrZHeJHm@$H}gN->hhnCztXONZ0? zf0BwLuNn;QHsd2yA{ajk$k*z|P_QYDWA9L}%>(bBg0hd9({M|&lz|xoX;gozUpz2f z6stmMangRe-xn|6$hqb0ywL~Th!|`aXYTR{w#$$f3Kn0AGT#4JPfs5y7=w7 zTuP+ftDut>8p#;^-#+1^$9T;ERch^Sg6JA|8ZJ*!`w{@m$j|W8@b5n)P!CD%`yFi$ zx3wuHF>BCsI5%!|?rY2tF5oOvR;k*d1UOXd7b)yY@P3X$;kT;M-$xx2x-^?6KNcO6 zcU+hiAtr~ELBv|e2kXVRK(5Uk|h&p^HXg`?~w0EWNdN#Ys}d` zWCnY4rb1D%YGU948v2#_Pg081@=>aPHU_@`S?8%}Qt^xaq=7pg*$Hq3T@X2*vN|}w z;Kd9(ap3H;L(J>UdIcfviD`~G>(?vu? ziHaY5bP0oAOv1cdXD28Ga-)@3OF=xHubub?C3`g!HQX}-pUanlPD6i|d}3r73vteMEjdXcO)B&EAwtL?hM7++?5 z#Zkc}FDQ4BLobrf8h4p#=IkQ-@-Hh_5|OV%cY>q}z= zrYBc7SA-EBTW_^i^!oGXlq|PrM>0It$MgsYO%T1?{mGIb2(uj8+W06vd|A#VfBDP&#Z4kn#M%dC_}H6wbx~N+_@5ctL1gBkBC+Bwc`BD z=*Gcz8j%?r-}bFN-gBSEIY)MEBJ8Ho^C&@&Q?k{z(_QwFOt!gS2S4{t7URhHj+OvB zvq(4Jr-5m8R3I&FA<^H8;Bk3A7|zYyi79C;VTlc`9ds7bCt~~cF~tDD)WLNSbVX^A zI!Nw)bKoC%kjlA0)!WxW*usTck?ygJyq3kM>I;{EIUgK~8o|WSgMAf^npcurrwR`l zWr3Sz=e?4Fm>1zzqM4)2(WnX)ad2?WOzFID7;ZXXmRzcQ$o>!M0*dk6;36Q1S91?b z&Ph1g?4|0rVXK1uxn6L;qnU-^2--W?K3UI3@~gYMMED>7t*_OEo&8Wq&LkiCNWQ^- zx5AlX0k9|ylic>)>(myhO}C9`t6?oBG|4P?;=%$!dT6o*$!+!FhH2!k*8g|rK(U}b zwvf1EV;&m!gF9J`ypOzy^Z@s-lw-3V(T}4n^tue?ITcUxpDDk?#r1(J-p-#Gry6_d zqqy|ZY+d7{e)JjCpZx&;*s4m_x}EE@2_<>a_#Pj>`~(zOrz5xe7bdfn$UD^bf@FnT z>NAUr-+#{QR#vs$09_1%DA@@xxrz)FGd1~^wy{7x)O^hO*z)Zd^?unl&E-{df4YHP zQu?ZQT^Woxkmf)pwJlLhQ;Z|YDtY_X`O6%q!xy2dK|&A%#>X3CQRH{3p!Ao3N#bXt z?fk)J`%b5g3lc-|Zi`(N?EyJ$C4FtF*q*eQo@WM;$WpyHk>UA1MLkfa_0l<0_olF< zA~~PL!-dK9Hq{|O`Nqc3S}IaIrLZ%9BFZc7oQ^447=wP5sp67^1m(nYzT?MG?vvb) zV%Q)HvzpCTw?V`ycy_AIe&wTriI{af{QF`)Qdy@*yM&93^dVm|ld|W;IHt2K z>ZSy%h753b&`JhYukvi4+{391&?E_$1JlOEw|^_zAM-^dO=d;h^{ohi$8|6lUW#2# zOy2#wYIXV<{nu8!skzBEN{K@}C`%8mLS{!s9z_yH%W@SzWXgG3=t}k}F z*uPCn#m%|;ez|XwM7+A3o~b4817WvLEREQk_eFtkE^R%+uWXv8DJ~uIjj$coolnDO z8)EKIJjawJyg_j8HVdlTBC)Q)*Ws z%8FM9wU7~ALF~nKRP709JMUJEWK=z)QndfFfh%Jr%EnZ z-LfVJy2I_DyJu>5vyk^uS=|Gd2&$J}mkw;z!zZ-&UZ_1SYqs^rDC>CV_{L@%>~eM$ zbiY>Vnv-AwJS5^@zE|;o`*~JU>%M2Y{|27~oP<6kivnb0l6*715WADpAUNJOz z;4Ydosk@%4@(udta4vkk4;ZoGk%}_loi84ctkWc0CeZ#xKF@*`;$*^TUDS<9jqIcr zee<0~k#Vu`Wh)w)flf*yG)x$zZeF@~po#|C(`3d1(G6o1VHQk|FQek=I^84+@sjlD++dzp+r?{LswZg1f&Scuc?fkA0!~@By?r_mVk}u z-ud)4)n5YaTm@^8eyPpC>|`UcTN;&=jvtD{)=}`AdVNtox)|rm1&1& z;~eY%6RLI%3SOi04Q|^k!&(GAsaiu?)24-rV*_(bHziPXX|VM;u7w%IiX8a8|F3qd zY8sUC8!-DY*~_P#-#M)$V?{s6(C+h{&2Ng%32PM4hx`ObS9wgc(HqSxs;ycItCuLp z`XAJ}ThCSTvJTB*@Mh)nM3J8J*DD!2KjB;{u2N2UMg&|vWhbL$%5iPMdX%Zl%>sUr zMlJf*pz5?a{h>?+kMI72^wilx* z+8YY9YGLb@=V#UU6&P7$iO1trbYF)f{CmJ%tsV9pKwyLFuo^WCe5Dy_2N$-i9gtnl zmvTu$te|l|#m|(;eQk|RY-L2ldB{f-= z&tD>+=!#p=S_gPwL*g*3oAcI8;s0c#e`59oT#sm)PZ|*)u=nz5mTyf`a{c%&3K^@STAo1^ZY^p=2%8GmK2B7m8k2ADm0{#Qz8@bED9}kTa{cAw;CI_}n z{B(k0#j4TG647D1S-<+1gjcFpwTnqIAYE{iAU#a;FxL~*6}(?jbC$r;7qz3}DyAit z#V}VVT%=|`w-h^XoDq>S+>D+M@SqoWAfH7VPz_kl3p%eUM!=4(;i+x3M3zC0isigk zGz)Qhzdnczb#GHisX6zQ>b7~8t@GHv!d}oPT=6sf5=o+;v~p*qv4k#Chy&s9oj&++hG zMTfDWZ2HX_Gctug;B1#v6C~-6LOXRc;s5#=q$jt!Eb(km6-W2|^B>RVy*9aGv~<(U z_SA9w@w7G3P_AO*wal)c#thb>rEW5(#4-D=|Io%C_-TA{0IPQgi{jU$ptrLHyBb;x zNl^vlGC7pY#YvfTVIYGweoRkbE{)zZxgfW!e6l4pOnZ}Sl+VxX4Qe^&Kr*V9TCYw-o5o&; z4=Qowp>Rg1C~zk`Of4{77=$n-wOeFNrn{4Ynws~XRfo*O1yeA^Qpo1wzT#dL6_4q| z1;hRP)rY`1A*cpSi zjC+XSBy5b^_uBq=M#Bd8d~~@JFtK;dM*{>B)U4 z+3L`~F&XoYlaMxXRS!0fxI^OZJQiTpIr>m^4m5J^BQELG(CFWHsc`bIJp0zn^0eYd z8KO*-%4wi{u#=r12l#ldgZa_CrbI+gDws?bD zlpJvXkE?foWV-+V#~nf?R;lE)kxHcqT(!S%W>qClCwGF zn3(gN8YbpE=fh@WCqBEb_x1YW`~7Kuz~jE>{eHjQZwCkLO>D>2^VJRcVxa)W-`mfB zR|;ouM>U>wHYFwV1Lbu&Db+!s6qU%v2Pqa|j~RF5ppzW*apw&)+`HzH8KENe$DZ6J z-?YR_;v6||Oj?>;L5@}s>-KJKT>sLGZuM#83(N|?z3c}vjoNvMsMd{AUu(+e8x9Qb zkG;A|+WCVH6&sP*&TY>NNebxs!zj<(0Pg4qt;=LYRvWXOAz;+ka3)38nKX{!^AA%a zYAbW3ype#q9&S-uP0~`slG-!J)NeNf=rbC=U~y36K94`62%`Sw_A8COMeFok?BAmN z?)~RwmB08@HHYUagt?4rCe}N*%w$k9=EYjK9+D?_HD)KP25zT%^(s@~GqTyoRONp; zP8y-M;w$-;=?~F9z%UNK+s)9W)cO)dmzvu_@*lZBg$^V++U|d9e(cZWPJ=d&8lD~; z+L`FX@uqL=PpG zL#HUA3!OSddxF%&{?53Jf-bm#KE9?Fyu$W6Y7D3Lk5hfNXw|R%INw{S{j7MGuRW)x zs};_+dcrsY*U^KZAYjhnanHNc{4iIXF&VjRyD4p|(TgfCGrR`}&R#?`($_VIzZe=) zq71?Z)&w`mXV&e-6uDZj(o*J|DK+`@@d%*JEVPfP?+e$&)M3kDXU(kEMpO+Bi zg-_wI0vth#-~MWS_Sqfb!`#)gU|lod4p}g{SRyNRx@9zWNho3ncoq=B?AW=&3MP| zYQaoxBVe^N%aziti4hSy4zUYUYyb2;Y00tTH49=?jr~18!oA>Jqp)=m@E_me?z@+T zKc&KxNQywwna?BqHjimtDUSoaE+Al}p1u%hUwcY`Mn5$Qym;zIBkP&^TEV6FA7L`n zhUHj1a%|dhTAlo{>iaE5K;yW@P5DBI9{0-l<=hj=^Y^WBmu{@Q8)aFvhK+KvSyQjU z#aiNJj#zb1r)+gnm*iiC)R=+xZJ6Z2*k5Jw5;*PH(cVg0%7e!NQh#Z40DwIl`0xxq}OU<>y5k6eBN~z-VS=Ext`{6dL)m^OF zg|x0f@#L7hFuz5oB>rXB|&T4vN{D4$~1ZV2X zQ07vMO{wD4OFi9u?7Zz(jNC}R%T#u4Z^}>I8l{P?af3WjIiBQ` z#hBwLZ|R!tRwvnHFWrj-M8N+qcM)0Mfi8Z)us zjcKijkBI3kt)YOfI~K5E_}%bb(3AR>zcdyapJ}4b29e7XXm<$E_hGS=hy(7<#!-4J z^JY+V;QN1MHVKITEfZTjQ6h3jkEyOzPPL9o{%%e6x9c0b)C5=|sGe`&`gOLt=%GpA zRdw{j&Waf-xU`x5ykVDYF~F#rfnMV_(Js+i;43>Zc=c|@-~2U=pM4?^A8{gH8G@I1diW>H$KyouSW4mHoN7Q#AXYWAAnBAZ+#SGobq z7L%OovYC7y0(~jRiF~fIN!3l8M}m`_rKj;=R&ZY5GOTcYuIo7rqSe4O~A?RWJ3sk;|QZ1#Q6LmG{9(_I7*~C zm}X>cp@! zsfn3dR;V_a!TKFWu6=nBSzwO5|AUaT#(n7h+AG>CCWI=|BE0`1qvaJCLu(zcgl|c$ zN&HVK1xhHJGQ0ODy6ytQ7DapUp+uQNjeNi6-9ERl{oFN`gE-J? zRlV0=+RK%5KHkH$Z*3Le+e;eR&P6iN?4R36lGs2&-$c$v<-gPC(EoAf1zDbln{)$byH_#)4f_A)q3=_v<|5NmwChECuO;Yf3WW1!a3nXkZ zb3a1)!Ob^gGZ*KNF!IAYFOMd}R^5)zRDj(Ixqut@{zl1^2T(I;cc^6RD;8GNSiDRUIR*k=CQf37r#{K#|gZI zekLzVkPWVV^osK8g1=GD*=lK3d)_DFXGNx^ zD1`ScX+{B(E0ygOY7S?9GTs(BFa-`n?qIc0HKC#yL_`X3y#r_ZZ)Hs;0lae))oc71+EdQF<&HjFkc+MQ*% zy*zjO+Ux7^ajtA~{6DQT$k9F{EW$k}v@@jK88tIkDR+l2q4z;Jt-XNJ_!fom$shc_ zH=Gh%(rC#8nK=%Mj#!kyxq#iO^FWW?5P0V-XeX~YdD@^Wh52rQ6Ks&F(*z&cG!p6S zK1@I4(<&EWXY}cKcdzST_Ir;=w<0>`-O9OP+NC}@QPd#Qq70reA6!z)#Ai9!%SZ&J z!@5x$5=dJ9Rr8F^z-kDjw~)Fg`el+$@F?`?)d8+vVYHqYoD8YhOX&g!L5DviV5e}g zGzW})HxWf>Vs!@se-Y)ehcpK0=XZ|$Ph zOF^WkeVgqK{PaJ~PZac@ z#8s3aWRc@|^ZtDfr)(WRo`xeu0lJ4Nho@P2pVwP0Ym9#CNQ83q$eL+(b6MDc`rMSv zgn5tbbfvh={>yX=6Q3Vx$PCJI{dcu|s+H16xr^h{nL{<$&+EphCk# z3XArn)QX&V_#epil*^wGnPu0_0GQNEp;(Nzr4h*{v#6kC( zM%6};5$FqxFQ7$fSdvlT1x&d<&{+}DQ{9M_X6fy5KK)@?_P~2p$O%<#n2i`8PBKbI zG;VVM`*Nk@Qe%B*^cxUM;PT0*^|gHaEqsLVQcd?$nym^meEG{WL9Y|ps-xV%$1v?_Q?#LElffMvw~PIStiYDq4uOH&<;PcdGsrF_+@rlpS;G zXvY^5wgf%NMe8Z>G24VH2|sHxEivTkH)a&YZ=cs)Xe}U1fg-YXA;twOK}S~5NQTb1 z2EKmqM)*uV!9qWA@3!L`WYcctH)RN+LNoM0u#cDyaGUr)5bZxNo?FfGr4F$(t~}L2 zmi}_*1!7Em!5T+*>omXTh-=*3)Fr>~iW{xeKl1*EmR#s#Qx3J@ddmx+h!?83?nj5| z*zeNrZs6I|5rDn5#5DFf2{>vyu&mcEu89Lw7V7I3a^D4b9nhKff4vz{U(OR0uHG&$ zt?Z;HEzTp5q=-gmvPJ^csHjnYBBFU{!WYN655IX&$0c(~ms(41m#s#^YGf{!uj%v{ zmZiFfCRKJtYgkGDm8gEf3nc5j(Po=$t$eo69%sedbK5KJRsip^<6$?7>~ipgulilm z!Q=e(6uAkP3u~xoU(=kj2SJ$&@7S7x_u)umRMA1VQc>o+2>;wh^Y9Cd5tj(od(-d> z1rkt}>9k>ZX%=4q?%ZKIkLNaLPdBj)2S0kJke+crFZ;~lMa04Ak2jplV^HXKL=k28 zd!0>?P)SQRs31Y z-$S<_c^z`gu$o0*{_#35>p8Aps`YBT#-m%ke8CN)anox&oMPkI_Lac+_XBMBzdOgC z0gsCG%{i_LIbMN~h{&s)a&0RON7cG%*KdCM(S9C;EG1jqKP>Gvl)G5QpZ|gp zfhQ%%QuyJKh90WZ{E?N6%-b^7mpv;e> z7Wv2h>^RIZb%U6l4c4amCAlsBuRczZLFuTR4F9NJ# zK*)|~jtrASV%fem&y<4_1Z`xh>cnM`C0*)tyLO3 z7->E^_Swnj&58O2D@>2eu9Tw(oTxVVqT~0N$Z;K&%e5_$DX;7W@YEag1^w)F7{1B( zau*2_Z@#+|@atJ!VgF7~$^V<4;66Oc(#sbuNuL*Ddrw9^ay@lEYXREXDia`(&F$Liei0@v}j2#N8qouN0qd~&yEWsVlyU}rMD9OxYk@1IF^unz@@$Yg0B z7bh08`vFYAcFhX5W+Yo4m`EuDx^$*@iDE)J7eySJqB}2X_~SIjw1HuL+&Jw$;IPEt zcjN4QEj`HoRxuRkIFl!`t#Gc@@VM8o$dAhWw4zdvcKkrL!tl375=mGBC?96g)KHGh z_egT=@+D1JP-T2estZmm^Y0J3LPBu-d)1@DNfvUfc1JOKjKT3OIsL5b=0rA+d;Il$ znCvoOT!poMD_2p?@nbEGK#RkZam(P+&Q(O^UJyj+@e&?23sCdZ&<3le3fRn^lH$= zlkj(wHZ$h-H`0nc0yqfzEpRB?;*`Zrx8DsICdyvGFh}b^J7zCTda_3`d!gU?K2}sg z+pNn;6Q_tI9@Vwezl`4>&p8%z)WE3ej8)sH(SYF_UE74$70za=ogF+E zg$n{ACE*d0?~QGS8{#hp-@1ncK=V!@gi9fTzB@e~mxZeazlO_wi9nhGioi&AEZFqUr*>{ZXX+`rIambO zsMQOtBj9}ww~xtE@G@+m&a@%z0q4dCA1!5pCabN5Q{B=zTh3Ih>{4cEe=H@ycbrqS6VT5I89eG%C()73|;*51%b|A_%x5L zPUzpz5FCaxz1q6Z4Gz6Kcy9uhnrbj~UT_u4@!Si+94#?khu;f5-tBTw49>~pM?a*? zt*LcoICh3-nu5w^rCxXDDfj~u;CGgoJPBwzXC=u;B5iPIk5)8AJajQpXJi5>scAMW zgL-xdOC$ZW5MpBcK_7TfczSJeky*V|)ts`N|CN#~F45>kL@n`ww%)_MjLC&nf>Si8C>4+20`I$`Jc=FUE z^g+8qzyPf#@Mch4*h}(LTll+K`x@YTj0J>iy#~2sKBjikea#4gc(aGAS$HjAQVANy z{IU0Ye?F`&dw~^QtpO~b0IyO14b0qm^uKRKlMj!|k*u}hcK*TRg}G1#Ju_Au*P8u1 z_xK~@@vjxm!%{%EtXK$&khM!?KdtevV*ziS?@ba}Q zKOi#Nl?z2c%K>!0vrt>eLv@e4O_eV>MnoG}!_-QO@n#!8tp1 zoAYXoOxbi}siuxU%~x_%?NgKtAvN4h|QlzcZ$bNc~bP9A~Xe6QOKQRBR{ z9$cA-*t{N?vZ_NE9(|aR6RkM3XdP}F^nh_6}{@k{%77DOsZL}J0pQS4+!v%ZGO7|y7t$EF+yJaz= z+JW(*Tt0IIpO<|5RQHw?<$X*3_eD2xTr0@Fu79r&O8<9#*op%WD(moQ+6Ld5>EV$O zetkp_g8OUc2uSx@BdRO>W&9Bw94;-MK0_OUk<+K%Y26hv?|5nrFb)c1yIO!p@@3me ziCHGvp&~hD#Yrm87q#bm15*orTla@mc$m|4WyN$gp8Xzy*i`VDp}i>g?0lKqUweNa zCdqnz4#vTT&WQ|G6o-O~8#t)4Gtw7Ag%}cz9KgxVK=x9-dn4hAXasuCG~7EfiRBFX`UX%p4ATzdV!pw6u#D`v`cxXL ziJ4BJ%oE@ha5mYUOe;SyEx<{;9Q+MGxIe`gguA{l%jhz=te$M4(rFyZ;kk+_n>&QS z`|YvZ!P^qe(oPVUubQCJDk&WxDOumfwc1by$Q&A}_{vR_Smmuo9>BhHF1M?W)^D+041dg_v#( zeHwtH@#O0R$$QN`#$e&f2#W&gxG698ikt?9oSTCICRZnZWn z>YsAPfggirEsZV5IGp#b_&FE*r1{L0A7&dS36BfkGJlrk{vF!eoxzN#fq;kc+L#dg ztM0p%7@jeY;TjcN*vGN3*@N=6nQ@a_6cfAq)O+S$4)#=;tj0h;6vw($M63q&8fXW0 zt&NPpo_o+uyXq8+dL6t?Zl=U;GRx`Uc8&yf@G{=e)v@hU5YRaZ z{Ihs#kE3#f@#Ii^R33v-`=#A0=(#7oywB%M&j!qr{eMbLvw{t(_Hrgkcrzhkbczsa~e!N*(}RU+Is870s5}>VszdfW;`~{ zdjaCw!q~6Nkiq@^mfw`Q^=_4T#xxZDpjGCJJ)r5GIS9nlVy*4j3U)YXqTdl@bWcHi z_dEH0wEds;O&GoU_hxeKe>W4AYjrex@@$^m-4nq_6M3_GwU!+Y-1@@%dry}KoBC>> zzHb_}accaxGXkjzwhg8^dUuWU!6D5D@PsNZ{ne*4VKU(yV$bB|??(!MvDGo!`}wX{ zMy{Zac}w**AWZIFx1Usqy!*k0EM?s9M(9dpm_s~5-N}3QFVa{hq%oHNEioz3lU*J{ zL2Ey)EmkXDlw^z*sJmZZTf1lV?PZqeqV11+JkD;RQ^vZ4{Av~XDZWd?T8QTSWmoXz zry{|N_Go7THb-r}MkS-v)df3av3*qwyE4GV95n(x5O>XRgFx^J_ zM_P=}L2fjG9GV*f#7ap@M z7j2iGX7_?X%J-V~IT!e{dWRb_3$&&NX^ zl<>5hY{R?bZ#o8(L-t|*oCP3ff9_?|GzEcuokt-`y!bYKwb@MVNO3>5C~msW24ty^ zv+hvu;5Peyd-JNhfM1ql0{NL|xRX#`51gP)ACTAkk6}6TS(ISY3mltt>9FIe^iqX zSn$AHbJh6xjBXG^Kih9+ezH(Men<)=M0Ci`O9M`uli zUYar8MvLwyznXM|TB+Qx4v((D)q)2Cizq*KC_6YmMopQJY&`sU%TJ4`_EoXxhYoB) zGMVGxZOSx0e12~x-R0&|@@;9yHuH?V&SI2tQM@Uo_{P(z$uPt9!!I+x$m|5ISs~cg zy7c+!O#TY-(&g|lKZpVD zwb7ARGHGSHJx~Dj^Mat=+HkBPKbKat&g>#U@-Y0MW%V&x&Xw;QY@J)ueK&Hd&U=pQ zL!)qMhZ21|H)q!h`Q-P<*o09REe|u(jJY^IWKX-S_R4S@dN;ggXP6&?xhNj(I9-mY zXRl19x1X12fqhBke&5~Lq|;|No=Z?4C5-Zc9=l4q4JW(7Nk^SBVl6~sG+W8UW=a3&}2#=ng01rHeL|pjtz2gW+DW1gFqw18)AGR(<5R}ti z0PA~{;a6u|P9!3qh`m3)n(yv1>BKm4D<{l!g=*bI5TZW(dwM?sFq|3J6-~RzVkeCq znvEE`;`1LaMei~%)d9AuQGkgNnb}B`zhRc&8-lqhXk5Y@XAUCuJU)<%jST^fx+%51 zqY=Lw4atDUeiPJ+9smb%3g$9j%(Yj8y7Ylit_()jsLF4b+D>_jW1H1f zrFDN=J;RQO(RD;r$Tvf=k`$H~%N{27{$E)%=+u8onuK3~HbG9=^PEp0r+srDbDkBR zku5(hQ;(IJw8+U^j5NO0OH9CP?%43dxPiVkS&QI$1wVQz~Jg8UokBA&-o z>rX6xKAUmM_IX)DW=<3QI31UGZYL!C4pa-L2OzYkW%ZZ512E zPz*Y0{+~~nwU}>~Q-V|r&V1}5DAqE?HseZ4t%(k~&1iplf&27^`Nt$A47|Lk@Ak2~ z%HTNe{^Qk$iywGRmqb8|?g>+4yET`Ewh1Nb~M(bS4lKi<;^RY3sgI+HPs;X4=L*O%&MPmez^M%K7ovi~igRTCSqt@acn zoBs%vgdXc|sV#`lrXvG1vcCz%i{(H3Q058O{9P8wjw;(obpwSG(hl5m_|zFU``Z-( zgY=UwJv1|xb^s(wSi=naNrbptK~ptRR|xM&(A>`%%GRugZS!_HW&Mm@cg%Jp%KviH z4q$ABNTOOKg@+59!5=57)VPqDAYIUaH1zR|rZplV(|noq2)l>oZh+I0P(a`L0V8L@@NU4u}~O6MV3;n>8%^@h(a50uv%h$@jHb=E=R}j_p*H1A(fZII4fl?8^+#mR48(fKvttsG z#Q~f~Hc+^kVACdD3_bh#ow1diO}+n(`rY1W9yIr|P8eT#Hsh_W77f8E!1zD5&Usf1#H`wa(b9nN)<%SU2L`ggTFmJ{tEL z4g^YqzJOy`_*(i~-Jt7ufec1D|2hCZIL?N60;Hw1u{0LUYgoQO71ZgmdG|7MG_X1XKhJb0fJhQr+z*f>u-L zEV+DO{xUJBZ@#hxxF;2IU>*8#vAy%S~K>?-w>=od>Scnx+JoC%_vC1e{7o5I4OK7ksId zm8t3gQwdXoh2C{U5ktA^3EZp7s47^uz(sp@Be@0W^V+CYh}AHuoEEbPr<-#T82xnE zlT?Auu+H?uZ|jeIcV7EEbwpKw7$K$DISCgPY6ZJ-F@dSXMQj%~?(-zdre&4< z2+BjUu;(6c<+pe&XZ|e_Y&7QlBms~_cs5npb~}vpQ3>VySpcn%`qBGj5`P&3*Gm*G z@!3SPzY_vuvDUJ-DZi|%#+6`_&%e8T&ti1J*yOFNp!an!>DRGOfR900M=CkoLC$o^ zt@+0|hE6)bwEo45mv*?S!fSD)DfJBZI(NBZN@<7mUzZ(E|H#%8EeK}S!YTdt}s}|bEu{|RM5>HQJBsknvXz_D`A}n#D zIWuS(R{(ljq9Q*?Q1`s@xKnza6cNG+|6PB{6a{9kjtwrz00bD;=TgnV;|%Q;T6XZL z>2N4ax?)lyzVfQDdIU#x#o&#O;fjRfe}F7c*bVc=F`raVI zI3mfi-jpKK$cHHNA6rK@S~FQMGp?ZEUk6@%gRPE08}bsons5TmG`@c>%6U6O|1p1t zg0G$kt5Yp*^*mypZ~N!B^Ksz?lE=QTVB49tbI2>whx%H&N~F3YF+p};Lyc0H8ef}) zwW+gu#jLE8$u)650_9%-`K85Xx!P4xaq64AlY+}YQG;SEUQacQl%{TyL^Z3uzSSV}Q0t1cu+_0;M3Q2^%)>#$pN5YP zcchvDSvzZ!TvJB^u3D_aqf?q&xJ)TXI>+wb*aA3}p*o;XE6F${syY@4_^(}cjD?j@ zcf`_g{r1HKAiCldeI|NY$7Xd81Klq!0y!zkRKK>jDqIFr#%Ifh!kKr~6|cH9U}d4b z`P-Jb#1&a|Rie)vW~_GH1>Gr@yLDdsx5_Wk0qZTubEc%%jEO-MD+-+-hu&jNZOd$U z_a6(rwZ`l02wt+ldktfo@5lDnnlK3h?CoS#rF4s0HDAC!B`P5IN3LxB|4TxkG{^PG zABduF#m~DrNT{%>gO|{nEyn0@awmGi;^EgcCUTtX|pc?HedVg>EHjuikJUT zB5HnfXXDhf=u53P;}K0N4ks~=sb$TU2Tub#hR7#Bwi7hHzbKCfRveZk(<21dU-lXw z8}2z8+o!-SFY(pmW~fFGcfRReAox&X~gwC2X28eFluoGb1y z>2rEmuX)S8GqTr`-WOUT=Ozc~CTH<2P&?GIA#A`Gw^X*M6=)t?=cYGlln$n?`8egT zkQ;Rlu|OHQt~P~F$aOMu^%prxf`yFRfEt-(Rwky*yG})9&%dzY5bN>~TR|H8%J+G# zu(8M{Jys|DW6X0KPxI!uMCpC-m!em28JJg-g?sb+rjLldcR}B9$+r445{Gp-=5SG? z^0w0S6^6{V62pF88}~b1CHS&tMoqY5;`3=*GPbMXtH2toZiV&k=DC5r#F2+vp-B|2 zZ$B2+xsTCs?-2EQ)48x(Ip>T*w{*m>zs7Gp9J$p`G)p{{c(O$QY-at2(;=4Tep?Wr z_D5DN7OGFs57x`Mt{!m3&*w`I&}_P0bhYEEjfv&Q&_UuLP~zr8sI$>3B8l4+|0d5` zajlvMq z4!@+vjKF1uZU-JOA=_oIGRYI^wU*owY9DXPhd)r-Q>;DBwe}8aS|YM=%3|#HJ&l~c zTRRVwOuw4`A=LmAXs7GRUmA)A+BGxCRjhzg6JI%?LvPqA3Lfdu{Qa;*Du7Fi8A>&*z)z@!mGyG>-@m)`ivMJw#xBq{|d##SkNUoq`!Ty#!GK8PuiDiMR6 zgNitd!u9;$DWSN1E}kSpniW3PAI=0}U`Zxf#o$1~miz{=vz6~^J^ z#Z&QH>Q8MV6scRk&@V#Y*_;c^aO1|lrrr>trM5MD-g&yA>Mwiv27Vd5TWLDumoGRA z9gAdH$0p|@Sve(cy*qz8_H-YciuDX{5*;St#9-}rBVh~q$J+R<yn`_w0k)>0top7jhcsJo%WxUo-XI<6Ov7rP##2) zVf)T8Z49`#-~P2ZpL$`FDjx>E)DIiR8@xD(^Ek)@==FXHih|5lMLiJG?)^mcqo%1t zc8`gVq>csQk?;FeKI430k+%t30TC2d*4D(dQ2FH&cq>HaUK!J7Li+>gHgL4P@sYba zmg^(J2AjDHXuMOKUAr18dl+;9Gw(wAvAWo#I=~Y+9TgB)6Mx&i#kAS{5xXu5X0Vy z!Ng?`(U0&+MgI?zvFk$6e4exo9!j~h#D_vHO|hRt19rq!L<3lR(u}U7y)K-~y3~w+ zC4zU>VE2<0;=MnLV2f-8-yDF*XGg-QsmOk!Yda~a5-YXgXcPPfnnpj55-$6tv|E{q z7OFj=_=ufbEBCSDpihR057WcfP28Wb32>90?5{FVmhYgAtTPXn$%prd7sMOQP_x>r zBr&mgp_O7XDLhR>Io|o8orfG5B!}Wp;_Y#WR*b>r2|B-6?qKxZZ9t#)XiWo4VU=A` zgT6FdzXt*<=I|m|Xp^vevs6uC6~RTo!9=E?o~XT@805Ki%vQ`6bhN_gKx3V`xuDAY zvhziKEc1~RHi#CJ?~Z7#vhie0Z_rN#FkdpiRD>J+?$@~4Y=t|ID`X8^w+*$$tZG?@ z_P_^PRa$nvDF3t((CcsI>>_bX$6m@REDDbN%>8398!Q@*t5c(rqB!V!=w3Vdmo3Biz)Ar*J-iDoQ|D%Pecm;OPUX}fs~ z6hp%oGl4&5iXqP(Ud-u`W<#y<+j61GBVthDPyDB*6y1t^& zKBEp35SK!EHdY{r|L|~GktA=MN`h(fMNtN||W=GH^=c0a> zoY2CNH$J2ig0ZQjTn}tu0y23o1oAU1B$t2ri*Y(^PDi6px*9QoTQ??IXXp6&_L@#8 z)ho_uap1M&yAJJyXKho7&MJ!ZK5&ATh~o4msw<5+{$a$WlP}|=sl@6M&3wAocU>%q zY2+B^qBj+PBP9QZH0{p~z;Y9>@}-f~-yf+r^6Yk(`Qg)q>$~7}#8RjhBcyDbokTaL zaajdE5wd^0B)k+*Dz+~45#%F#C{uxX=`%vZX^yUtyIG=1!eNYl6EbTYOO#1~|JIu3 z-t#I+01#E@ZC*Tl?&;Lz+~j2UyuWPEHS6rCdd-1C=lAS?JB#;!o#nO%->QiC``|Cx z!gbPEQqjZ3Gz&L?jf0xUV$Kb_ZL@QBB=5PN$h`PiF4;t-8r)fclid*&KF0c1kQd2H1%kw*oVg z0^ZB-$i9YsWPd%>RQX0Td&HCd_MkKN|0qCFx&7$`WaqeH znoUOeGtg1byqjTt8-;$?yY&mF1Uz@sXn#sj=%mZG8zI5yRKpkI27joJ*p?IT%WTs; zZ*Nw;$ZRybxFCr%{%hDx*iLV^rr`R>xE4Wrq*k-SE~a%qlJm0^6C?G7cSD9N{*8%(bBYI+lqi_F7C=3NxBcN2Q@(1P+#(cEQe zq^$VRcVb{VKImA+jJ7|l`_Ljmf^nvYvDp`Xl!l<3V2-TIhZ_*IK6@HqU8K4mn^@_i zigq3pt-n#nR{}|{V)Na55W*#bIHPv%}CA)CoyBj94#XqR~~hn4N8>GfNLSQxmLxz$k`)W~0QyF|N0g^?xcwZ3MVVJU58 zYL~J$C8Az3X+sD)9;O%m@5f~Jn#VuCOYTO7%kjvOU%JO~eZ;TLZTaW)2o5lOm(@Jv z4F|Z-lY~{F3u2r4Vn+=VxeWy`sOj90!Kxd8q2gbBE#n+5g*o#|1fO?n?pm?N`A&@b zJZF{VevfbA!zX(hh2lKBEEfwplZei7!pgfKDv#izxVy(GQH&gAB&eNo{S~&-EuA3N za;P33@XD9XLACaKWXFt8s(+(46|KG`z2r6gt0`D%m#aIja8$bVp;L^^fRBz=&r$aQ zF>;pYH}C$mg*=q=HLqo>pl;t%cK%b6IWOxa`D?p6`?7kf=cJ&-+Ej?_D@OU6r5fbt z{!(3T*%T|&!0z_BuGEoNdh@AL)!NH$F8Q9}=pi3&yrGy!9ufi38&Sshgc$#!q{lsy z(`tG!dRd)%EVS9s!EPa~>`$<7BFIT?9-k+Ne-QdM4jz^2oEf;-p|O&Y&ARk3YXUVY z14mn|TTr*owRD?^xu`pL7rSS;X)~_N)e^(j2ms{tddAfhjFX_ErfEq7K5FwW%fa-` zu^>#)WN6uvM&%e48;nIagS**C6zIO-`dM)M=2j1|40KD-ity(4G$o68SCmkCnA{G) zxcK%mAZCOEFkgvA$y5z)Tdrj5LqO8)PfQwM=-?~m9f_U9ZXC41XLlHGfcpPbOK5J& z6O;YF=gmF{bxLU@{(evBiBlIp_ZavV8BNUXZTQlrHu7j>r;PrV_^egkV^Ifa;~Y(G z9c&jIc(&+i=yM=~_1J5^`13N=D{1e<+Jo%w*YucM0h#JOoHD^`hiyu);pq|cCWqV%#meMwh4_{qoF)CLIWs@x5ETS@2bu9+%tt7{ApfHk~OyL#eHH7HL^@Rd%C zHiWP_NfC|DKx%y7Vn$cw34u+J<2P6jA##~t!k;(AlvU98b?_z7~vu&rE@-hTfUicuv4 zpudFV3*Lt2cFanUo5*LJvk1P4N(V;Se&S@Y*;d7+WL|u}z(REzT{fZAuh56+HdlyI zb!9h0>!QA1wB@VUzYD9I@JM(?LOfuDix|4N>S2?oMQz`S{jP7PhxbwNN-*sy#@;?} zGu{DKPHu1P%fte-awHb|?S&ZM$TYxsdGQS$6e*@zIF-!eV8qysEKLosPSq_wnpPfs zH7S)C=?R{^f$ebyJDX~i1FT}lJ3TaZ_MWFz*%sRODhX6ahaKCHUZBxs@FK#K;BYN4 z=3P)EEPO?I{_qP)UY!hjmLvnySY{v6=CtmDCT+iJpvR@|0N|7NmsPQQ0SDdq>xNA| z)sETlQ=T%3*muxGX+q+frnK2ZE2^g`PCZ=3^}Q zy|q?$%a>j{w~kV|KB- zZ|8q00^=js;}9{5qZK{y=e^9547AAbbP$+O=oSW|!fy1HDVUCl&oXasKYv^Q7Mgy` zPk{U$=@qjeL@XDC1Lpd<*B=i+Z|HkGHkdT(_Z;xz?tKER{D3$iW+me@f|r9Y84W4> z(3|l_YJy_lO6KR7FDFv70zbmW>gOC7;<9GErQAQh=Uv~>MUVjO2-iZT6CV6h?s99_ z*KS~si{!4!Qcf8nYR=i=JUV0I9+U1>U3P4byT3bls>d5c&qZj`nqLK-XY zyE;<3aJN`-uB!t^*JCt!yso~~HDuIeK1M(4ChRjAgjQkb5QLmv!V0lB$%~h<{^${( zZ7YV$XforQ_pqP5%3*$}-CIP^K(Egbss&^`V$%w5GPxPJX;k?Ml zq54YP`|&xKMD9m|x7NHleyn-NMjLqqTgCxLpCLSRPBcKbrN`CU+8W#1ivBps;H#$3 zmQ~y&>>ibn!3*YVCHc$?J!aYFP2g8!IL=EV-?mqP5xt^sV>uVtiw0PEk*g%`vG*iaU# zK5+X1G_X-=_mrBVeEZNW>nE@J_yXuQ$z-Rb8_OT40GPbW*NY8ug~W`Y{h0rcsCSQN zy8r*jlWMutR=G-;Nh%#g2pdDF)Fp><6>`pDiD8@591~exgbE{v(ZM0-W9D2AbC}Jk zVNNkK8Hw36bNH?6`@TNEzx?TS+w=K+JnoPCAR*z26W_8wow@4B5H*Z!!g3mxksB2G^UdwN~HI{GFh2tbTjt z*23sdJ3WS6qt;Z+7C5}6))v6Fq#@vLAh#fuUjf6xZFTM1)}BM>qfBY^!GPbf;xO@l zvBF^-d`dP?#Xmd126PCufTHimDS^~sw=U-WXx=7iTN7{}!1q2{;zg65`b)h8@2gNkK`#OfRGleUs4h2_zZXMDNH4Km6i*gm+n2A(kQbb47i@ZFew5xpH zY$x7xx3i}^)q4y|!dd@Dh=y|%B>A)_5T*BV?Xe%lo?_bl^27MA;gNQ@Ka2E6+tiP_+9N5hW9r z`0CU{u)2}mYrTq86B8BH0{y`uz(U$}b9=WmT*l8NmqGYU)r-qH*e7vYfSi1n%~M<@ zlhlBxnj_cUI;b`30Ws(~U4~6KUDcaj(|>G3jlkU$7j9c^l8i_$SvFW=bm(*lBC`al zoFM%&w@v1g(Cs&w>nGhd(}I+#=gf&1|p<98n?&#EoX>~xV;Lt#9q_YcT zmZC4Gy)!$qxue;y0!Y;6TvGqsad0t0xk|jO-c^{tkrT5LpW^&qB-W^1pU3Qa@-Ftk zv-InvD0+oIWAPnoRZW&_mCqTcpa(ZsWD%d*BdR z(!K5MHjN`;tNn_94x`zZO;gWW4zITL>L5J_gLu7FTUSW69^7Q9;U?{lE`6i159IAs zM8y8c^5|Prt8t18nef5hnm!PrlI-|&=k9VEwRCc9CF^$lIzV^QQl$f%(8t{hCMpqj z2peL|{9#R~**A`F=tC`T@aPZ0Qmwnq3{R!!2(>AlQa-J7XyH)v1=6?IJ~caE%sJu~ zY+cDxPvo?KVLLtrUDm7xa&@-K%XJ5=jNmNP;BS?=N))z8txtV3p({5vXLe5 z5q#)WQPj;0y^K14`4*Af2)cwW&A=a8ehxir>USJ%dZ(Uq)dOE_^iQbyzqLxm;p#@pc2X3`yb{zd zuSm(KMRy(ke&ueOwNs1Sely%-OtW5nPURxEH!`Z!{D>n-9%GL0sS%eI=O471nEQ#H zGrrN}Umrl9BU`y=z&Yy0i(Uk@Y628HpGdo&a@*YAi2FUAH`H6>ZZpumShymiM?$QU zb-0uU%c+{alFE|iIVL`=Q9ZWwllbfPO<)T#)(mKAWhxzhG}QfoE37taF}O0AE20A z$L{lh(jZkoG_ieur5#4!h&B6i{Lnze3}kWl>V)FwxySH@mRwxj(T}X-v(P?o!fkL| z*AnqJ<5|YqJ-3$yW5uiHL7NXf!5lx!8R!aSogTpq{ZTpIx~VY(;?SNg!)K!-H6I<6 z@>o>Ezx9+w=vZS?bqbYP*O3zLQ_n>)XBaahuJl^YdEb%0?%%PxCtJ1U3@LgZbJ(-^m6KnB{%#`YM8w$H}o2T&XyfA&akjA_etB=b3wi2;!JdbxdSZ+E^yEC zaN`~ATTi5c9J_09~i5*($JT4U>P4Gb17l9!ExR?yvfDk4K++g z-v6!Rlxz_U0Mq0H_m?wjorbZe8S{tedR^u6NPVQ1rlqlNzuv6Y_wjPp{%`3VnOWPV zu)jI67E_SrA3=HSbe1gdNuNJpbmO{@<{P;v#&YG^pnE?=QeUU0KU2V%m-(58^s+1& z-Kpv|Z48_7wdNEgfmIjEO`jC=l-W6+J1I69S$Ms3tT$0aRmsO<;?`#}nev{i_0Se_XIlm0Y|7CG4bqM21GBpmHzOJ=MG=)Pd`;;GdK0~b}ZQkJr8Qb zMc4KaCF9jp{$??uH78W4_OG25C_U&NiNJ}=W-?}p1Z?*auPX~~5nts`QET~%^ruOg zJa26Dlg%P(Uw}J3wCD61$%4$;YJ7=pGf#AB4d?@8rBP+ms7HhJAH%yV)@SS)HVQ^~ z6Tg9^Ov!nnn|Eim`Hd`O%f3D!&#&g`r7@gdaLmoQ=Wb#J02x?QCpbz8ACQTsU|k|g z!=u9Ac|vM?3r#uw`Tib41UVHd$IapZIcD`WRS`ese@cb!ramNJ1BIMj7cy5LLMq1^ z5~N!-mMi1GT9ZDlXfOmti#0+VdK>4dw7kd7;{sc4d5@<9{o}8BlE=H>iR9sbiR7R8 zB-D*GiVp6TLpGyR1ow;6!X;SBDz);H!s#y7cSyy3rSn{ntK6+5T*)0VBN~IP10l308(81v&dQw9+*<`Djl^0iF-y z*yKJps!|-QMm|J1jRmA7EXdrDRy&RDjll5!TFN+c6cN2L#ygHuF%z_O2U)P z)?Tzas2JM#*x*=%{%yqQHDOIw-NEfp!+!4yW-#;l-FHa(qF(o99wXU?W}WoC9le$% zw{Ex?dw(C)L@&9I_ti3=4?4Ilc-RhUnA(x?wuU2|9R-R}w@Z{glRXvYt+N4l&NIf)8|8pu(B-PrFqK%Mz74qP?%(!sNR4;w@BUWne6g#lM!@0lkXGl=jwJKV0{ zBAabKOJ6r`FUYstmRn+!U14@#xQfsqqR6Csm$N1s`)Kg2JUZs!2vaF|-Rr73BnH5)~1W0v&h^2==!*mEuBpwN-| z&}yX71Db^4U|L}J9X$7$_?^XG|L@FKnV~dozjp2`?yV5I;q|5*l#1@fJaCef6=>l4 zTP05Z&QR}V)L@M*G0eiaF>VmjlY!JT>I!?}@(r>(sjrSLa7hXas_fjm&D+V}+f1e<0v&1kF?r*WI!$lC8;I!0Dpqp&^N?8;a<5*;0Hmzaf~;(3dqoa%Gy~BB*inf z{L84u!MHR$Cr&;9y5~%r8LYbn)7f-rz+A8!y2H8#WMF^(44pD)k`T7T>foVcummWz z2=bK} zi5>eDsyqg%$;7-ER1p-zH*O=Zn}t6hNSO;@Yc?QjnTAwXS+`8+@Bty+()csLUctOi zgr=~1pkFJ2+qGKc(pI3@^UkQLrgQL^8e1Kt)BS8Ld}jX8Ukhn8%0=bwfsV95bc$k? zd5kbc`6p5~jxf`fD-F-Yx3j*eukdXFOY*|rG=VY2u6HW^!W3W53j2m`+-7I2Kond` zEtltRP<6W<1z-_m14-Go-=_OnWlRCM&iNHz#}kCZ*5+S3I5{yFEyp z^^Ji3Vjj#gQGMhgEP%QJuFbqQltR@Q4pTm@s??_>Unb43I`+eGtX%bvQF? z!0NK)V=p}lZTWnjavAyaWc|h^uYL;p7S71jQTImffq+%tlx?%TO@g4Twe``48DBda z5@v`~mCwLY2Ss>~t!yn^$j4nB=M~imH`nqylt5N~ldwM%8F+CJ_I;PR&HU8lOCkNB z%lkxan9i8lRGT}-Qkc{F^2R62Anh(t2ei?dncf2Hsm;;+LZNA7p}G6+I?h|sv1ER% zZ@Uj;MFXn;Lsggc?UX=djT-)CUefahH&X9yrD4`yPjSz~o@az{@+m$=*aeh{&J~NS zj=t>H;tv`!m0f62R$H}sXNNZ%qu(~RUASO`tCbHE>2|xZQ+@5meVORz{)$?e2dMC| z>#459Qyep$bCwBu`R4hzbT@82+-cskE}Mm3;Y^gx=yy*Mk>pOc%6cvvs}Yt&Pi_U zYBSbCf|YP~ zHgl>fFfAL92dk(^MhTCep$k#kg3~hk*SSxqU&j`;8*24g7CA3qnuhhpo!06*l_iTP zxw^Isx-)PI+TDSo!$qYf21U-DbEoGTX4ecQWSva4Z^s|(d1wsFVgH?Sm`O}=%godB zpo-V)L=xo;v^izJxSk6GKw0f$`ns+ChS*WJ((8vC$@S_OYe&2&C@dvo1M0`9~dzFC&pKRtrV?sis+*T;gtNTY+; z!iP_|JN2$mgPsq-OfUH!rO{@ zJHwm)k~kt{_DFD<$+L@#OcbQpc-sCTWa;0CpF4c4YdKjlaF!RrWPRzuRCYE*$zVs2# zO+&nCuq;vHssRgJ?hg^a6S7}p+bWfXGYYj~+tOv9F|JBjpR(TitMv7*#E2o1PP@Q( z>{l}v3n*``tkfyM)Ecrln5cx10&f*{^{oQ?K@gn7AN4qei7Rt+<~xcxs<&< zqgveg)~ru$*eIV~pF^8JeqA5d3KdY&bNT8co_y<4Pj9D*Z3^d035I-=j39g7T~8&X z`Z!aaMdx61&6~y)t@?=bA#i87KJ8@3i|UUZ8tZmHRK+kXfq z_fNHnUwV$qOw(iLnRP#uIbn+{gHj+vXs6r$3?evOlWHx^v1fawba08EJ=@lT1*Sjt4m0gc(@s}a{k6T$uoyCw7VKLp0SJ}jg zNrEtCX@*QP!B^mmpe zu?F!OJVDma@QsAs#2{k;jC=S_iY~~*FRW%Lb6IoAK#?S(Yq*+$dnl2EIw4p8xOfN! zypS>ct0}{3KQ6BB{Pt^BqVP8XYOKfcKf{>LFCw0%7q6EgGP5>oLer z=7#jp0T;M^pta)MeT@jQMK>k(^^$`nM`vXKw4?(sVtKi}#50iduFU3Z#Fa{vX2F0D9IIz%BZ16Epdpa1OyA zF2?t^r0BHiMQ!a{GSF1{!phnMTLzcu=PWfSJU+N^?K&i2ajHsZ{Sy7!k4c>7A(kv) zRV2N}loHsg_W0n2tBv2wWxiNy>yf#`)*e0KRmAr~&eJOnZv zOj}IVZ}J0W-ATPQ|6YFx&^G-}ds( zJwTce@&8<4!kYbN%%2ATvW-6rNE@om82Tb=)))B{x;7r%{X+i&VdZXC&7d+cs&Qnh zj&4J_TnEnh_E=&d9QX|Nv5WKVP3Y}-WqHPRn;FPu&mK|4z|hTfcv%k6@2n+&3SFs@ z2-4J3RB^h}NY=_yLo!DSOfrlf`uCb=`e&c`6j&e}8!!oP=IRnKQJ7tq%oER0MXwnK zu|Dtz>wKIB>k^3j2540GPxyeQ7)J7myrS=_P2`=T!lKhH+S42D>Q2Z`ZjApE?mtzY z`#k?)$DI`&KAA%yTM^)l(x)Tp7e}tT>qJ7?HZ}Id4SJByQ`gGE>)NaUB5w;Iy<-cC4hVzs_amg+wZ{U8(qRWHhA)9xnBqgVR zj5Yj?pmt0iY{cHyQ~62_=u=_uqrcwTr_x%G9w?c_SI)?w-m~xF$iBCqj9?0EyTZhk zV9YWb%qSqkTzJ=sml7_OLakICF9EbAr6R0{n|+nb?M9_Je{zLS9d}1k5VdMKD&D>s zQ#6|-_)-@k$veIeE=TICe&!#G=&t($RSz#w&s`6yQ?cba6kZq`_}w`Q{D1JzBm8c+ zd|Tw&TUY23cn*`;Epp!MG~lC<5=vUQIungPq@&V{covTXx@oD1!-vR5Woa6@qok8+0JV6=r~ z-?{+;8|QU&>-F6m^Gv@fb6)X>vp5R*tnQ`p#C!Ik$cii5u#S0!geaNX zMspz!@ZxEaRa*GD{2ENwiCKZ-sVVH{ukC5~oyLrsKNg;^6^{$goLYYKVRHtS{4N^7 zS6!ynRm_dw*BKtS#YcDIfNXL09`-?uW^jpW67|w;QZ+yaqM5Gw_nA&|-mP5oM@ZSF z_sIA5at343^YWPDYwlw=3PB~sNjK9n)Mjc(@IkGIufy~h1xESBmU45_JF7eWGFnsH zhv{a9t`9=`sR6bQ^}J+Mx9^WJ8pN$ZJ$~71tl>CIkQMTBRIeksug7n7e|dYjSbfbk zowjqV%6DO%t7)%54b4vU^<(u5uPEV1vt;I>Y(S@{5)Q)XwSHAnjwtSP_<7SF*YGb)-j*vK9jtl=sxnsj+ApQdg;l2hYgigu;prxzlz4`71}w~rlfo%GS@ zRe3S>Q!jCE6Xr|Lr|rh(b-BCLPucV|{A`Dqth%8p=q({xX!GxtUbEtbCd&cMIm3XY)i7_2M#cVURy)K2Uu&+57=P74DJT`RA3@l?) ziXQBaLud;y-IGx~bP*+}8_dG{Pez>8QW>n);mn2aA|e(3&MiToFopO(lnmp1E`JZ! z{*kkawT9?Uo>n=YXh~|gM93zE6SlsNf|d`bpEtl$945f{d5B%6I+Gd}p$(@CDe-G<1x2W_*$E z9k=%6mh0Dzh92zxTelU+aoT#CSj|%i1S(MZr8A52w9tS`!A1T+Q<$fh@#oZfb7^WU z_enWM*6pHmQR;f6#;yt7_>JlkSyI+wk=CHxO9awKcnQKa|NqnZ@I%bkhjm7TrGXiP3aLk?v6ltQ(`A}aB?AZU zFZc<;o28iK<rgUzcMVQ4-lII2g zf$ak08@6_1aiZAhlrHW|c+WrV9RJtmcImkXeNypA4YQzE=$ZJV#{+Mvn>vojKq-ig zTu(i2AAxLyhsyVXP9z}oRf=|QYmY`OLOWQ;iKG*zFwQ9Tu<<_5>SpPNapI!Dt8l3& zmdiKcM%){(Sq&}otS`4;=FrteJSN=;ACMgESjwUfcHY8F=l!{6H)8Wkc_Wa_2T4Kl z*r)N!rj^4k!)xXH)B)N%YI3TCOIj(D)8Z3eP1loMnxy3e3Zh_zyu+T5LVm1n`whz- z-sp&2s6l4)$#|dX?T2vym(TaV(Jv1d@IgahomCr4Yun?^_Teqkw;5eQtsfb*n1sLL zdoMQs?h2&+Usu43CC)mG3xy^_Ga;{L?2c@((cu2#W}rICq4A31L1y+_l6;Hy{*j=0 zBJiqKfoO_ukK!CE+xNk!bBGRwZQ;sFsDM2C=ErcA$fI%`tEl=`_i@LKBz3^NnS6=7 z1K-{&u*&w@&&*jiE#x(MNiH2nzEcW@{L+qLj+FA2)r3W%pwqaSe!T8(*4n@*bHB0l zmc23EF42mgWPCm3`MVx#2jzdfm#u~3hkdN|@u@ZTcn4b}i+-GQ-qX9cl3eV0@jB)H zmpZ3sal~~0y@?XRqhf6avW)qUD&42pM?g7*@8WE`2R4TOHie0YKN`~y^_kkt-J~IH zyAqaHekxKRvl=S7m=M;htBWlNnBZm3&yROiRrl@B)y>WPi+fv5b z{1oBbJ6&lEy#1nID{Wn-RTCu^wDME<=;2oy`(sFfeE&iu~x{irn?b znqnYt0P!k!t z&@1kjw#sJ*u0>Zwk8nn76P!USWdIoOD1Wn3uJeeXd|j#M*lMF9%CUl{mQ+~hl7JTc z5Qfqttk@?SLF9{MeX>spiHw^a2DfHNNS14*Q%ATK;X~JSH3Cb-{aNaBumyjIUXyR> z6F$B8wI$m-T#gc0a*nHdrs!^5>`r#9#y?QTvkduFc0EBK?{7H8kI7-zv%vHXc3wlhKDBNd)8w z738AAf!cr`lCWqVw*BV!uHGvsHR1JAWErp)&>p>(9yJ4>J)Ka|S?H_;9Pl+S7nJ>4zEN zBLE?zFl1!bIMQFTI;4mU@0dC%xT!73(*A@xvP!0^-i^P-Zy=`#%e_}xD(yEBVA+|? zli+&c0x2;MKPgeyIYfQG=%iF9>VuN}2FyK4JwD^|QZ^9z5ktfCf;x!!5dm)8c+x!l$IYZuk!S5^rqt`}aJ8lg&A8Dl>V zKd%|DF^%AUw_UAY6Bb=_>$B%KHRjtt{Kj5CYOkYDw5W9J){=Wx25g!y&s};QMQLzi z`5NdzHv}yhi}=NVLUz63pVnb^o6VH1*}vb`PCXlQaihoiVpt|lA)>Gf*SdBX4tKYM zuYJf&Qb>pm%*48W1<)TwcrSIu`p>YPzR8y~xy7}XB_KO$fCukQT(R{sdZFuv53gpI zDd@rh)?N_N)YzcPCSpZG5b90E; z)!2C}4LvZF7hmgh>2em@V*M1d>l{`4c@$EpuTxb`vXutMVs0&lv#~q{>9vqmj&>J-8N!lGE>sM|s+beq3Z?!?xu5{EJHo17(E*3Iy7spI& zNX`q*o2>`dP9PIC<1a2u!(MCt2(b;>e|%XDy|6y|)?AjCS;e0pNI<$Q**tQrTuhGB z?Ye=72wqlOJsn%8315md@t8VD6+qpYn~_U)Z+Z}4XHS`2oH!e%@{ANr-E0SUhF%x` z7(^r)6#{g1EDJ43@AY}U^)j8Z{&v9?lGn_`F2!c-upDCro~1Gx0Yzd832VxMs}dU= z-Cy<_{lb3{f)7vT7FLK)`xZa^xhg{SWiy|3NcPcmTs+-0vq?dd1o zZb!)mLpQVq9iKS*egUB${Db5M6d|vU=tXS~x5VdgU!cKHd|OPLI~975_xTutQQ!bj zh**Cnqh%*eZ=>1k?I%#6Gi%dwC8##QC@B3 zPn#IGgR8`J88!HA)QNInkcxz}`ZkvOy=H|eF1evzXR0p# zODfroaKg@MvdQFTJ1j{41(Lf(I$ZQQ+QAh8L2ab^r=M|cki`tlTLRok}CkoDi>dEr~pj?cSx>at8Qpvy#f zsUtxp@3p8o@Coe3i3Di#v-2!kRP^-wnU*vDeJ708$yCvM{+hX{7*kwvCO$|ExtU}e z@N`gQN8q*NONR}8*n!Ua!}Pjm=z!#%d8$eIPlWZ`jiE0P5WBeQ9nL85Y22A*GShfHV+fwm#1(VNYA*t~?<9rmdGwfD*3Bp9o0Pd?v(ju@@)B zyz&d}7n!N%I-D6BUwfi!x%l@ios+k77AotbxC6~YB{=O}Dq-#UBn(u*dgF+Z!pH`c z;WD89sSZ3JUbsImsLyeuw>F-bg@xGZ1nnc%RKy&bV()Wl3w|tXE!?3#E5xyFr9(7f zz&i7P!no1+QQvNq9#M&PMAlfs`0^mM7+R!V240w{%5}MK#zyDeJ0T#1k&Jz?jfx(Yv)6XBn#>IbdL-IZ(eR-7N))Ee?T2396H0qY74^L!e&(crt8GFsVqd4ZO56^!H5CZJEyLN$|6Sd^D zWI5dGe7PP~oX+=j9r$wpT4!AnTHaCCBH_|-m6DIt>K>x!;6a-Hi68VEXXl6=hwopn za?2c59{X#2Ga79JaJ6CNzL*-Afo5dj=TuM;2Zg3Zqef)$pG3zBp|7g8tTKdac(a(RmoU{Bfy5sRpCsoPGkC zZ*D&l*=USv7HPv@T;($9W4RK{s;6aMPK59x)o6HJ&~X!g zE4!^sgq+$B1CkCXR+tL6{U+aBxDZi%nEbV=$YRO)KxmG^Rkv^OGV@dOBh$^<;DrBmzJQ;l2Ysj7yp=! z_KI_@XKHuK;_5mlEHjw>cS*Xqq44Oi7{M6>&DDn?OU4_kLP}@(Rg9vVwA&;r(Pt$ou1y^sKXC0o(Z_&s{bMEK!T z|J+X}jsMM|r{YqZQ>kgVwAaton~`$o=JK?LL;Xl~)bV>5Let6Zqcv;QeF8FHnN9tr zp2cj=TMX%^oe`KoI})p(uQ+8quS_|jwyr*zVSH(>M6u|$M)!2kCIBmKZH7=O<=1>fk&*#!`B$Y#G!;lRK_;J;^~#mrP?8EDaL^1C|VUl$@| zV}3yS%LWrlg>g0GKYcZBXK8n|Z^ZQ^_A7!abk91&pA{Mj7E7J0Z3IK#KR?b`Dl=p7 zl6}8LM&gFtBA7M=Y&68~g5=WsC7H4Cnirb3KrAm$rB5hPY7*1Ht4+ldQ();D0Qf2Q zM)!+HfG^Y!F6?F>l}9sjzh2A2rtPqt6c-S%8};w0K?`s2Znwr9#@+(u#}`wZ zlBt*FU4o*@n_luA9!)8Kf&E3 z#_(pF9*2^Q!IqZ@i70KiL~4fae(Z<=;quZuGyl#{q0G`S85AX=d<m7`MU~7reMX88@l&^+LXTveeAqr#fB@Ff!WBF2(h;qZQ0|t=C@me@(DLgt zE{TYRFl+2-5`^}TJG7334yrfHW~WrmTXy2>Mm29BM zuC3`%^sm1l@km%B^g~a7`#sr5@t4iK?r1`fKV{BNmgzB$-dFDSxwmEImtn59TqWhP z5p7A4zvS}y^L`Id8tjyTq97}*wnhPDa3#|0rEhTAFjIS(|rfZ6BurMN=GB%Fb9B>Z!^Be4RUtC_Zs& zs@lj-;Qi2~$|b1dGrF@toUAi=uJU3uPsLx&+wpU_bl^DHr~~M|f-T?r(vZrdR#P2Q zsJ?0unZMAV4RsSVS7$<>m@-tF_4L`Bg&Ro6+zEcd*24>10r0-oeb}Pu?oR6VOVBJV z;4S!>r;$COIqWJfFm)>?HBA9$x(m%JHIl@LLU@YD5hZ_FoA zpYQY8yEBP#{8U&L|21}$_-Rf}1v$KTBR!z;mb>2CYQ~|M3|Qr2Oyj4;tk9D1)zfYl zE&IHkZnbS|PbJiP?%i@Lb}~gF(HS;WJH*iG1eSqyz##4e@C!H22f6hyG&Vq+_o?A` zAPxBsbN2T~o=*{tt^EF38Bh++o=FUjbO4^EoH3i<-)qziwvg>V{6O3neUp_lU-|1f zmN3iS)jAN8I2bQMZ=g3a((d_;wz$i7E7!mG|DtIsEXCTrQcd}1>!9sTqp~Y2b**Tbq6@cm!Ib^7<0Rf-UbZ)eu=4#W(mX;?vTba zSb7!yb!X#cQ!`mcTHx!$dBC39l-V~TB?`0UB^lO~%>xD@xe~}i(Y#*Egv-H*ofF8H zHPq*fRK|C0P@7}aRv%;UM#Ewjxd+2Do$mvZ@aV-0kKv4S=J~M|ZT$eRL5J>)^Dmbntk+@t1Y$qc zuB9||XR`ta1TTc&ECS0rWzOwrXv>(hTMYgT2Fy+<_xWhbE$(Kfvd;Ew8V5&{Gc~MY zsQ#7Q#fFA+xqC2~DxY=uaa5ml*?Rs9PGlQ!bQrgtS@0LCzA8ShM z9;$3XAx8`G-ro~i1I0*v*F?2*TI zQ!8d|N~gW8s%~#B*z%qS#s8I}I$?+|hY0A2P~ zYOTwYi*#ey`koPOQf8G}_XEP^jR)9~5IO4*NcTr8{u5w`*gE1{)9$1KmexSX?*mo! z=~dB@BOru2m!}jK`FUHKRhr|vUG9#ozg^~2mD zTm6j7qBTeeJR=um7#bTS>DHhM_u0DdbuncBbdAF>)G(rZIQXTf7>bnS7iZt0f5dU1 zq|!VtcDcJ??6)>f<$ujlJvHXlY4~*2k(p2s;wV54Q3>vyzBRKJf;EE#Lq9-k!Cy|Q z*rF1@=X}KFLgJ3>#zI@VOO+IZ*-nDaVTU=Z;ObUA-S?3-O&tU8wxt0Btw3NNaJ!@*Z#=` znXtDJ4Ytd_lCKG?cTCVho^Zdt&c zVWHDM{hYDX(s9Kk^1HYk)Rg4RNKHf)&R<$;$$5NHJ*?V${mds-ebi#VDG%bj1mcA| zFM^)sIYdHc^=71gybF%#zuX&mhLxrzg^}W%!xXdkaL#jldLzlmU)LQVQ(gy3xB?LE z90{CH_@L4}*QO-sAKB_uwO$Ie&*!%IJGH%3O)0rqV%upq1;)%2nUn-}R$DQar42LV z-Qc*14iGfnaX`7}PnU72dTOOot&ZTQw5myf7pO!Hz#IwMi zDH8Qyn~dAD;8Xa6v+T!mB(l+6kg=&KUz;?KSC>Kc#{){Qfxmo7LFfV3-})uWu1?@( zOmLbrp{!qtxl~AYNLiC$t$ADEQeUJsc12cu*=h1b&yhfKndzIKdx(iO7Y*OkTp(qA zKgF)dScwkyBCJf{7S*@boD?(H1L(r2I%(RQ?gDWOcb`CAe6S^CD$J#=>wWT#H|=B| zYuhWJw{Gxl%fiQJm)o_Gn3~p5*X;PP>+W!pJoiPq*>M@rLgSxlEBGF?a%Qgrkh5Di zB5b=f4C@flh(qYmOqUd*JlO5LStkBFLda1X=)OlZa)yKF#w0hWbW@#2K3X&{f-bhr z^P(IZ8qC5#*Z1)4p4V#yjmQ;+S#;ef4f{&F4MGdy%Jar(RLdl4`Zuf9h@!ywrxN&{ zLaA9SxsXCSt+><0MA|DweQ#IfopZsmuFlTaRxggcB(z zFuJWf*E`;rHid|+cDXEJwsJGrUrW*xwV%l?g%^VKV^ut?xGzw4VM*!Uzd5PK|Ke#r z9BR>nojoLhz-aR$R1mL>>_EY=qH6%sYolESt!BzMP&8arEaSZPN3F7C3tC?&c>2|C z0B*O!DP(w8%BD!BPv>PbHP_9g0-bD-|A=bGZk8P`Q}xK~n3y8m%j>$1mw@)^0N=*@ zg$Oi0Nf#A*CDW2nix-(!)Ke6Aj1F7mb!d>ntLv?|CbnjMS+!T28}UNK)tfie0GqP} zMy3_ogrpAI#)h7P@z$H#aSRaPU7=uqtY) z$X~X}1pGY5oK^wq+vnmHF|WRK1s~cy7Qx|+W`u~KN~go4e3$pOY<;FH{H>?Pga44b z1Avu9bT+;coc_LbRfrNJGcZ}b2Hl^zQT*gYqCXWyK^E=(enDO#E_SUjZ0#It^Wn3_ zvz*3JWU%qX2bNuP==I@!!-qPaYdqzWxO)>TDRmBq>$ZC%vU#Q5#@CzJnibL^w9_3P zLr;ZcJMmw)ZA0{r5XL$dtcudQ%^LrOHUD)c4hvyT9vFazl?Z!^1aR&KVh;LkuX2BX z2&^*`S3PnL@h1W+8@KQ+D{=i;L22s&I%Q4Kch`kN^P^|97qpiU!QX8FTSJiuFL=q#^(|-QQD#PJ#F>~ z8%$!k@?nJ1YdaY!7q64Xc>j3+LsBSO^G6?k0ezhPchw4wN@yRhibds4aqaH$OUwTi ziJ$u~roLRdJY5S^Jc8?vasqn8EZRj*ukCIGk55}K-~p$mo(kZ>Dyq}g2cm)PiN z6Ow`pdprvf8(*K@zL~aq)n-{n2pO+H6*D<^x+96NU@816*I$vp49Q`o{J(sOH=1cr zA(+!{S@Yp40bxU?GSB`$w%$A(>ivx$PO7PssGJf8l}b)Z$i5YoWUHJ)7-X3o>loV@ zOhxF}BSV-;Whwi$$Gy&o2LT&HMd%->>_= zU(2A}?p@Tdz^?wLxacUjqf<2|xP%LV$Y|Nki^@>mms_3@p(YIkQ6$vKD zh2d;)<+Wjt)hR-++aiR@O(y&y;@=MFiZ{4QhV81XYM-v^Z97D|mvx)~BPyp^&iGTs zL0&$zwWRGO*XX|R*TC{*rOZus7zGH2>(@d;76kCer|s8VzQCG`%#YO zC1!ts%=4gPmLTh3-cgnUP47Fm@69fDQbhL?O9%iOXR}f^pKX4bPCuIAP}+QsAsL&MIFiK7NzW{ zJoo4@Yk4vfp5F|^oyXm{)p1At9Qn>dzTKUw$u4G~Q*HU1@jj>T{J_{K1G^}hZ9Wv%rAInw;JkNbTUId0)ar{1e~>4 zpo6{OVFCMXwD;V5rS7ttea;<#Q%lF0ifiS(93lr7vK-uiLBPyyM%o8*Ah?vBGsuxz zu27ki_P%T)SbMbXj~2g4DJzblzC&gHnpyL1o&T9n5{cUcjO*`N$@CQfh;0fYa0*Syu{D1|gMJIPH6@ zly&3>1%?)^I|4zvu*Ug-aUV^vGkT6*Vi{=CKR5M!Y91|{f=Vd(6in(Frdg)JIt0P% zkzxDK5e<`iclK24(G#m*%32%lg)N>X8|=##Rm2^!P}bj&(R&06BcO!380Gry0L{q1 z#nAS-B#ab&&3SI8j<;ToqFd;VAFTr=P4J?_zMEa@zC3|^4Ge286D(9klxK7^O7H7Y zjcNVS^_%1140z6xEC0g8rUdlcbekmwN3J7UPlzw8oK5wVCs_AqoLHz?Er-A- z_C>kFxV~@W#`k?v^DT;4+a{YqsoL_|IuVZ*xlVD90{cMqPXcv)=qDwTyLM1zh- zF75*zU2uKB$M8EpXOpG8-StUtKJq3n{7@OGo?N9bA{(cYu#(--RQVgux|Ftf6gy74 zdb!!3_n&q<=Iix>vB>~~$FLDch3vnvJUYgR|BP8Ayb6m!V|| zNCW%NT+rLfY*b?oaIS=d#-a@urv*oqB)SA$> z-B0wqa+rZ=UZUAl;MlVR695uz^X;v zY~qQ7$*5Y(0H3SlxJWV|A=FRv!fLHhjmy`K3>PwU}$K>3#7t699XEh+|IO~5j-NyB2Mt|i8`H3wnmME!95T8jYcXW)aY|AkB|Dd{MD=L+y6r#-{IC zhWR6NuqVDhZwhxp%T2Z93VlbT`CYAlq>`AwC};5&qC52N=c}>yF5r7fB@LdRoEJ1) zQR108&(BOwPXG^&TLsNT*b3L!9g4T>y(8!Gj&Xyb=G|kS=2&gY>d`P0u8=7HqmP|r90)|XsWaF;Cf9S6fp*9i#YWHYFKdro=*7ey z^-?6}3vVD0-kLwElHCzQIXdV$Mwv7~(S`e{^IQBk%V=2SXj)h&OPW7{ix?p03LT~qNcvW&~*<$FjgkH{|+S*DKDbHYd$ zZXar&`(qC;zu%&Pavd02_eue(8tWVV%@-Yvj4V5>6clWnYo{F6t#=VdJ+< zo(*~a00ioU9k=2g>$cJ#lKoThy>6qK?-PqOL&#@gwZmu?v#>ZL%`%&)y2W59*q=9J zLaLG`-OXGq-H=o=m%eO|{nJ$ej#3?ZF%bo(sSuBR|C%h`M8%+Wfq`Tu*Q z_<)xLiPlj19XWUzypB;FUA7>pek>1rOWYTuer;$&Xf(lgy33tdx0zCD_N;}#JAumc zc#4FMx8wafz>OM2?pyS@B6BG{jEb*3%D85Qfdh7Gk>Bbqt?8 z#%#xI|Ev0bZ}X14kyMG<*jZqPymDS7sehUXE*y{vw2=!6i^QAHRpx|G+{zwGytX93 zJxAAC-RXyVO_6>{f8ASzk4uCV2d%ve0xo_Y8}lE})ztsJ?=}2GNnvr}O9@mwRwTP6 z^nG*#s?=oL?^-}nn&BcvJ^{Uv@|FA}Bl;LURn|yK3*)$#Dn}Ja$jezgBd3n&_WkHI zK5(n_hI3AeSqx+MYPt7{#;!*28JesQ{U<%obC1B(-EbQ|;Lh+5Op=O;=f7%sIYU(ORzte9!I#8)o z(XQI6dVVz3r^`mM50g@fB9gETR`f+osU*bZZ<7m3@?nYnnI09?{Hc z#0j0RQ?me-900#!GQ^rZncxz^cCT;B6nvtKS3l7u%NlJRVZDCu6J87d-rn_#Ph2)K zx*}c(ITDT8_JhUSNx5J(&4+0eORGJP54`?_sX&*itNz|z!6FlfxW|yYk5IWj|0g)a zr}uw=iTF9|<6O);=LB+HmWfDcGC9ug-b!gd>|U+2>K07MLPtaQOT^GoC}bI3+4)ky z92_|<--ei0&RO-CeW6DlYOPOIg&-C7(A)V0@o;(4XDKFobtOrYhh6CEL#R#vNTh-VsA;O=UvaIo_yzofNOFK$H&=I z^eg2ig;A(Et z2?BnV4IOK0>^SW=uq}iOe^rGn?P}Dq5J!^~*(qp0ETjf`LQj!cFN8%lG~UKic3k%y z-eJTjsNp*eoGKKgng4Awm==urzVoZcbhLpe{hb?)+{gNRt#FdIfSEm{wPN2Ab`+@j zEhmw5Js4mOebGa7rM=DWepbB-&FG%^u0Yro)}fuk!US7nvlw;@&&Dt-gp)4uJax|& z^R*pKt*z{1xkesEw~9vNM6^<6UF^>%27DPgy8;JSLOL$5+~%v`Ov6ZlSCA>XhEq_$ zZB}^VNu#8?_y5na>C9WtpY9qsjgc_EQi_tIRs5JQOanzaG6KgQZ4V|64GL1UF9QUW%p6+Jm>e}9&RQjZdxbCO1l-ZWi($oh0 zDkx=5qmitor{yDusZ^~85Ew0x7UBqj($x=8L&>vG&yM*PcWE$zy{)d++Zqe;xvp_@ zUwU`=en85fG53b@NCXKcVGqZ)P4Hhg`SYaM!V{50uB37P^)r5)7j)8jxqcCAMdr*$kllvoFD?l~!bM=t4I zVjXyk6jW3e8byZh0t!g?@Qcg_DF#X2+1z#dLXTz*^%0e@pq8i=gel^LU-;%Qp5VzS z7RhjHI>QZYQkvAeydt#nN8m_$vRk~HSK(GgtCp>Ef!B&24zIebg2OjI$;R3+jht-@ zThKM{efD~Ov&EY){%`!FAL|zrWm#aEKsE-;!KDkD_x^g*_Q*i^A?$j94$*KxlG1lc zqbLbB*nPJS?=~H8i?Bw6tn4=r(5wkJW;NO}!lMW~Dnp1w?~h?5M{OVO%YG~2(@d2! zS_w4i(cD_ExL`dKjFQ?}MWJ9LM;VNqyUIigd+VHtT$(dab8;FmqI|EP{9epn#_oz; zq2DzKTqnmv5UvT=S!ssrI6;&}LA3Cjiv7Yad&m!A6K^*v?UT4&;mJX1mL-_Yp6DtX zMY9LL%pOI$ksPo@lT|eS7n?>DkXpHrB{l}EJ<=K=7^2B9G~dwv+f7KGg@VcRT_@hh z(2@LO6NeV+L8&37)-6Vh&8@TtNTJQCqsOP22WOG*k=c_n7go@zwLTvJv~MNLeGm7Z z@Vn-Z)9I4vZR`bq8uovQS6{8_VQJN_xSz&EUV>h^KxcFp!S-kaA#=gKZ -?#NQ!g`w$b|WU` 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
'; + + const outgoing = connectedEdges.filter( + (e) => e.fromId === gateway.id && e.toId !== gateway.id, + ); + const incoming = connectedEdges.filter( + (e) => e.toId === gateway.id && e.fromId !== gateway.id, + ); + + if (outgoing.length > 0) { + html += `
Outgoing (${outgoing.length}):
`; + outgoing.slice(0, 5).forEach((edge) => { + const pathLen = edge.path ? edge.path.length : 0; + html += ` → GW ${edge.toId}: cost ${edge.cost.toFixed(1)}`; + if (pathLen > 0) html += ` (${pathLen} tiles)`; + html += "
"; + }); + if (outgoing.length > 5) { + html += ` ... and ${outgoing.length - 5} more
`; + } + } + + if (incoming.length > 0) { + html += `
Incoming (${incoming.length}):
`; + incoming.slice(0, 5).forEach((edge) => { + const pathLen = edge.path ? edge.path.length : 0; + html += ` ← GW ${edge.fromId}: cost ${edge.cost.toFixed(1)}`; + if (pathLen > 0) html += ` (${pathLen} tiles)`; + html += "
"; + }); + if (incoming.length > 5) { + html += ` ... and ${incoming.length - 5} more
`; + } + } + + if (selfLoops.length > 0) { + html += `
Self-loops (${selfLoops.length}):
`; + selfLoops.forEach((edge) => { + const pathLen = edge.path ? edge.path.length : 0; + html += ` ⟲ cost ${edge.cost.toFixed(1)}`; + if (pathLen > 0) html += ` (${pathLen} tiles)`; + html += "
"; + }); + } + + html += "
"; + } + + tooltip.innerHTML = html; + tooltip.style.left = mouseX + 15 + "px"; + tooltip.style.top = mouseY + 15 + "px"; + tooltip.classList.add("visible"); +} diff --git a/tests/pathfinding/playground/public/index.html b/tests/pathfinding/playground/public/index.html new file mode 100644 index 000000000..b3180dc45 --- /dev/null +++ b/tests/pathfinding/playground/public/index.html @@ -0,0 +1,315 @@ + + + + + + Pathfinding Playground - Interactive Visualization + + + + +
+
+ + +
+ +
+ + +
+
+

Pathfinding Playground

+

Interactive visualization for naval pathfinding algorithms

+ + +
+
+ Loading... +
Map 1
+
+
+ Loading... +
Map 2
+
+
+ Loading... +
Map 3
+
+
+ Loading... +
Map 4
+
+
+ Loading... +
Map 5
+
+
+ Loading... +
Map 6
+
+
+ Loading... +
Map 7
+
+
+ Loading... +
Map 8
+
+
+ + +
+ + +
+
+
+ + +
+

Pathfinding Playground

+ +
+ +
+ +
+ Select a scenario to begin +
+
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+ + 1.0x +
+ + +
+ + +
+
Performance
+ +
+
+ + NavMesh +
+ + +
+ + + + + +
+
+ +
+ +
+ + + + +
+ + +
+
Legend
+
+
+
+ Start Point +
+
+
+ End Point +
+ +
+
+ NavMesh +
+
+
+ Initial Path +
+
+
+ Used Gateways +
+
+
+ Gateways +
+
+
+ Sectors +
+
+
+ Edges +
+
+
+ + +
+ + +
+ + + + diff --git a/tests/pathfinding/playground/public/styles.css b/tests/pathfinding/playground/public/styles.css new file mode 100644 index 000000000..1a9f34559 --- /dev/null +++ b/tests/pathfinding/playground/public/styles.css @@ -0,0 +1,795 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; + background: #3c3c3c; + color: #e0e0e0; + overflow: hidden; +} + +/* Welcome screen */ +.welcome-screen { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: rgba(28, 28, 28, 0.98); + backdrop-filter: blur(10px); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.welcome-screen.hidden { + display: none; +} + +.welcome-content { + text-align: center; + max-width: 1100px; + padding: 40px; + background: rgba(42, 42, 42, 0.95); + border-radius: 16px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.7); + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.welcome-content h1 { + font-size: 42px; + color: #fff; + margin: 0 0 16px 0; + font-weight: 600; +} + +.welcome-content p { + font-size: 18px; + color: #aaa; + margin: 0 0 30px 0; + line-height: 1.5; +} + +/* Map grid */ +.map-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 16px; + margin-bottom: 30px; +} + +.map-card { + background: #1a1a1a; + border: 2px solid #404040; + border-radius: 8px; + overflow: hidden; + cursor: pointer; + transition: all 0.2s; + position: relative; +} + +.map-card:hover { + border-color: #0066cc; + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0, 102, 204, 0.3); +} + +.map-card img { + width: 100%; + height: 180px; + object-fit: cover; + display: block; +} + +.map-card-name { + padding: 10px; + font-size: 14px; + color: #e0e0e0; + font-weight: 500; + text-align: center; + background: #2a2a2a; + transition: opacity 0.3s ease; +} + +.welcome-selector { + display: flex; + flex-direction: column; + gap: 12px; + align-items: center; +} + +.welcome-selector label { + font-size: 14px; + color: #aaa; + font-weight: 400; +} + +.welcome-selector select { + width: 400px; + padding: 14px 18px; + font-size: 16px; + background: #1a1a1a; + color: #e0e0e0; + border: 2px solid #404040; + border-radius: 8px; + cursor: pointer; + transition: border-color 0.2s; +} + +.welcome-selector select:hover { + border-color: #0066cc; +} + +.welcome-selector select:focus { + outline: none; + border-color: #0066cc; +} + +/* Fullscreen canvas container */ +.canvas-container { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: #3c3c3c; + z-index: 1; +} + +.canvas-wrapper { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + background: #0a0a0a; + cursor: grab; +} + +.canvas-wrapper:active { + cursor: grabbing; +} + +.canvas-wrapper.selecting { + cursor: crosshair; +} + +canvas { + position: absolute; + top: 0; + left: 0; + display: block; + transform-origin: 0 0; +} + +#mapCanvas { + z-index: 1; +} + +#overlayCanvas { + z-index: 2; + pointer-events: none; +} + +/* Top panel - overlay on map */ +.top-panel { + position: fixed; + top: 20px; + left: 20px; + max-width: 900px; + background: rgba(42, 42, 42, 0.95); + backdrop-filter: blur(10px); + border-radius: 12px; + padding: 20px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); + z-index: 10; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.top-panel h1 { + font-size: 24px; + color: #fff; + margin: 0 0 15px 0; +} + +.scenario-selector { + margin-bottom: 15px; +} + +.status-section { + padding-top: 15px; + border-top: 1px solid #404040; +} + +.scenario-selector select { + width: 350px; + padding: 12px 16px; + font-size: 16px; + background: #1a1a1a; + color: #e0e0e0; + border: 1px solid #404040; + border-radius: 6px; + cursor: pointer; +} + +.scenario-selector select:focus { + outline: none; + border-color: #0066cc; +} + +.info { + padding-top: 15px; + border-top: 1px solid #404040; +} + +.info-row { + display: flex; + gap: 30px; + margin-bottom: 8px; + flex-wrap: wrap; +} + +.info-item { + display: flex; + align-items: center; + gap: 8px; +} + +/* Debug panel (bottom left) */ +.debug-panel { + position: fixed; + bottom: 20px; + left: 20px; + background: rgba(42, 42, 42, 0.95); + backdrop-filter: blur(10px); + border-radius: 12px; + padding: 15px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); + z-index: 10; + border: 1px solid rgba(255, 255, 255, 0.1); + display: flex; + flex-direction: column; + gap: 10px; +} + +.debug-panel-row { + display: flex; + gap: 10px; + align-items: center; +} + +/* View panel (bottom right) */ +.view-panel { + position: fixed; + bottom: 20px; + right: 20px; + background: rgba(42, 42, 42, 0.95); + backdrop-filter: blur(10px); + border-radius: 12px; + padding: 15px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); + z-index: 10; + border: 1px solid rgba(255, 255, 255, 0.1); + display: flex; + flex-direction: column; + gap: 10px; + min-width: 160px; +} + +.zoom-control { + display: flex; + flex-direction: column; + gap: 6px; + align-items: center; + padding: 8px 0; + border-bottom: 1px solid #404040; + margin-bottom: 2px; +} + +.zoom-control input[type="range"] { + width: 100%; +} + +.zoom-control span { + font-size: 13px; + color: #aaa; + font-weight: 500; +} + +.clear-button { + background: #cc3333; + color: white; + border: 2px solid #dd4444; + padding: 10px 12px 10px 10px; + border-radius: 8px; + cursor: pointer; + font-size: 15px; + font-weight: 600; + transition: all 0.2s; + text-transform: uppercase; + letter-spacing: 0.5px; + width: 100%; +} + +.clear-button:hover { + background: #aa2222; + border-color: #cc3333; +} + +.toggle-button { + background: #333; + color: #e0e0e0; + border: 2px solid #555; + padding: 10px 12px 10px 10px; + border-radius: 8px; + cursor: pointer; + font-size: 15px; + font-weight: 600; + transition: all 0.2s; + min-width: 100px; + text-transform: uppercase; + letter-spacing: 0.5px; + display: flex; + align-items: center; + gap: 6px; +} + +.toggle-button::before { + content: "☐"; + font-size: 24px; + line-height: 1; + color: #888; +} + +.toggle-button:hover { + background: #404040; + border-color: #666; +} + +.toggle-button[data-active="true"] { + background: #0066cc; + border-color: #0088ff; + color: white; + box-shadow: 0 0 10px rgba(0, 102, 204, 0.4); +} + +.toggle-button[data-active="true"]::before { + content: "☑"; + color: #00ff88; +} + +.toggle-button[data-active="true"]:hover { + background: #0052a3; + border-color: #0066cc; +} + +/* Timings panel (left side) */ +.timings-panel { + position: fixed; + top: 250px; + left: 20px; + background: rgba(42, 42, 42, 0.95); + backdrop-filter: blur(10px); + border-radius: 12px; + padding: 20px 20px 15px 20px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); + z-index: 10; + border: 1px solid rgba(255, 255, 255, 0.1); + min-width: 280px; +} + +.timings-header { + display: none; +} + +.timing-section { + margin-bottom: 0; + padding-bottom: 0; +} + +.timing-section + .timing-section { + margin-top: 15px; + padding-top: 15px; + border-top: 1px solid #404040; +} + +.timing-label { + font-size: 18px; + color: #e0e0e0; + text-transform: uppercase; + letter-spacing: 0.5px; + margin-bottom: 8px; + display: flex; + align-items: center; + gap: 8px; +} + +.refresh-icon { + background: none; + border: none; + color: #00aaff; + font-size: 18px; + cursor: pointer; + padding: 4px; + line-height: 1; + transition: color 0.2s; + border-radius: 4px; + width: 26px; + height: 26px; + display: flex; + align-items: center; + justify-content: center; + transform: translateY(1px); +} + +.refresh-icon span { + display: block; + line-height: 1; +} + +.refresh-icon:hover { + color: #00ccff; + background: rgba(0, 170, 255, 0.1); +} + +.refresh-icon.spinning span { + animation: spin 0.6s ease-in-out; +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.timing-label-detail { + color: #888; + text-transform: none; + font-size: 14px; +} + +.timing-value-large { + font-size: 48px; + font-weight: bold; + color: #00ff88; + font-family: "Courier New", monospace; + line-height: 1; + margin-bottom: 15px; +} + +.timing-value-large.faded { + color: #888888; + opacity: 0.7; +} + +.timing-value-speedup { + font-size: 36px; + font-weight: bold; + color: #ffaa00; + font-family: "Courier New", monospace; + line-height: 1; +} + +.timing-breakdown { + margin-top: 15px; +} + +.timing-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 3px 0; + font-size: 20px; +} + +.timing-name { + color: #e0e0e0; +} + +.timing-value { + font-family: + "Consolas", "Monaco", "SF Mono", "Roboto Mono", "Courier New", monospace; + color: #f5f5f5; + font-weight: bold; + font-size: 20px; +} + +/* Legend panel (right side) */ +.legend-panel { + position: fixed; + top: 50%; + right: 20px; + transform: translateY(-50%); + background: rgba(42, 42, 42, 0.95); + backdrop-filter: blur(10px); + border-radius: 12px; + padding: 15px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); + z-index: 10; + border: 1px solid rgba(255, 255, 255, 0.1); + min-width: 160px; +} + +.legend-header { + font-size: 16px; + font-weight: 600; + color: #e0e0e0; + text-transform: uppercase; + letter-spacing: 0.5px; + margin-bottom: 12px; + padding-bottom: 10px; + border-bottom: 1px solid #404040; +} + +.legend { + display: flex; + flex-direction: column; + gap: 10px; +} + +.legend-item { + display: flex; + align-items: center; + gap: 10px; + font-size: 14px; + color: #e0e0e0; +} + +.legend-color { + width: 28px; + height: 4px; + border-radius: 2px; + flex-shrink: 0; +} + +/* Form elements */ +label { + display: flex; + align-items: center; + gap: 8px; + cursor: pointer; + font-size: 14px; +} + +input[type="range"] { + width: 120px; +} + +input[type="checkbox"] { + width: 16px; + height: 16px; + cursor: pointer; +} + +button { + background: #0066cc; + color: white; + border: none; + padding: 8px 16px; + border-radius: 6px; + cursor: pointer; + font-size: 14px; + font-weight: 500; + transition: background 0.2s; +} + +button:hover { + background: #0052a3; +} + +button:disabled { + background: #404040; + cursor: not-allowed; + opacity: 0.6; +} + +.timing-button { + width: 100%; + background: #555; + color: white; + border: none; + padding: 10px 16px; + border-radius: 6px; + cursor: pointer; + font-size: 14px; + font-weight: 500; + transition: background 0.2s; +} + +.timing-button:hover:not(:disabled) { + background: #666; +} + +.timing-button:disabled { + background: #404040; + cursor: not-allowed; + opacity: 0.6; +} + +#status { + font-size: 14px; + color: #888; + font-style: italic; +} + +#status.loading { + color: #00aaff; +} + +#status.error { + color: #ff6b6b; +} + +/* Error toast notification */ +.error-toast { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: rgba(138, 26, 26, 0.98); + color: #ff6b6b; + padding: 20px 30px; + border-radius: 12px; + font-size: 16px; + font-weight: 500; + box-shadow: 0 8px 30px rgba(0, 0, 0, 0.7); + z-index: 100; + display: none; + max-width: 500px; + text-align: center; + border: 2px solid #ff6b6b; + animation: slideIn 0.3s ease-out; +} + +.error-toast.visible { + display: block; +} + +@keyframes slideIn { + from { + transform: translate(-50%, -60%); + opacity: 0; + } + to { + transform: translate(-50%, -50%); + opacity: 1; + } +} + +/* Tooltip */ +#tooltip { + position: fixed; + background: rgba(0, 0, 0, 0.95); + color: #fff; + padding: 12px 16px; + border-radius: 8px; + font-size: 12px; + pointer-events: none; + z-index: 1000; + display: none; + border: 1px solid #666; + max-width: 350px; + line-height: 1.5; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5); +} + +#tooltip.visible { + display: block; +} + +/* Loading spinner */ +.loading-spinner { + display: inline-block; + width: 16px; + height: 16px; + border: 2px solid #404040; + border-top-color: #00aaff; + border-radius: 50%; + animation: spin 0.8s linear infinite; + margin-left: 8px; + vertical-align: middle; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +/* Responsive adjustments */ +@media (max-width: 1200px) { + .top-panel { + left: 10px; + right: 10px; + padding: 15px; + } + + .debug-panel { + left: 10px; + padding: 12px; + gap: 8px; + } + + .debug-panel-row { + gap: 8px; + } + + .view-panel { + right: 10px; + padding: 12px; + gap: 8px; + min-width: 140px; + } + + .toggle-button { + min-width: auto; + padding: 8px 10px 8px 8px; + font-size: 14px; + } + + .clear-button { + padding: 8px 10px 8px 8px; + font-size: 14px; + } + + .legend-panel { + right: 10px; + max-width: 200px; + } + + h1 { + font-size: 20px; + } +} + +@media (max-width: 768px) { + .top-panel h1 { + font-size: 18px; + } + + .debug-panel { + gap: 6px; + } + + .debug-panel-row { + gap: 6px; + } + + .view-panel { + gap: 6px; + min-width: 120px; + } + + .toggle-button { + min-width: auto; + padding: 7px 8px 7px 6px; + font-size: 13px; + } + + .clear-button { + padding: 7px 8px 7px 6px; + font-size: 13px; + } + + .timings-panel { + top: auto; + bottom: 180px; + left: 10px; + transform: none; + min-width: auto; + max-width: calc(100vw - 20px); + } + + .legend-panel { + top: auto; + bottom: 200px; + right: 10px; + transform: none; + } +} diff --git a/tests/pathfinding/playground/server.ts b/tests/pathfinding/playground/server.ts new file mode 100644 index 000000000..6e1fe0d2a --- /dev/null +++ b/tests/pathfinding/playground/server.ts @@ -0,0 +1,269 @@ +import compression from "compression"; +import express, { Request, Response } from "express"; +import { dirname, join } from "path"; +import { fileURLToPath } from "url"; +import { + clearCache as clearMapCache, + getMapMetadata, + listMaps, + setConfig, +} from "./api/maps.js"; +import { + clearAdapterCaches, + computePath, + computePfMiniPath, +} from "./api/pathfinding.js"; + +// Parse command-line arguments +const args = process.argv.slice(2); +const noCache = args.includes("--no-cache"); + +// Configure map loading +if (noCache) { + setConfig({ cachePaths: false }); + console.log("Path caching disabled (--no-cache)"); +} + +const app = express(); +const PORT = process.env.PORT ?? 5555; + +// Middleware +app.use(compression()); // gzip compression for large responses +app.use(express.json({ limit: "50mb" })); // JSON body parser with larger limit + +// Serve static files from public directory +const publicDir = join(dirname(fileURLToPath(import.meta.url)), "public"); +app.use(express.static(publicDir)); + +// API Routes + +/** + * GET /api/maps + * List all available maps + */ +app.get("/api/maps", (req: Request, res: Response) => { + try { + const maps = listMaps(); + res.json({ maps }); + } catch (error) { + console.error("Error listing maps:", error); + res.status(500).json({ + error: "Failed to list maps", + message: error instanceof Error ? error.message : String(error), + }); + } +}); + +/** + * GET /api/maps/:name + * Get map metadata (map data, dimensions) + */ +app.get("/api/maps/:name", async (req: Request, res: Response) => { + try { + const { name } = req.params; + const metadata = await getMapMetadata(name); + res.json(metadata); + } catch (error) { + console.error(`Error loading map ${req.params.name}:`, error); + + if (error instanceof Error && error.message.includes("ENOENT")) { + res.status(404).json({ + error: "Map not found", + message: `Map "${req.params.name}" does not exist`, + }); + } else { + res.status(500).json({ + error: "Failed to load map", + message: error instanceof Error ? error.message : String(error), + }); + } + } +}); + +/** + * GET /api/maps/:name/thumbnail + * Get map thumbnail image + */ +app.get("/api/maps/:name/thumbnail", (req: Request, res: Response) => { + try { + const { name } = req.params; + const thumbnailPath = join( + dirname(fileURLToPath(import.meta.url)), + "../../../resources/maps", + name, + "thumbnail.webp", + ); + res.sendFile(thumbnailPath); + } catch (error) { + console.error(`Error loading thumbnail for ${req.params.name}:`, error); + res.status(404).json({ + error: "Thumbnail not found", + message: error instanceof Error ? error.message : String(error), + }); + } +}); + +/** + * POST /api/pathfind + * Compute pathfinding between two points + * + * Request body: + * { + * map: string, + * from: [x, y], + * to: [x, y], + * includePfMini?: boolean + * } + */ +app.post("/api/pathfind", async (req: Request, res: Response) => { + try { + const { map, from, to, includePfMini } = req.body; + + // Validate request + if (!map || !from || !to) { + return res.status(400).json({ + error: "Invalid request", + message: "Missing required fields: map, from, to", + }); + } + + if ( + !Array.isArray(from) || + from.length !== 2 || + !Array.isArray(to) || + to.length !== 2 + ) { + return res.status(400).json({ + error: "Invalid coordinates", + message: "from and to must be [x, y] coordinate arrays", + }); + } + + // Compute paths + const result = await computePath( + map, + from as [number, number], + to as [number, number], + { includePfMini: !!includePfMini }, + ); + + res.json(result); + } catch (error) { + console.error("Error computing path:", error); + + if (error instanceof Error && error.message.includes("is not water")) { + res.status(400).json({ + error: "Invalid coordinates", + message: error.message, + }); + } else { + res.status(500).json({ + error: "Failed to compute path", + message: error instanceof Error ? error.message : String(error), + }); + } + } +}); + +/** + * POST /api/pathfind-pfmini + * Compute only PathFinder.Mini path + * + * Request body: + * { + * map: string, + * from: [x, y], + * to: [x, y] + * } + */ +app.post("/api/pathfind-pfmini", async (req: Request, res: Response) => { + try { + const { map, from, to } = req.body; + + // Validate request + if (!map || !from || !to) { + return res.status(400).json({ + error: "Invalid request", + message: "Missing required fields: map, from, to", + }); + } + + if ( + !Array.isArray(from) || + from.length !== 2 || + !Array.isArray(to) || + to.length !== 2 + ) { + return res.status(400).json({ + error: "Invalid coordinates", + message: "from and to must be [x, y] coordinate arrays", + }); + } + + // Compute PF.Mini path only + const result = await computePfMiniPath( + map, + from as [number, number], + to as [number, number], + ); + + res.json(result); + } catch (error) { + console.error("Error computing PF.Mini path:", error); + + if (error instanceof Error && error.message.includes("is not water")) { + res.status(400).json({ + error: "Invalid coordinates", + message: error.message, + }); + } else { + res.status(500).json({ + error: "Failed to compute PF.Mini path", + message: error instanceof Error ? error.message : String(error), + }); + } + } +}); + +/** + * POST /api/cache/clear + * Clear all caches (useful for development) + */ +app.post("/api/cache/clear", (req: Request, res: Response) => { + try { + clearMapCache(); + clearAdapterCaches(); + res.json({ message: "Caches cleared successfully" }); + } catch (error) { + console.error("Error clearing caches:", error); + res.status(500).json({ + error: "Failed to clear caches", + message: error instanceof Error ? error.message : String(error), + }); + } +}); + +// Error handling middleware +app.use((err: Error, req: Request, res: Response, next: any) => { + console.error("Unhandled error:", err); + res.status(500).json({ + error: "Internal server error", + message: err.message, + }); +}); + +// Start server +app.listen(PORT, () => { + console.log(` +╔════════════════════════════════════════════════════════════╗ +║ Pathfinding Playground Server ║ +╚════════════════════════════════════════════════════════════╝ + +Server running at: http://localhost:${PORT} + +Configuration: + - Path caching: ${noCache ? "disabled" : "enabled"} + +Press Ctrl+C to stop + `); +}); diff --git a/tests/pathfinding/utils.ts b/tests/pathfinding/utils.ts new file mode 100644 index 000000000..6e3a12ceb --- /dev/null +++ b/tests/pathfinding/utils.ts @@ -0,0 +1,225 @@ +import fs from "fs"; +import path, { dirname } from "path"; +import { fileURLToPath } from "url"; +import { + Difficulty, + Game, + GameMapType, + GameMode, + GameType, + PlayerInfo, +} from "../../src/core/game/Game"; +import { createGame } from "../../src/core/game/GameImpl"; +import { TileRef } from "../../src/core/game/GameMap"; +import { genTerrainFromBin } from "../../src/core/game/TerrainMapLoader"; +import { UserSettings } from "../../src/core/game/UserSettings"; +import { NavMesh } from "../../src/core/pathfinding/navmesh/NavMesh"; +import { PathFinder, PathFinders } from "../../src/core/pathfinding/PathFinder"; +import { GameConfig, PeaceTimerDuration } from "../../src/core/Schemas"; +import { TestConfig } from "../util/TestConfig"; +export type BenchmarkRoute = { + name: string; + from: TileRef; + to: TileRef; +}; + +export type BenchmarkResult = { + route: string; + executionTime: number | null; + pathLength: number | null; +}; + +export type BenchmarkSummary = { + totalRoutes: number; + successfulRoutes: number; + timedRoutes: number; + totalDistance: number; + totalTime: number; + avgTime: number; +}; + +export function getAdapter(game: Game, name: string): PathFinder { + switch (name) { + case "legacy": + return PathFinders.WaterLegacy(game, { + iterations: 500_000, + maxTries: 50, + }); + case "hpa": { + // Recreate NavMesh without cache, this approach was chosen + // over adding cache toggles to the existing game instance + // to avoid adding side effect from benchmark to the game + const navMesh = new NavMesh(game, { cachePaths: false }); + navMesh.initialize(); + (game as any)._navMesh = navMesh; + + return PathFinders.Water(game); + } + case "hpa.cached": + return PathFinders.Water(game); + default: + throw new Error(`Unknown pathfinding adapter: ${name}`); + } +} + +export async function getScenario( + scenarioName: string, + adapterName: string = "hpa", +) { + const scenario = await import(`./benchmark/scenarios/${scenarioName}.js`); + const enableNavMesh = adapterName.startsWith("hpa"); + + // Time game creation (includes NavMesh initialization for default adapter) + const start = performance.now(); + const currentDir = dirname(fileURLToPath(import.meta.url)); + const projectRoot = path.join(currentDir, "../.."); + const mapsDirectory = path.join(projectRoot, "resources/maps"); + const game = await setupFromPath(mapsDirectory, scenario.MAP_NAME, { + disableNavMesh: !enableNavMesh, + }); + const initTime = performance.now() - start; + + const routes = scenario.ROUTES.map(([fromName, toName]: [string, string]) => { + const fromCoord: [number, number] = scenario.PORTS[fromName]; + const toCoord: [number, number] = scenario.PORTS[toName]; + + return { + name: `${fromName} → ${toName}`, + from: game.ref(fromCoord[0], fromCoord[1]), + to: game.ref(toCoord[0], toCoord[1]), + }; + }); + + return { + game, + routes, + initTime, + }; +} + +export function measurePathLength( + adapter: PathFinder, + route: BenchmarkRoute, +): number | null { + const path = adapter.findPath(route.from, route.to); + return path ? path.length : null; +} + +export function measureTime(fn: () => T): { result: T; time: number } { + const start = performance.now(); + const result = fn(); + const end = performance.now(); + return { result, time: end - start }; +} + +export function measureExecutionTime( + adapter: PathFinder, + route: BenchmarkRoute, + executions: number = 1, +): number | null { + const { time } = measureTime(() => { + for (let i = 0; i < executions; i++) { + adapter.findPath(route.from, route.to); + } + }); + + return time / executions; +} + +export function calculateStats(results: BenchmarkResult[]): BenchmarkSummary { + const successful = results.filter((r) => r.pathLength !== null); + const timed = results.filter((r) => r.executionTime !== null); + + const totalDistance = successful.reduce((sum, r) => sum + r.pathLength!, 0); + const totalTime = timed.reduce((sum, r) => sum + r.executionTime!, 0); + const avgTime = timed.length > 0 ? totalTime / timed.length : 0; + + return { + totalRoutes: results.length, + successfulRoutes: successful.length, + timedRoutes: timed.length, + totalDistance, + totalTime, + avgTime, + }; +} + +export function printRow(columns: (string | number)[], widths: number[]): void { + const formatted = columns.map((col, i) => { + const str = typeof col === "number" ? col.toString() : col; + return str.padEnd(widths[i]); + }); + + console.log(formatted.join(" ")); +} + +export function printSeparator(width: number = 80): void { + console.log("-".repeat(width)); +} + +export function printHeader(title: string, width: number = 80): void { + printSeparator(width); + console.log(title); + printSeparator(width); + console.log(""); +} + +export async function setupFromPath( + mapDirectory: string, + mapName: string, + gameConfig: Partial = {}, + humans: PlayerInfo[] = [], +): Promise { + // Suppress console.debug for tests + console.debug = () => {}; + + // Load map files from specified directory + const mapBinPath = path.join(mapDirectory, mapName, "map.bin"); + const miniMapBinPath = path.join(mapDirectory, mapName, "map4x.bin"); + + // Check if files exist + if (!fs.existsSync(mapBinPath)) { + throw new Error(`Map not found: ${mapBinPath}`); + } + + if (!fs.existsSync(miniMapBinPath)) { + throw new Error(`Mini map not found: ${miniMapBinPath}`); + } + + const mapBinBuffer = fs.readFileSync(mapBinPath); + const miniMapBinBuffer = fs.readFileSync(miniMapBinPath); + + // Convert binary buffers to strings for Terratomic's genTerrainFromBin + const mapBinString = String.fromCharCode(...new Uint8Array(mapBinBuffer)); + const miniMapBinString = String.fromCharCode( + ...new Uint8Array(miniMapBinBuffer), + ); + + const gameMap = await genTerrainFromBin(mapBinString); + const miniGameMap = await genTerrainFromBin(miniMapBinString); + + // Configure the game + const config = new TestConfig( + new (await import("../util/TestServerConfig")).TestServerConfig(), + { + gameMap: GameMapType.Asia, + gameMode: GameMode.FFA, + gameType: GameType.Singleplayer, + difficulty: Difficulty.Medium, + disableNPCs: false, + bots: 0, + infiniteGold: false, + infiniteTroops: false, + instantBuild: false, + peaceTimerDurationMinutes: PeaceTimerDuration.None, + startingGold: 0, + goldMultiplier: 1, + chatEnabled: false, + ...gameConfig, + }, + new UserSettings(), + false, + ); + + return createGame(humans, [], gameMap, miniGameMap, config); +} diff --git a/tests/perf/AstarPerf.ts b/tests/perf/AstarPerf.ts new file mode 100644 index 000000000..6e5931672 --- /dev/null +++ b/tests/perf/AstarPerf.ts @@ -0,0 +1,29 @@ +import Benchmark from "benchmark"; +import { MiniPathFinder } from "../../src/core/pathfinding/PathFinding"; +import { setup } from "../util/Setup"; + +const game = await setup("giantworldmap", {}, []); + +new Benchmark.Suite() + .add("top-left-to-bottom-right", () => { + new MiniPathFinder(game, 10_000_000_000, true, 1).nextTile( + game.ref(0, 0), + game.ref(4077, 1929), + ); + }) + .add("hawaii to svalbard", () => { + new MiniPathFinder(game, 10_000_000_000, true, 1).nextTile( + game.ref(186, 800), + game.ref(2205, 52), + ); + }) + .add("black sea to california", () => { + new MiniPathFinder(game, 10_000_000_000, true, 1).nextTile( + game.ref(2349, 455), + game.ref(511, 536), + ); + }) + .on("cycle", (event: any) => { + console.log(String(event.target)); + }) + .run({ async: true }); diff --git a/tests/testdata/maps/world/manifest.json b/tests/testdata/maps/world/manifest.json new file mode 100644 index 000000000..3a2df3f99 --- /dev/null +++ b/tests/testdata/maps/world/manifest.json @@ -0,0 +1,325 @@ +{ + "map": { + "height": 1000, + "num_land_tiles": 651761, + "width": 2000 + }, + "map16x": { + "height": 250, + "num_land_tiles": 37185, + "width": 500 + }, + "map4x": { + "height": 500, + "num_land_tiles": 157860, + "width": 1000 + }, + "name": "World", + "nations": [ + { + "coordinates": [375, 272], + "flag": "us", + "name": "United States" + }, + { + "coordinates": [372, 136], + "flag": "ca", + "name": "Canada" + }, + { + "coordinates": [375, 374], + "flag": "mx", + "name": "Mexico" + }, + { + "coordinates": [500, 378], + "flag": "cu", + "name": "Cuba" + }, + { + "coordinates": [524, 474], + "flag": "co", + "name": "Colombia" + }, + { + "coordinates": [593, 473], + "flag": "ve", + "name": "Venezuela" + }, + { + "coordinates": [596, 705], + "flag": "ar", + "name": "Argentina" + }, + { + "coordinates": [637, 567], + "flag": "br", + "name": "Brazil" + }, + { + "coordinates": [1280, 975], + "flag": "aq", + "name": "Antarctica" + }, + { + "coordinates": [709, 57], + "flag": "gl", + "name": "Greenland" + }, + { + "coordinates": [831, 112], + "flag": "is", + "name": "Iceland" + }, + { + "coordinates": [925, 186], + "flag": "gb", + "name": "United Kingdom" + }, + { + "coordinates": [887, 183], + "flag": "ie", + "name": "Ireland" + }, + { + "coordinates": [908, 264], + "flag": "es", + "name": "Spain" + }, + { + "coordinates": [1004, 250], + "flag": "it", + "name": "Italy" + }, + { + "coordinates": [958, 220], + "flag": "fr", + "name": "France" + }, + { + "coordinates": [997, 205], + "flag": "de", + "name": "Germany" + }, + { + "coordinates": [1064, 101], + "flag": "se", + "name": "Sweden" + }, + { + "coordinates": [1046, 193], + "flag": "pl", + "name": "Poland" + }, + { + "coordinates": [1061, 188], + "flag": "by", + "name": "Belarus" + }, + { + "coordinates": [1073, 243], + "flag": "ro", + "name": "Romania" + }, + { + "coordinates": [1161, 274], + "flag": "tr", + "name": "Turkey" + }, + { + "coordinates": [969, 133], + "flag": "no", + "name": "Norway" + }, + { + "coordinates": [1062, 133], + "flag": "fi", + "name": "Finland" + }, + { + "coordinates": [1099, 211], + "flag": "ua", + "name": "Ukraine" + }, + { + "coordinates": [1344, 136], + "flag": "ru", + "name": "Russia" + }, + { + "coordinates": [1537, 186], + "flag": "mn", + "name": "Mongolia" + }, + { + "coordinates": [1524, 328], + "flag": "cn", + "name": "China" + }, + { + "coordinates": [1368, 373], + "flag": "in", + "name": "India" + }, + { + "coordinates": [1276, 239], + "flag": "kz", + "name": "Kazakhstan" + }, + { + "coordinates": [1238, 309], + "flag": "ir", + "name": "Islamic Republic Of Iran" + }, + { + "coordinates": [1178, 351], + "flag": "sa", + "name": "Saudi Arabia" + }, + { + "coordinates": [1679, 657], + "flag": "au", + "name": "Australia" + }, + { + "coordinates": [1890, 775], + "flag": "nz", + "name": "New Zealand" + }, + { + "coordinates": [918, 342], + "flag": "dz", + "name": "Algeria" + }, + { + "coordinates": [1030, 332], + "flag": "ly", + "name": "Libyan Arab Jamahiriya" + }, + { + "coordinates": [1092, 335], + "flag": "eg", + "name": "Egypt" + }, + { + "coordinates": [963, 410], + "flag": "ne", + "name": "Niger" + }, + { + "coordinates": [1112, 406], + "flag": "sd", + "name": "Sudan" + }, + { + "coordinates": [1074, 508], + "flag": "cd", + "name": "DR Congo" + }, + { + "coordinates": [1154, 443], + "flag": "et", + "name": "Ethiopia" + }, + { + "coordinates": [1075, 707], + "flag": "za", + "name": "South Africa" + }, + { + "coordinates": [1194, 627], + "flag": "mg", + "name": "Madagascar" + }, + { + "coordinates": [1052, 420], + "flag": "td", + "name": "Chad" + }, + { + "coordinates": [1030, 665], + "flag": "na", + "name": "Namibia" + }, + { + "coordinates": [1632, 465], + "flag": "ph", + "name": "Philippines" + }, + { + "coordinates": [1537, 426], + "flag": "th", + "name": "Thailand" + }, + { + "coordinates": [1610, 364], + "flag": "tw", + "name": "Taiwan" + }, + { + "coordinates": [1710, 290], + "flag": "jp", + "name": "Japan" + }, + { + "coordinates": [1869, 119], + "flag": "ru", + "name": "Siberia" + }, + { + "coordinates": [74, 117], + "flag": "polar_bears", + "name": "Polar Bears" + }, + { + "coordinates": [419, 975], + "flag": "aq", + "name": "West Antarctica" + }, + { + "coordinates": [542, 603], + "flag": "pe", + "name": "Peru" + }, + { + "coordinates": [1075, 615], + "flag": "zm", + "name": "Zambia" + }, + { + "coordinates": [1099, 165], + "flag": "lv", + "name": "Latvia" + }, + { + "coordinates": [1427, 336], + "flag": "bt", + "name": "Bhutan" + }, + { + "coordinates": [1511, 524], + "flag": "id", + "name": "Indonesia" + }, + { + "coordinates": [1809, 977], + "flag": "aq", + "name": "East Antarctica" + }, + { + "coordinates": [1255, 382], + "flag": "om", + "name": "Oman" + }, + { + "coordinates": [853, 373], + "flag": "ma", + "name": "Morocco" + }, + { + "coordinates": [656, 678], + "flag": "uy", + "name": "Uruguay" + } + ] +} diff --git a/tests/testdata/maps/world/map.bin b/tests/testdata/maps/world/map.bin new file mode 100644 index 000000000..d841a10b6 --- /dev/null +++ b/tests/testdata/maps/world/map.bin @@ -0,0 +1 @@ +?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776665555555555544443333322222222332222222222111100011100/////////////....//////00112233221100//..--,,-,,,,,,,,,------.------,,++*********++,,-,,++**))))))(('''''&&&&&&&&&&&'&&%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$################$#######""""""""""""!"""""""""""!!!!!!!!!!!!!!!!!!!"""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!""!"""""""""""""""""""""############$$%%%%%%$$$$$$$$$$$$$$$$$$$############$$$######$$$$$$##############""""""""""!!!!!!!!!!!!!!!!!!!!`````!!!!!!!!!````````!!`````````!!!!!!"""""""""""""""""###$$%%&%%$$$$%%%%%%%%&&&&&%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++++++++++++++++++,+++++,,+++***++++++***))))))))))))(((()))***)))))))**))))))**************++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//..--,,++**)))))))))(((((((((((((()((((((('''''(((())**)))))))(((''''''&&&&&&&&&&&&&%%%%%%%%%%&&&&&&''''&&&&%%%%%%%%%%&&''''''''(())**++,,--..//0011223344556677887766554433221100//..--,,,,,,,,,,,++**))((((((((((())**++,,--..//00112233444433221100//..--,,++**))((''''''''''''(()(((('''''''''''&''&&''''(((((((())****+++++,,,-----,,-,,,,,,-----.......//0000//000000112233445555555555555555555565566778899::;;<<<<==>>>>>>>>>>>>>>??????????????????????>>>>>====>>>>>>>>>>>>>>>>>>>???????????????????????????>>==<<;;::9988778889988777766666666777777777776667777777777777888888899998888988776655555555566778899:9988776666778899::9988776655443445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655555555544444433333222222222222221111222110000000000////...................//001122221100//..--,,,,,,,,,,,,,,,,,--------,,++***********++,,,++**))))(((('''''&&&&&&&&&&&&&&%%%%%%%$$$$$$$$$$$$$$$$$$$$$$#####""""""""##########""""""!!"""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````!!!!``!!!`!!!!!!!!!!!!!!!!!!!!"!!!!!!!!""!!!!!""""""""""""##$$$$$$$$$$$$$$####################################$$##""""""""""""""!!!!!!!"!!!!!!!!!`````````````````````````````!!!!!!!!!"""""""""""##$$%%%$$#$$$$$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++++++++++++++++**++++++++++************)))))))))((((((((((()))))((((())))(())))))))))))))****++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((((((((((((((('(((((((((((''''&&&''(((()))))))))(('''''''&&&&&&&&%%%%%%%%%%$$$$$%%&&&&&&''&&%%%%%%%%%%%%%%&&&&&&&'''(())**++,,--..//00112233445566777766554433221100//..--,,+++++++++++**))(('''''''''(())**++,,--..//001122334433221100//..--,,++**))((''&&&&&&&&&&''(((''''''''''''&&&&&&&&&''''''((((())*******+++,,-,,,,,,,,,,,,,-,-----.....////////00//00112233444444444444444554455555566778899::;;;;<<==>>>>>>>>>>>>>>????????????????????>>===========>>>>>>>>>>>>>>>>>?????????????????????????>>==<<;;::99887777788887766666666566666677776666666666777777777777788889988888887766554444444556677889998877666666778899998877665544333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655544444444444333322222111111112211111111110000///000//.............----......//0011221100//..--,,++,+++++++++,,,,,,-,,,,,,++**)))))))))**++,++**))((((((''&&&&&%%%%%%%%%%%&%%$$$$$$$$$$$$$$$#################""""""""""""""""#"""""""!!!!!!!!!!!!`!!!!!!!!!!!```````````````````!!!```````````````````````!```!!`!!!!!!!!!!!!!!!!!!!!!""""""""""""##$$$$$$###################""""""""""""###""""""######""""""""""""""!!!!!!!!!!`````````!!!!!!!!!!!!!!!!!"""##$$%$$####$$$$$$$$%%%%%$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,++********************+*****++***)))******)))((((((((((((''''((()))((((((())(((((())))))))))))))**++,,--..//00112233445566778899::;;<<==>>??????????>>==<<;;::99887766554433221100//..--,,++**))(((((((((''''''''''''''('''''''&&&&&''''(())((((((('''&&&&&&%%%%%%%%%%%%%$$$$$$$$$$%%%%%%&&&&%%%%$$$$$$$$$$%%&&&&&&&&''(())**++,,--..//001122334455667766554433221100//..--,,+++++++++++**))(('''''''''''(())**++,,--..//0011223333221100//..--,,++**))((''&&&&&&&&&&&&''(''''&&&&&&&&&&&%&&%%&&&&''''''''(())))*****+++,,,,,++,++++++,,,,,-------..////..//////00112233444444444444444444445445566778899::;;;;<<==============>>?>>>??????????????>>=====<<<<===================>>>>>????????????????????>>==<<;;::9988776677788776666555555556666666666655566666666666667777777888877778776655444444444556677889887766555566778899887766554433233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554444444443333332222211111111111111000011100//////////....-------------------..//00111100//..--,,+++++++++++++++++,,,,,,,,++**)))))))))))**+++**))((((''''&&&&&%%%%%%%%%%%%%%$$$$$$$######################"""""!!!!!!!!""""""""""!!!!!!``!!!!!``````````````````ˁχÃ```````!````````!!`````!!!!!!!!!!!!""##############""""""""""""""""""""""""""""""""""""##""!!!!!!!!!!!!!!```````!`Ā`````````!!!!!!!!!!!""##$$$##"#####$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????>>==<<;;::99887766554433221100//..--,,++******************))**********))))))))))))((((((((('''''''''''((((('''''((((''(((((((((((((())))**++,,--..//00112233445566778899::;;<<==>>????????>>==<<;;::99887766554433221100//..--,,++**))(('''''''''''''''&'''''''''''&&&&%%%&&''''(((((((((''&&&&&&&%%%%%%%%$$$$$$$$$$#####$$%%%%%%&&%%$$$$$$$$$$$$$$%%%%%%%&&&''(())**++,,--..//0011223344556666554433221100//..--,,++***********))((''&&&&&&&&&''(())**++,,--..//00112233221100//..--,,++**))((''&&%%%%%%%%%%&&'''&&&&&&&&&&&&%%%%%%%%%&&&&&&'''''(()))))))***++,+++++++++++++,+,,,,,-----........//..//00112233333333333333344334444445566778899::::;;<<==============>>>>>>?>????????>>>>==<<<<<<<<<<<=================>>>>>>>????????????????>>==<<;;::998877666667777665555555545555556666555555555566666666666667777887777777665544333333344556677888776655555566778888776655443322233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554443333333333322221111100000000110000000000////...///..-------------,,,,------..//001100//..--,,++**+*********++++++,++++++**))((((((((())**+**))((''''''&&%%%%%$$$$$$$$$$$%$$###############"""""""""""""""""!!!!!!!!!!!!!!!!"!!!!!!!``````ȅȀˌɆ````!!!!!!!!!!!!""######"""""""""""""""""""!!!!!!!!!!!!"""!!!!!!""""""!!!!!!!!!!!!!!````````````!!!""##$##""""########$$$$$#######################$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))))))))))))))))))*)))))**)))((())))))(((''''''''''''&&&&'''((('''''''((''''''(((((((((((((())**++,,--..//00112233445566778899::;;<<==>>??????>>==<<;;::99887766554433221100//..--,,++**))(('''''''''&&&&&&&&&&&&&&'&&&&&&&%%%%%&&&&''(('''''''&&&%%%%%%$$$$$$$$$$$$$##########$$$$$$%%%%$$$$##########$$%%%%%%%%&&''(())**++,,--..//00112233445566554433221100//..--,,++***********))((''&&&&&&&&&&&''(())**++,,--..//001122221100//..--,,++**))((''&&%%%%%%%%%%%%&&'&&&&%%%%%%%%%%%$%%$$%%%%&&&&&&&&''(((()))))***+++++**+******+++++,,,,,,,--....--......//00112233333333333333333333433445566778899::::;;<<<<<<<<<<<<<<==>===>>>>>>>>>>>>>>==<<<<<;;;;<<<<<<<<<<<<<<<<<<<=====>>>>??????????????>>==<<;;::99887766556667766555544444444555555555554445555555555555666666677776666766554433333333344556677877665544445566778877665544332212233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443333333332222221111100000000000000////000//..........----,,,,,,,,,,,,,,,,,,,--..//0000//..--,,++*****************++++++++**))((((((((((())***))((''''&&&&%%%%%$$$$$$$$$$$$$$#######""""""""""""""""""""""!!!!!````````!!!!!!!!!!`````ɃΎƋ```````````!!""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""!!``````````````````!!""###""!"""""#######################################$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))))))))))))))))(())))))))))(((((((((((('''''''''&&&&&&&&&&&'''''&&&&&''''&&''''''''''''''(((())**++,,--..//00112233445566778899::;;<<==>>????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&&&&&&&&&&&%&&&&&&&&&&&%%%%$$$%%&&&&'''''''''&&%%%%%%%$$$$$$$$##########"""""##$$$$$$%%$$##############$$$$$$$%%%&&''(())**++,,--..//001122334455554433221100//..--,,++**)))))))))))((''&&%%%%%%%%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$$$$$$$$$%%&&&%%%%%%%%%%%%$$$$$$$$$%%%%%%&&&&&''((((((()))**+*************+*+++++,,,,,--------..--..//0011222222222222222332233333344556677889999::;;<<<<<<<<<<<<<<======>=>>>>>>>>====<<;;;;;;;;;;;<<<<<<<<<<<<<<<<<=======>>????????????>>==<<;;::9988776655555666655444444443444444555544444444445555555555555666677666666655443322222223344556677766554444445566777766554433221112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433322222222222111100000////////00//////////....---...--,,,,,,,,,,,,,++++,,,,,,--..//00//..--,,++**))*)))))))))******+******))(('''''''''(())*))((''&&&&&&%%$$$$$###########$##"""""""""""""""!!!!!!!!!!!!!!!!!````````!``͋`!!""""""!!!!!!!!!!!!!!!!!!!````````````!!!``````!!!!!!```````!!""#""!!!!""""""""#####"""""""""""""""""""""""#######$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((((((((((((((((((()((((())((('''(((((('''&&&&&&&&&&&&%%%%&&&'''&&&&&&&''&&&&&&''''''''''''''(())**++,,--..//00112233445566778899::;;<<==>>??>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&&&&&%%%%%%%%%%%%%%&%%%%%%%$$$$$%%%%&&''&&&&&&&%%%$$$$$$#############""""""""""######$$$$####""""""""""##$$$$$$$$%%&&''(())**++,,--..//0011223344554433221100//..--,,++**)))))))))))((''&&%%%%%%%%%%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$$$$$$$$$$$%%&%%%%$$$$$$$$$$$#$$##$$$$%%%%%%%%&&''''((((()))*****))*))))))*****+++++++,,----,,------..//0011222222222222222222223223344556677889999::;;;;;;;;;;;;;;<<=<<<==============<<;;;;;::::;;;;;;;;;;;;;;;;;;;<<<<<====>>??????????>>==<<;;::998877665544555665544443333333344444444444333444444444444455555556666555565544332222222223344556676655443333445566776655443322110112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322222222211111100000//////////////....///..----------,,,,+++++++++++++++++++,,--..////..--,,++**)))))))))))))))))********))(('''''''''''(()))((''&&&&%%%%$$$$$##############"""""""!!!!!!!!!!!!!!!!!!!!!!```````!!!!!!!!!!!!!!``````````````````!!`@`!!"""""!!`!!!!!"""""""""""""""""""""""""""""""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((((((((((((((((((''((((((((((''''''''''''&&&&&&&&&%%%%%%%%%%%&&&&&%%%%%&&&&%%&&&&&&&&&&&&&&''''(())**++,,--..//00112233445566778899::;;<<==>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%%%%%%%%%%$%%%%%%%%%%%$$$$###$$%%%%&&&&&&&&&%%$$$$$$$########""""""""""!!!!!""######$$##""""""""""""""#######$$$%%&&''(())**++,,--..//00112233444433221100//..--,,++**))(((((((((((''&&%%$$$$$$$$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##########$$%%%$$$$$$$$$$$$#########$$$$$$%%%%%&&'''''''((())*)))))))))))))*)*****+++++,,,,,,,,--,,--..//0011111111111111122112222223344556677888899::;;;;;;;;;;;;;;<<<<<<=<========<<<<;;:::::::::::;;;;;;;;;;;;;;;;;<<<<<<<==>>????????>>==<<;;::99887766554444455554433333333233333344443333333333444444444444455556655555554433221111111223344556665544333333445566665544332211000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433222111111111110000/////........//..........----,,,---,,+++++++++++++****++++++,,--..//..--,,++**))(()((((((((())))))*))))))((''&&&&&&&&&''(()((''&&%%%%%%$$#####"""""""""""#""!!!!!!!!!!!!!!!`````````````Ώ`!!!!!!!```````ǁ```````````!!"""!!```!!!!!!!!"""""!!!!!!!!!!!!!!!!!!!!!!!"""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''''''''''''''''''('''''(('''&&&''''''&&&%%%%%%%%%%%%$$$$%%%&&&%%%%%%%&&%%%%%%&&&&&&&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%%%%$$$$$$$$$$$$$$%$$$$$$$#####$$$$%%&&%%%%%%%$$$######"""""""""""""!!!!!!!!!!""""""####""""!!!!!!!!!!""########$$%%&&''(())**++,,--..//001122334433221100//..--,,++**))(((((((((((''&&%%$$$$$$$$$$$%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%$$############$$%$$$$###########"##""####$$$$$$$$%%&&&&'''''((()))))(()(((((()))))*******++,,,,++,,,,,,--..//0011111111111111111111211223344556677888899::::::::::::::;;<;;;<<<<<<<<<<<<<<;;:::::9999:::::::::::::::::::;;;;;<<<<==>>??????>>==<<;;::9988776655443344455443333222222223333333333322233333333333334444444555544445443322111111111223344556554433222233445566554433221100/00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111111111000000/////..............----...--,,,,,,,,,,++++*******************++,,--....--,,++**))((((((((((((((((())))))))((''&&&&&&&&&&&''(((''&&%%%%$$$$#####""""""""""""""!!!!!!!``````````!!``````˅``@@@@@@`!!!!!````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''''''''''''''''&&''''''''''&&&&&&&&&&&&%%%%%%%%%$$$$$$$$$$$%%%%%$$$$$%%%%$$%%%%%%%%%%%%%%&&&&''(())**++,,--..//00112233445566778899::;;<<====<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$$$$$$$$$#$$$$$$$$$$$####"""##$$$$%%%%%%%%%$$#######""""""""!!!!!!!!!!`````!!""""""##""!!!!!!!!!!!!!!"""""""###$$%%&&''(())**++,,--..//0011223333221100//..--,,++**))(('''''''''''&&%%$$#########$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""""""""""##$$$############"""""""""######$$$$$%%&&&&&&&'''(()((((((((((((()()))))*****++++++++,,++,,--..//0000000000000001100111111223344556677778899::::::::::::::;;;;;;<;<<<<<<<<;;;;::99999999999:::::::::::::::::;;;;;;;<<==>>????>>==<<;;::9988776655443333344443322222222122222233332222222222333333333333344445544444443322110000000112233445554433222222334455554433221100///00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211100000000000////.....--------..----------,,,,+++,,,++*************))))******++,,--..--,,++**))((''('''''''''(((((()((((((''&&%%%%%%%%%&&''(''&&%%$$$$$$##"""""!!!!!!!!!!!"!!`````````````@@@@@`!!!!!``````!!!!!```````````````````````!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&&&&&&&&&&&&&&&&'&&&&&''&&&%%%&&&&&&%%%$$$$$$$$$$$$####$$$%%%$$$$$$$%%$$$$$$%%%%%%%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$$$##############$#######"""""####$$%%$$$$$$$###""""""!!!!!!!!!!!!!`````!!!!!!""""!!!!``````````!!""""""""##$$%%&&''(())**++,,--..//00112233221100//..--,,++**))(('''''''''''&&%%$$###########$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##""""""""""""##$####"""""""""""!""!!""""########$$%%%%&&&&&'''(((((''(''''''((((()))))))**++++**++++++,,--..//0000000000000000000010011223344556677778899999999999999::;:::;;;;;;;;;;;;;;::9999988889999999999999999999:::::;;;;<<==>>??>>==<<;;::9988776655443322333443322221111111122222222222111222222222222233333334444333343322110000000001122334454433221111223344554433221100//.//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000000000//////.....--------------,,,,---,,++++++++++****)))))))))))))))))))**++,,----,,++**))(('''''''''''''''''((((((((''&&%%%%%%%%%%%&&'''&&%%$$$$####"""""!!!!!!!!!!!!!!`ˉ```!!`@@`!!````````````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&&&&&&&&&&&&&&%%&&&&&&&&&&%%%%%%%%%%%%$$$$$$$$$###########$$$$$#####$$$$##$$$$$$$$$$$$$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$###############"###########""""!!!""####$$$$$$$$$##"""""""!!!!!!!!``````ā`!!!!!!""!!````!!!!!!!"""##$$%%&&''(())**++,,--..//001122221100//..--,,++**))((''&&&&&&&&&&&%%$$##"""""""""##$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""!!!!!!!!!!""###""""""""""""!!!!!!!!!""""""#####$$%%%%%%%&&&''('''''''''''''('((((()))))********++**++,,--..///////////////00//00000011223344556666778899999999999999::::::;:;;;;;;;;::::998888888888899999999999999999:::::::;;<<==>>>>==<<;;::99887766554433222223333221111111101111112222111111111122222222222223333443333333221100///////0011223344433221111112233444433221100//...//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000///////////....-----,,,,,,,,--,,,,,,,,,,++++***+++**)))))))))))))(((())))))**++,,--,,++**))((''&&'&&&&&&&&&''''''(''''''&&%%$$$$$$$$$%%&&'&&%%$$######""!!!!!```````````!`ƈ```````````!!!!`Α````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%%%%%%%%%%%%%%%&%%%%%&&%%%$$$%%%%%%$$$############""""###$$$#######$$######$$$$$$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<;;::99887766554433221100//..--,,++**))((''&&%%$$#########""""""""""""""#"""""""!!!!!""""##$$#######"""!!!!!!```````````!`````!!!!``!!!!!!!!!""##$$%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&&&&&&&&&&%%$$##"""""""""""##$$%%&&''(())**++,,--....--,,++**))((''&&%%$$##""!!!!!!!!!!!!""#""""!!!!!!!!!!!`!!``!!!!""""""""##$$$$%%%%%&&&'''''&&'&&&&&&'''''((((((())****))******++,,--..////////////////////0//0011223344556666778888888888888899:999::::::::::::::99888887777888888888888888888899999::::;;<<==>>==<<;;::99887766554433221122233221111000000001111111111100011111111111112222222333322223221100/////////00112233433221100001122334433221100//..-..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////////......-----,,,,,,,,,,,,,,++++,,,++**********))))((((((((((((((((((())**++,,,,++**))((''&&&&&&&&&&&&&&&&&''''''''&&%%$$$$$$$$$$$%%&&&%%$$####""""!!!!!```````!!!``````````!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%%%%%%%%%%%%%$$%%%%%%%%%%$$$$$$$$$$$$#########"""""""""""#####"""""####""##############$$$$%%&&''(())**++,,--..//00112233445566778899::;;;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""""""""""""!"""""""""""!!!!```!!""""#########""!!!!!!!`€``!!!!`````````!!``````!!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%%%%%%%%%%$$##""!!!!!!!!!""##$$%%&&''(())**++,,--..--,,++**))((''&&%%$$##""!!``````````!!"""!!!!!!!!!!!!``````!!!!!!"""""##$$$$$$$%%%&&'&&&&&&&&&&&&&'&'''''((((())))))))**))**++,,--...............//..//////00112233445555667788888888888888999999:9::::::::99998877777777777888888888888888889999999::;;<<====<<;;::99887766554433221111122221100000000/00000011110000000000111111111111122223322222221100//.......//001122333221100000011223333221100//..---..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///...........----,,,,,++++++++,,++++++++++****)))***))(((((((((((((''''(((((())**++,,++**))((''&&%%&%%%%%%%%%&&&&&&'&&&&&&%%$$#########$$%%&%%$$##""""""!!``````````````````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$$$$$$$$$$$$$$%$$$$$%%$$$###$$$$$$###""""""""""""!!!!"""###"""""""##""""""##############$$%%&&''(())**++,,--..//00112233445566778899::;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""""""!!!!!!!!!!!!!!"!!!!!!!``!!!!""##"""""""!!!````````````````!!!!!!!!!```!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%%%%%%%%%%$$##""!!!!!!!!!!!""##$$%%&&''(())**++,,----,,++**))((''&&%%$$##""!!``!!"!!!!```````````!!!!!!!!""####$$$$$%%%&&&&&%%&%%%%%%&&&&&'''''''(())))(())))))**++,,--..................../..//00112233445555667777777777777788988899999999999999887777766667777777777777777777888889999::;;<<==<<;;::9988776655443322110011122110000////////00000000000///000000000000011111112222111121100//.........//0011223221100////00112233221100//..--,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????>>>>>==============>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????>>>===>>>>>>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.........------,,,,,++++++++++++++****+++**))))))))))(((('''''''''''''''''''(())**++++**))((''&&%%%%%%%%%%%%%%%%%&&&&&&&&%%$$###########$$%%%$$##""""!!!!```!!!```````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$$$$$$$$$$$$##$$$$$$$$$$############"""""""""!!!!!!!!!!!"""""!!!!!""""!!""""""""""""""####$$%%&&''(())**++,,--..//00112233445566778899::::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!!!!!!!!!`!!!!!!!!!!!`````!!!!"""""""""!!````!!`````````!!""##$$%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%$$$$$$$$$$$##""!!`````````!!""##$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!``!!!!```````!!!!!""#######$$$%%&%%%%%%%%%%%%%&%&&&&&'''''(((((((())(())**++,,---------------..--......//00112233444455667777777777777788888898999999998888776666666666677777777777777777888888899::;;<<<<;;::99887766554433221100000111100////////.//////0000//////////0000000000000111122111111100//..-------..//00112221100//////001122221100//..--,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????>>>>===================>>???????????????????????????????????????????????????????????????????????????????????????????????>???????>>>>=========>>>>>>>?>>>>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...-----------,,,,+++++********++**********))))((()))(('''''''''''''&&&&''''''(())**++**))((''&&%%$$%$$$$$$$$$%%%%%%&%%%%%%$$##"""""""""##$$%$$##""!!!!!!```!`ʀ````````Ń```!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####################$#####$$###"""######"""!!!!!!!!!!!!````!!!"""!!!!!!!""!!!!!!""""""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!!!`````````````!````````!!""!!!!!!!`@@@@``ʇ`!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$$$$$$$$$$##""!!``!!""##$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!``!!!!`````!!""""#####$$$%%%%%$$%$$$$$$%%%%%&&&&&&&''((((''(((((())**++,,--------------------.--..//00112233444455666666666666667787778888888888888877666665555666666666666666666677777888899::;;<<;;::99887766554433221100//0001100////........///////////.../////////////000000011110000100//..---------..//001121100//....//0011221100//..--,,+,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????>>=====<<<<<<<<<<<<<<====>>??????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>===<<<===========>>>>>>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---------,,,,,,+++++**************))))***))((((((((((''''&&&&&&&&&&&&&&&&&&&''(())****))((''&&%%$$$$$$$$$$$$$$$$$%%%%%%%%$$##"""""""""""##$$$##""!!!!`````````````````````Ǝ```````!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##################""##########""""""""""""!!!!!!!!!```````!!!!!`````!!!!``!!!!!!!!!!!!!!""""##$$%%&&''(())**++,,--..//0011223344556677889999887766554433221100//..--,,++**))((''&&%%$$##""!!``````````!!!!!!!!!`ŋ`!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$###########""!!``!!""##$$%%&&''(())**++,,----,,++**))((''&&%%$$##""!!`````````!!````!!"""""""###$$%$$$$$$$$$$$$$%$%%%%%&&&&&''''''''((''(())**++,,,,,,,,,,,,,,,--,,------..//00112233334455666666666666667777778788888888777766555555555556666666666666666677777778899::;;;;::99887766554433221100/////0000//........-......////........../////////////0000110000000//..--,,,,,,,--..//0011100//......//00111100//..--,,+++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>====<<<<<<<<<<<<<<<<<<<==>>??????????????????????????????????????????????????????????????????????????????????????>>>>>>>=>>>>>>>====<<<<<<<<<=======>=========>>>>???>>>>>?>>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,,,,,,,,,,,++++*****))))))))**))))))))))(((('''(((''&&&&&&&&&&&&&%%%%&&&&&&''(())**))((''&&%%$$##$#########$$$$$$%$$$$$$##""!!!!!!!!!""##$##""!!```@`````!!``ȏ``````!!!!!!!!!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""""""""""""""""""#"""""##"""!!!""""""!!!`````````!!!``!!````!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899887766554433221100//..--,,++**))((''&&%%$$##""!!`ʌ`!!!```````@```````````!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$#############""!!`````````!!""##$$%%&&''(())**++,,--..--,,++**))((''&&%%$$##""!!!!!!!!!````!!!!!"""""###$$$$$##$######$$$$$%%%%%%%&&''''&&''''''(())**++,,,,,,,,,,,,,,,,,,,,-,,--..//00112233334455555555555555667666777777777777776655555444455555555555555555556666677778899::;;::99887766554433221100//..///00//....--------...........---.............///////0000////0//..--,,,,,,,,,--..//00100//..----..//001100//..--,,++*++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????>>==<<<<<;;;;;;;;;;;;;;<<<<==>>?????????????????????????????????????????????????????????????????????????????>>??>>>>>>>==============<<<;;;<<<<<<<<<<<=============>>>>>>>>>>>>>>>>>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,,,,,++++++*****))))))))))))))(((()))((''''''''''&&&&%%%%%%%%%%%%%%%%%%%&&''(())))((''&&%%$$#################$$$$$$$$##""!!!!!!!!!!!""###""!!`@@@@@@@@@```!!!!```````!!!!!!!!!!!!!"""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""""""""""""""""!!""""""""""!!!!!!!!!!!!``````````````````````!!!!""##$$%%&&''(())**++,,--..//00112233445566778899887766554433221100//..--,,++**))((''&&%%$$##""!!``````!!``@@Å```!!!``````!!!!!!!!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$##"""""""""####""!!!!!!!!!!!""##$$%%&&''(())**++,,--....--,,++**))((''&&%%$$##""!!!!!!!`````!!!!!!!!!!"""##$#############$#$$$$$%%%%%&&&&&&&&''&&''(())**+++++++++++++++,,++,,,,,,--..//00112222334455555555555555666666767777777766665544444444444555555555555555556666666778899::::99887766554433221100//.....////..--------,------....----------.............////00///////..--,,+++++++,,--..//000//..------..//0000//..--,,++***++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????>>==<<<<;;;;;;;;;;;;;;;;;;;<<==>>?????????????????????????????????????????????????????????????????????????>>>>>>>>>>>=======<=======<<<<;;;;;;;;;<<<<<<<=<<<<<<<<<====>>>=====>=======>>>>>>>>>??>>>>>>????????????????????????????????????????????????????????????????????????????????????>???>>>>==<<;;::99887766554433221100//..--,,,+++++++++++****)))))(((((((())((((((((((''''&&&'''&&%%%%%%%%%%%%%$$$$%%%%%%&&''(())((''&&%%$$##""#"""""""""######$######""!!`````````!!""##""!!`@@@``!!!!!!``!!!!!!!!!""""""""""#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!!!!!!!!!!!!!!"!!!!!""!!!```!!!!!!``````!!""##$$%%&&''(())**++,,--..//00112233445566778899887766554433221100//..--,,++**))((''&&%%$$##""!!!````````````!!!!`@Á@```````!!!!!!!!!!!!!!!!!!!!""##$$%%&&''(())****++,,--..//0//..--,,++**))((''&&%%$$##"""""""""""####""!!!!!!!!!""##$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""""!!``````!`````!!!!!"""#####""#""""""#####$$$$$$$%%&&&&%%&&&&&&''(())**++++++++++++++++++++,++,,--..//00112222334444444444444455655566666666666666554444433334444444444444444444555556666778899::99887766554433221100//..--...//..----,,,,,,,,-----------,,,-------------.......////..../..--,,+++++++++,,--..//0//..--,,,,--..//00//..--,,++**)**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????>>==<<;;;;;::::::::::::::;;;;<<==>>???????????????????????????????????????????????????????????????????????>>>>==>>=======<<<<<<<<<<<<<<;;;:::;;;;;;;;;;;<<<<<<<<<<<<<========================>>>>>>>>>>>>>>>????>>>>>>>>>?????????????????????????????????????????????????????????????????>>>>>>>>>==<<;;::99887766554433221100//..--,,+++++++++******)))))((((((((((((((''''(((''&&&&&&&&&&%%%%$$$$$$$$$$$$$$$$$$$%%&&''((((''&&%%$$##"""""""""""""""""########""!!``!!""""!!`@@```!!!!!"!!```!!!!"""""""""""""#######$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!!!!!!!!!!!!``!!!!!!!!!!````````Ĉ`!!""##$$%%&&''(())**++,,--..//00112233445566778899887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!!````!!```@@ā`!``!!!!!!!"""!!!!!!"""""""""##$$%%&&''(()))))***++,,--..///..--,,++**))((''&&%%$$##""!!!!!!!!!""####"""""""""""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##""!!``````!!!""#"""""""""""""#"#####$$$$$%%%%%%%%&&%%&&''(())***************++**++++++,,--..//0011112233444444444444445555556566666666555544333333333334444444444444444455555556677889999887766554433221100//..-----....--,,,,,,,,+,,,,,,----,,,,,,,,,,-------------....//.......--,,++*******++,,--..///..--,,,,,,--..////..--,,++**)))**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????>>>>>>>>???????????????????????????????>>==<<;;;;:::::::::::::::::::;;<<==>>????????????????????????????????????????????????????????????????????>>>===========<<<<<<<;<<<<<<<;;;;:::::::::;;;;;;;<;;;;;;;;;<<<<===<<<<<=<<<<<<<=========>>======>>>>>>>>>>>>>>>>>>>>???????????????????????????????????????????????????????????>>>>>=>>>====<<;;::99887766554433221100//..--,,+++***********))))(((((''''''''((''''''''''&&&&%%%&&&%%$$$$$$$$$$$$$####$$$$$$%%&&''((''&&%%$$##""!!"!!!!!!!!!""""""#"""""""!!``!!"""!!`@```!!!!!"""""!!``@``````!!!"""""""""##########$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````````````````!`````!!`@`!!""##$$%%&&''(())**++,,--..//001122334455667788999887766554433221100//..--,,++**))((''&&%%$$##"""!!!!!!!``````````!!`````````````!!``````!!!!!!!""""""""""""""""""""##$$%%&&''(())))))))**++,,--../..--,,++**))((''&&%%$$##""!!!!!!!!!!!""####"""""""""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!``!!!"""""!!"!!!!!!"""""#######$$%%%%$$%%%%%%&&''(())********************+**++,,--..//00111122333333333333334454445555555555555544333332222333333333333333333344444555566778899887766554433221100//..--,,---..--,,,,++++++++,,,,,,,,,,,+++,,,,,,,,,,,,,-------....----.--,,++*********++,,--../..--,,++++,,--..//..--,,++**))())**++,,--..//00112233445566778899::;;<<==>>????????????????>>>>>>>>>?????>>>>>>>>>>>>>>>>>>>>???????????????????>>==<<;;:::::99999999999999::::;;<<==>>??????????????????????????????????????????????????????????????????>>>====<<==<<<<<<<;;;;;;;;;;;;;;:::999:::::::::::;;;;;;;;;;;;;<<<<<<<<<<<<<<<<<<<<<<<<===============>>>>=========>>>>>>>>?????????????????????????????????????????????????>>>>>>>>=========<<;;::99887766554433221100//..--,,++*********))))))(((((''''''''''''''&&&&'''&&%%%%%%%%%%$$$$###################$$%%&&''''&&%%$$##""!!!!!!!!!!!!!!!!!"""""""""""!!`ć`!!""""!!`@@``!!!!!!""""""""!!!`````````````!!!!!!!""""#############$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ã```€`!!""##$$%%&&''(())**++,,--..//0011223344556677889999887766554433221100//..--,,++**))((''&&%%$$##""""""""!!!!!!!````````!!!````!!!!!!!!!!!!!!!!!!!!!`````````!````````!!!!"""""""###""""""#########$$%%&&''((((((((()))**++,,--...--,,++**))((''&&%%$$##""!!`````````!!""#############$$%%&&''(())**++,,--..//0////..--,,++**))((''&&%%$$##""!!```!!"!!!!!!!!!!!!!"!"""""#####$$$$$$$$%%$$%%&&''(()))))))))))))))**))******++,,--..//000011223333333333333344444454555555554444332222222222233333333333333333444444455667788887766554433221100//..--,,,,,----,,++++++++*++++++,,,,++++++++++,,,,,,,,,,,,,----..-------,,++**)))))))**++,,--...--,,++++++,,--....--,,++**))((())**++,,--..//00112233445566778899::;;<<==>>??????????????>>>>>>>>>>>???>>========>>>>>>>>>>>>>>>>>>>>>>>>>>>??>>==<<;;::::9999999999999999999::;;<<==>>????????????????????????????????????????????????????????????????>>===<<<<<<<<<<<;;;;;;;:;;;;;;;::::999999999:::::::;:::::::::;;;;<<<;;;;;<;;;;;;;<<<<<<<<<==<<<<<<====================>>>>>>>>>>?>>>>>>>>?????????????????>>>>>>>>>>>>???>>>>>>>>=====<===<<<<;;::99887766554433221100//..--,,++***)))))))))))(((('''''&&&&&&&&''&&&&&&&&&&%%%%$$$%%%$$#############""""######$$%%&&''&&%%$$##""!!``!`````````!!!!!!"!!!!!""""!!```````!!"""""!!`````````!`!!!!""""""!!!!!!!!!!!!!!!!!!`````!!!!!!"""#########$$$$$$$$$$%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::99887766554433221100//..--,,++**))((''&&%%$$###"""""""!!!!!!!!!!!!!!!!!!!!`````````!!"!!!!!!!!!!!!!""!!!!!!!!!!!!!!!!!!!`````````!!!!"""""""####################$$%%&&''(((((((((((())**++,,--.--,,++**))((''&&%%$$##""!!``!!""###########$$%%&&''(())**++++,,--..///....--,,++**))((''&&%%$$##""!!``!!!!!``!``````!!!!!"""""""##$$$$##$$$$$$%%&&''(())))))))))))))))))))*))**++,,--..//0000112222222222222233433344444444444444332222211112222222222222222222333334444556677887766554433221100//..--,,++,,,--,,++++********+++++++++++***+++++++++++++,,,,,,,----,,,,-,,++**)))))))))**++,,--.--,,++****++,,--..--,,++**))(('(())**++,,--..//00112233445566778899::;;<<==>>>>>>>>>>>>>>>>=========>>?>>====================>>>>>>>>>>>>>>>>>>>==<<;;::99999888888888888889999::;;<<==>>??????????????????????????????????????????????????????????????>>===<<<<;;<<;;;;;;;::::::::::::::99988899999999999:::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;<<<<<<<<<<<<<<<====<<<<<<<<<========>>>>>>>>>>>>>>>???????????????>>>>>>>>>>>>>>>>>>>========<<<<<<<<<;;::99887766554433221100//..--,,++**)))))))))(((((('''''&&&&&&&&&&&&&&%%%%&&&%%$$$$$$$$$$####"""""""""""""""""""##$$%%&&&&%%$$##""!!``````!!!!!!!!!!"""!!!!!!!```!!"""""""!!!!````````!!!!!!!!!""""""!!!!!!!!!!!!!!!!!!````````````!!!"""""""####$$$$$$$$$$$$$%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@@Ƅ```!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::::99887766554433221100//..--,,++**))((''&&%%$$########"""""""!!!!!!!!"""!!!!!!!!!!!!!"""""""""""""""""""""!!!!!!!!!"!!!!!!!!!!!!!!!!!""""#######$$$######$$$$$$$$$%%&&''(''''''''''((())**++,,--.--,,++**))((''&&%%$$##""!!``!!""##$$$$$$$$$%%&&''(())******++,,--../....--,,++**))((''&&%%$$##""!!`@``!!!`````!`!!!!!"""""########$$##$$%%&&''((((((((((((((())(())))))**++,,--..////001122222222222222333333434444444433332211111111111222222222222222223333333445566777766554433221100//..--,,+++++,,,,++********)******++++**********+++++++++++++,,,,--,,,,,,,++**))((((((())**++,,---,,++******++,,----,,++**))(('''(())**++,,--..//00112233445566778899::;;<<==>>>>>>>>>>>>>>===========>>>==<<<<<<<<===========================>>==<<;;::9999888888888888888888899::;;<<==>>????????????????????????????????????????????????????????????>>==<<<;;;;;;;;;;;:::::::9:::::::99998888888889999999:999999999::::;;;:::::;:::::::;;;;;;;;;<<;;;;;;<<<<<<<<<<<<<<<<<<<<==========>========>>>????????????>>============>>>========<<<<<;<<<;;;;::99887766554433221100//..--,,++**)))(((((((((((''''&&&&&%%%%%%%%&&%%%%%%%%%%$$$$###$$$##"""""""""""""!!!!""""""##$$%%&&&%%$$##""!!```!`````!!!!!!!!!!!!!!!!!!!!!!!!"!!!!`@@````````!!!!!!!!!!!!"!""!!!!!!!!````````````````!!!````!!""""###$$$$$$$$$%%%%%%%%%%&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`@`!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;::99887766554433221100//..--,,++**))((''&&%%$$$#######""""""""""""""""""""!!!!!!!!!""#"""""""""""""##"""""""""""""""""""!!!!!!!!!""""#######$$$$$$$$$$$$$$$$$$$$%%&&''''''''''''''''(())**++,,--.--,,++**))((''&&%%$$##""!!`````````!!""##$$$$$$$$$%%&&''(())********++,,--...--..--,,++**))((''&&%%$$##""!!`````````!!!!`````!!!!!!!""####""######$$%%&&''(((((((((((((((((((()(())**++,,--..////0011111111111111223222333333333333332211111000011111111111111111112222233334455667766554433221100//..--,,++**+++,,++****))))))))***********)))*************+++++++,,,,++++,++**))((((((((())**++,,-,,++**))))**++,,--,,++**))((''&''(())**++,,--..//00112233445566778899::;;<<================<<<<<<<<<==>==<<<<<<<<<<<<<<<<<<<<===================<<;;::998888877777777777777888899::;;<<==>>??????????????????????????????????????????????????????????>>==<<<;;;;::;;:::::::99999999999999888777888888888889999999999999::::::::::::::::::::::::;;;;;;;;;;;;;;;<<<<;;;;;;;;;<<<<<<<<===============>>>>>>???????>>===================<<<<<<<<;;;;;;;;;::99887766554433221100//..--,,++**))(((((((((''''''&&&&&%%%%%%%%%%%%%%$$$$%%%$$##########""""!!!!!!!!!!!!!!!!!!!""##$$%%&%%$$##""!!````!!!!!!!!""!!!!!!!!!!!!!!!!!!```````!!!!!!!!!!!!"!!!!!!!!!!!!!!````!!`ǂ`!!""###$$$$%%%%%%%%%%%%%&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```Ā`````````````````!!!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$$#######""""""""###"""""""""""""#####################"""""""""#"""""""""""""""""####$$$$$$$%%%$$$$$$%%%%%%%%%&&'''''&&&&&&&&&&'''(())**++,,--.--,,++**))((''&&%%$$##""!!!!!!!!!!!""##$$%%%%%%%%%&&''(())*)))))))**++,,--.------,,++**))((''&&&&%%$$##""!!!!!!!`````!````!!!````!!!!!""""""""##""##$$%%&&'''''''''''''''((''(((((())**++,,--....//00111111111111112222223233333333222211000000000001111111111111111122222223344556666554433221100//..--,,++*****++++**))))))))())))))****))))))))))*************++++,,+++++++**))(('''''''(())**++,,,++**))))))**++,,,,++**))((''&&&''(())**++,,--..//00112233445566778899::;;<<==============<<<<<<<<<<<===<<;;;;;;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<==<<;;::99888877777777777777777778899::;;<<==>>???????????????????????????????????????????????????>>>>>>>==<<;;;:::::::::::9999999899999998888777777777888888898888888889999:::99999:9999999:::::::::;;::::::;;;;;;;;;;;;;;;;;;;;<<<<<<<<<<=<<<<<<<<===>>>>>>>>??>>==<<<<<<<<<<<<===<<<<<<<<;;;;;:;;;::::99887766554433221100//..--,,++**))((('''''''''''&&&&%%%%%$$$$$$$$%%$$$$$$$$$$####"""###""!!!!!!!!!!!!!````!!!!!!""##$$%%%%$$##""!!`Ņ`````!!!!""!!`````````!!!!!!!!!```!``!!!!!!"!!!!!!!!!!!!!!!``````!```!!""##$$%%%%%%%%%&&&&&&&&&&'''''(())**++,,--..//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```````!!!!``````````!!!!!!!!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<;;::99887766554433221100//..--,,++**))((''&&%%%$$$$$$$####################"""""""""##$#############$$###################"""""""""####$$$$$$$%%%%%%%%%%%%%%%%%%%%&&'&&&&&&&&&&&&&&&&&''(())**++,,--.--,,++**))((''&&%%$$##""!!!!!!!!!""##$$%%%%%%%%%&&''(())))))))))))**++,,---,,--,,++**))((''&&%%%%%%$$##""!!!!!!!``!!!!!!````````!!""""!!""""""##$$%%&&''''''''''''''''''''(''(())**++,,--....//00000000000000112111222222222222221100000////000000000000000000011111222233445566554433221100//..--,,++**))***++**))))(((((((()))))))))))((()))))))))))))*******++++****+**))(('''''''''(())**++,++**))(((())**++,,++**))((''&&%&&''(())**++,,--..//00112233445566778899::;;<<<<<<<<<<<<<<<<;;;;;;;;;<<=<<;;;;;;;;;;;;;;;;;;;;<<<<<<<<<<<<<<<<<<<;;::9988777776666666666666677778899::;;<<==>>??????????????????????????????????????????>>>>>>>>>>>>>>==<<;;;::::99::999999988888888888888777666777777777778888888888888999999999999999999999999:::::::::::::::;;;;:::::::::;;;;;;;;<<<<<<<<<<<<<<<======>>>>>>>==<<<<<<<<<<<<<<<<<<<;;;;;;;;:::::::::99887766554433221100//..--,,++**))(('''''''''&&&&&&%%%%%$$$$$$$$$$$$$$####$$$##""""""""""!!!!```````````````!!""##$$%%%%$$##""!!````!!!!``````````!!!!``!!"""!!````!``````````!````!!""##$$%%%%&&&&&&&&&&&&&'''''''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`€```!!!!!!!!!!!!!!!!!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<;;::99887766554433221100//..--,,++**))((''&&%%%%%%%%$$$$$$$########$$$#############$$$$$$$$$$$$$$$$$$$$$#########$#################$$$$%%%%%%%&&&%%%%%%&&&&&&&&&&&&&&&&%%%%%%%%%%&&&''(())**++,,--.--,,++**))((''&&%%$$##"""""""""""##$$%%&&&&&&&&&''(()(())((((((())**++,,-,,,,,,++**))((''&&%%%%$$$$$$##"""""""!!`````!!!!!!!!``````````!!!!!!!!""!!""##$$%%&&&&&&&&&&&&&&&''&&''''''(())**++,,----..//000000000000001111112122222222111100///////////00000000000000000111111122334455554433221100//..--,,++**)))))****))(((((((('(((((())))(((((((((()))))))))))))****++*******))((''&&&&&&&''(())**+++**))(((((())**++++**))((''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<<<<<<<<<<<<<;;;;;;;;;;;<<<;;::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;<<;;::998877776666666666666666666778899::;;<<==>>????????????????????????????????????????>>>>>>>>>=======<<;;:::9999999999988888887888888877776666666667777777877777777788889998888898888888999999999::999999::::::::::::::::::::;;;;;;;;;;<;;;;;;;;<<<========>>==<<;;;;;;;;;;;;<<<;;;;;;;;:::::9:::9999887766554433221100//..--,,++**))(('''&&&&&&&&&&&%%%%$$$$$########$$##########""""!!!"""!!````!!""##$$%%%%$$##""!!````!!!````!!````!!""!!``ņ``!!!!""##$$%%&&&&&&&&&''''''''''((((())**++,,--..//00112233445566778899::;;<<==>>????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!!!""""""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<;;::99887766554433221100//..--,,++**))((''&&&%%%%%%%$$$$$$$$$$$$$$$$$$$$#########$$%$$$$$$$$$$$$$%%$$$$$$$$$$$$$$$$$$$#########$$$$%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%&&''(())**++,,--.--,,++**))((''&&%%$$##"""""""""##$$%%&&&&&&&&&''(()((((((((((((())**++,,,++,,++**))((''&&%%$$$$$$$$$$##"""""""!!!!!!!"!!!!"!!!!!!!!````````````!!!!``!!!!!!""##$$%%&&&&&&&&&&&&&&&&&&&&'&&''(())**++,,----..//////////////0010001111111111111100/////....///////////////////000001111223344554433221100//..--,,++**))(()))**))((((''''''''((((((((((('''((((((((((((()))))))****))))*))((''&&&&&&&&&''(())**+**))((''''(())**++**))((''&&%%$%%&&''(())**++,,--..//00112233445566778899::;;;;;;;;;;;;;;;;:::::::::;;<;;::::::::::::::::::::;;;;;;;;;;;;;;;;;;;::99887766666555555555555556666778899::;;<<==>>?????????????????????????????????????>>>==============<<;;:::99998899888888877777777777777666555666666666667777777777777888888888888888888888888999999999999999::::999999999::::::::;;;;;;;;;;;;;;;<<<<<<=======<<;;;;;;;;;;;;;;;;;;;::::::::999999999887766554433221100//..--,,++**))((''&&&&&&&&&%%%%%%$$$$$##############""""###""!!!!!!!!!!``!!""##$$%%%$$##"""!!!``!!``!!!!`````!!""!!`Ć@@@@@@`!!!!""##$$%%&&&&'''''''''''''((((((())**++,,--..//00112233445566778899::;;<<==>>??????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````````!!""""""""""""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<;;::99887766554433221100//..--,,++**))((''&&&&&&&&%%%%%%%$$$$$$$$%%%$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$%$$$$$$$$$$$$$$$$$%%%%&&&&&&&'&&&&&&&&&&&&&&&&&%%%%%%%$$$$$$$$$$%%%&&''(())**++,,--.--,,++**))((''&&%%$$###########$$%%&&'''''''''(()((''(('''''''(())**++,++++++**))((''&&%%$$$$#####$$$#######""!!!!!"!!``!!"!!!!!!!!!!!!!!!````````````````!````!!``!!""##$$%%%%%%%%%%%%%%%&&%%&&&&&&''(())**++,,,,--..//////////////00000010111111110000//.........../////////////////0000000112233444433221100//..--,,++**))((((())))((''''''''&''''''((((''''''''''((((((((((((())))**)))))))((''&&%%%%%%%&&''(())***))((''''''(())****))((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;;;;;;;;;;;;;:::::::::::;;;::99999999:::::::::::::::::::::::::::;;::9988776666555555555555555555566778899::;;<<==>>???????????????????????????????????>>>=========<<<<<<<;;::99988888888888777777767777777666655555555566666667666666666777788877777877777778888888889988888899999999999999999999::::::::::;::::::::;;;<<<<<<<<==<<;;::::::::::::;;;::::::::99999899988887766554433221100//..--,,++**))((''&&&%%%%%%%%%%%$$$$#####""""""""##""""""""""!!!!```!!!``!!""##$$%%$$##""!!"!!``````!!!!!!``````!!!""!!``@@@@````!!!"""##$$%%&&'''''''''(((((((((()))))**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!```````!!!!!""#####""!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<<<;;::99887766554433221100//..--,,++**))(('''&&&&&&&%%%%%%%%%%%%%%%%%%%%$$$$$$$$$%%&%%%%%%%%%%%%%&&%%%%%%%%%%%%%%%%%%%$$$$$$$$$%%%%&&&&&&&&&&&&&&&&&&%&%%%%%%%%%%$$$$$$$$$$$$$$$$$%%&&''(())**++,,--.--,,++**))((''&&%%$$#########$$%%&&'''''''''(()(('''''''''''''(())**+++**++**))((''&&%%$$#########$$$#####""""""""!!``!!"""""""!!!!!!!!!!!!!!!!!!!!````!````!!""##$$%%%%%%%%%%%%%%%%%%%%&%%&&''(())**++,,,,--..............//0///00000000000000//.....----.................../////00001122334433221100//..--,,++**))((''((())((''''&&&&&&&&'''''''''''&&&'''''''''''''((((((())))(((()((''&&%%%%%%%%%&&''(())*))((''&&&&''(())**))((''&&%%$$#$$%%&&''(())**++,,--..//00112233445566778899::::::::::::::::999999999::;::99999999999999999999:::::::::::::::::::998877665555544444444444444555566778899::;;<<==>>?????????????????????????????????>>===<<<<<<<<<<<<<<;;::99988887788777777766666666666666555444555555555556666666666666777777777777777777777777888888888888888999988888888899999999:::::::::::::::;;;;;;<<<<<<<;;:::::::::::::::::::999999998888888887766554433221100//..--,,++**))((''&&%%%%%%%%%$$$$$$#####""""""""""""""!!!!"""!!```````@@@@`!!""##$$%%$$##""!!!!!!!`À````!!!!!!!!````!``!!!""!!`@@`!!!!!!!""##$$%%&&'''((((((((((((()))))))**++,,--..//00112233445566778899::;;<<==>>??????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!```````!!!```!!!!!""#####""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;<<<<<<;;::99887766554433221100//..--,,++**))((''''''''&&&&&&&%%%%%%%%&&&%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%&%%%%%%%%%%%%%%%%%&&%%%%%%%%%&%%%%%%%%%%%%%%%%%$$$$$$$##########$$$%%&&''(())**++,,--.--,,++**))((''&&%%$$$$$$$$$$$%%&&''((((((((()((''&&''&&&&&&&''(())**+******))((''&&%%$$####"""""##$$$$##""!!!""""!!``!!""""""""""""""!!!!!!!!!!!``````!!!``!!""##$$$$$$$$$$$$$$$%%$$%%%%%%&&''(())**++++,,--..............//////0/00000000////..-----------.................///////0011223333221100//..--,,++**))(('''''((((''&&&&&&&&%&&&&&&''''&&&&&&&&&&'''''''''''''(((())(((((((''&&%%$$$$$$$%%&&''(()))((''&&&&&&''(())))((''&&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::::::::::::::99999999999:::9988888888999999999999999999999999999::99887766555544444444444444444445566778899::;;<<==>>???????????????????????????????>>===<<<<<<<<<;;;;;;;::99888777777777776666666566666665555444444444555555565555555556666777666667666666677777777788777777888888888888888888889999999999:99999999:::;;;;;;;;<<;;::999999999999:::99999999888887888777766554433221100//..--,,++**))((''&&%%%$$$$$$$$$$$####"""""!!!!!!!!""!!!!!!!!!!````!!""##$$%%$$##""!!``!!!!!````````@@@@@@@`!!``````````!!!!````````````````````!!""""!!`@`!!!```!!""##$$%%&&''(((((())))))))))*****++,,--..//00112233445566778899::;;<<==>>????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!!````!!!````!!!!!!```````!!""##$##"""""##$$%%&&''(())**++,,--..//00112233445566778899::::;;;;;;<<<<;;::99887766554433221100//..--,,++**))((('''''''&&&&&&&&&&&&&&&&&&&&%%%%%%%%%&&'&&&&&&&&&&&&&''&&&&&&&&&&&&&&&&&&&%%%%%%%%%&%%%%%%%%%%%%%%%%%%%%%$%$$$$$$$$$$#################$$%%&&''(())**++,,--.--,,++**))((''&&%%$$$$$$$$$%%&&''((((((((()((''&&&&&&&&&&&&&''(())***))**))((''&&%%$$##"""""""""##$$##""!!!!!"""!!``!!""###""""""""""""""""""!!````````````!!!!!!!!!````!!""##$$$$$$$$$$$$$$$$$$$$$$%$$%%&&''(())**++++,,--------------../...//////////////..-----,,,,-------------------.....////00112233221100//..--,,++**))((''&&'''((''&&&&%%%%%%%%&&&&&&&&&&&%%%&&&&&&&&&&&&&'''''''((((''''(''&&%%$$$$$$$$$%%&&''(()((''&&%%%%&&''(())((''&&%%$$##"##$$%%&&''(())**++,,--..//001122334455667788999999999999999988888888899:9988888888888888888888999999999999999999988776655444443333333333333344445566778899::;;<<==>>?????????????????????????????>>==<<<;;;;;;;;;;;;;;::9988877776677666666655555555555555444333444444444445555555555555666666666666666666666666777777777777777888877777777788888888999999999999999::::::;;;;;;;::99999999999999999998888888877777777766554433221100//..--,,++**))((''&&%%$$$$$$$$$######"""""!!!!!!!!!!!!!!````!!!!!``!!""##$$%$$##""!!`````!!!!!!!!!````ƒÀ`!!!!```!!!!!!!`````````````!``!!`Š@`!!!!"""#""!!`````!```!!""##$$%%&&''(())))))))))*******++,,--..//00112233445566778899::;;<<==>>??????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!!!!!!!!!!!```!!"""!!!!```!!""##$##"""##$$%%&&''(())**++,,--..//00112233445566778899::::::::;;;;;<<<;;::99887766554433221100//..--,,++**))(((((((('''''''&&&&&&&&'''&&&&&&&&&&&&&'''''''''''''''''''''&&&&&&&&&'&&&&&&&&%%%%&%%%%%%$$$$$$$$$%$$$$$$$$$$$$$$$$$#######""""""""""###$$%%&&''(())**++,,--.--,,++**))((''&&%%%%%%%%%%%&&''(())))))))((''&&%%&&%%%%%%%&&''(())*))))))((''&&%%$$##""""!!!!!""####""!!```!!"""!!```!!""##"""""""!""#"""""""""!!````````!`!!!`````````````!````!!!```````!!""###################$$##$$$$$$%%&&''(())****++,,--------------.....././///////....--,,,,,,,,,,,-----------------.......//001122221100//..--,,++**))((''&&&&&''''&&%%%%%%%%$%%%%%%&&&&%%%%%%%%%%&&&&&&&&&&&&&''''(('''''''&&%%$$#######$$%%&&''(((''&&%%%%%%&&''((((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899999999999999888888888889998877777777888888888888888888888888888998877665544443333333333333333333445566778899::;;<<==>>???????????????????????????>>==<<<;;;;;;;;;:::::::9988777666666666665555555455555554444333333333444444454444444445555666555556555555566666666677666666777777777777777777778888888888988888888999::::::::;;::99888888888888999888888887777767776666554433221100//..--,,++**))((''&&%%$$$###########""""!!!!!````````!!``````!!```!!""""##$$$##""!!````!!!!!!!!!``!!""!!`````!!!!!!!!``!!!!!!`@@```````````!!!!""####""!!!!!``````!``!!""##$$%%&&''(()))**********+++++,,--..//00112233445566778899::;;<<==>>????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""""!!!!"""!!!```!!""""""!!`Ā`!!""##$$#####$$%%&&''(())**++,,--..//00112233445566778899999999::::::;;;;;;;;::99887766554433221100//..--,,++**)))(((((((''''''''''''''''''''&&&&&&&&&''('''''''''''''(('''''''''''&&&&&&&&&&%%%%%%%%$$$$$$$$$$$$$$$$$$$$$#$##########"""""""""""""""""##$$%%&&''(())**++,,--.--,,++**))((''&&%%%%%%%%%&&''(())))))))((''&&%%%%%%%%%%%%%&&''(()))(())((''&&%%$$##""!!!!!!!!!""##""!!``!!"""!!!!!""##"""!!!!!!!""########""!!```````!!!!!!!!````````!```!!`!!!""#########################$##$$%%&&''(())****++,,,,,,,,,,,,,,--.---..............--,,,,,++++,,,,,,,,,,,,,,,,,,,-----....//0011221100//..--,,++**))((''&&%%&&&''&&%%%%$$$$$$$$%%%%%%%%%%%$$$%%%%%%%%%%%%%&&&&&&&''''&&&&'&&%%$$#########$$%%&&''(''&&%%$$$$%%&&''((''&&%%$$##""!""##$$%%&&''(())**++,,--..//00112233445566778888888888888888777777777889887777777777777777777788888888888888888887766554433333222222222222223333445566778899::;;<<==>>??????????????????????????>==<<;;;::::::::::::::998877766665566555555544444444444444333222333333333334444444444444555555555555555555555555666666666666666777766666666677777777888888888888888999999:::::::99888888888888888888877777777666666666554433221100//..--,,++**))((''&&%%$$#########""""""!!!!!`````!!`````````!!""""""##$$$##""!!```!!"""!!!!````````````````````!!""""!!!!!``````!!""""!!``!!!!!``!!!!!!!!!!!""""###$##""!!!`€````````!!""##$$%%&&''(())*********+++++++,,--..//00112233445566778899::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""""""""""""!!``!!""##""!!```!!"""##$$$###$$%%&&''(())**++,,--..//001122334455667788899999999999:::::;;;;;;;::99887766554433221100//..--,,++**))))))))(((((((''''''''((('''''''''''''(((((((((((((((((((('''''''&&&&&&&%%%%%$$$$%$$$$$$#########$#################"""""""!!!!!!!!!!"""##$$%%&&''(())**++,,--.--,,++**))((''&&&&&&&&&&&''(())))))))((''&&%%$$%%$$$$$$$%%&&''(()((((((''&&%%$$##""!!!!`````!!""#""!!``!!""""!!!""##""!!!!!!!`!!"""""#####""!!!!!!!!!!!!!!``Ă`````!!""""""""""""""""""""##""######$$%%&&''(())))**++,,,,,,,,,,,,,,------.-........----,,+++++++++++,,,,,,,,,,,,,,,,,-------..//00111100//..--,,++**))((''&&%%%%%&&&&%%$$$$$$$$#$$$$$$%%%%$$$$$$$$$$%%%%%%%%%%%%%&&&&''&&&&&&&%%$$##"""""""##$$%%&&'''&&%%$$$$$$%%&&''''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778888888888888877777777777888776666666677777777777777777777777777788776655443333222222222222222222233445566778899::;;<<==>>?????????????????????????==<<;;;:::::::::9999999887766655555555555444444434444444333322222222233333334333333333444455544444544444445555555556655555566666666666666666666777777777787777777788899999999::99887777777777778887777777766666566655554433221100//..--,,++**))((''&&%%$$###"""""""""""!!!!````!!!!!!!!!`````!!!!!!!!""##$$$##""!!!``!!"""""!!!!!!!!!!!!!!!!!!!!!!""""""!!!!!!!!```!!"""""!!``!!!!``````!!!!!!!!!!!""""##$$$##""!!`€`!!!!""##$$%%&&''(())***++++++++++,,,,,--..//00112233445566778899::;;<<==>>????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$####""""###"""!!`````!!""###""!!`````!!!"""""##$$$$$$%%&&''(())**++,,--..//0011223344556677888888888888999999::::::;;;;::99887766554433221100//..--,,++***)))))))(((((((((((((((((((('''''''''(()((((((((((((())((''&&&&&&&%%%%%%%%%%$$$$$$$$#####################"#""""""""""!!!!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--.--,,++**))((''&&&&&&&&&''(())))((()((''&&%%$$$$$$$$$$$$$%%&&''(((''((''&&%%$$##""!!````!!""#""!!```!!""##""""""#""!!!``````!!"""""####"""!!!!!!!"!!````!!"""""""""""""""""""""""""#""##$$%%&&''(())))**++++++++++++++,,-,,,--------------,,+++++****+++++++++++++++++++,,,,,----..//001100//..--,,++**))((''&&%%$$%%%&&%%$$$$########$$$$$$$$$$$###$$$$$$$$$$$$$%%%%%%%&&&&%%%%&%%$$##"""""""""##$$%%&&'&&%%$$####$$%%&&''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566777777777777777766666666677877666666666666666666667777777777777777777665544332222211111111111111222233445566778899::;;<<==>>????????????????????????=<<;;:::999999999999998877666555544554444444333333333333332221112222222222233333333333334444444444444444444444445555555555555556666555555555666666667777777777777778888889999999887777777777777777777666666665555555554433221100//..--,,++**))((''&&%%$$##"""""""""!!!!!!```!!!!!!!!!!!````````````!!!!!!!!!!!!""##$$$##""!!``!!""""""!!!!!!!!!!!!!!!!!!!!"!!!!"""""!!````````````````!!""""!!!!!```````````!!"""""""""""####$$$$$##""!!````!!""##$$%%&&''(())**+++++++++,,,,,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$############""!!``!!!!!""##$##""!!``````!!````!!!""""!""##$$$$%%&&''(())**++,,--..//0011223344556677777778888888888899999::::::::;::99887766554433221100//..--,,++********)))))))(((((((()))((((((((((((())))))))))))))))((''&&&&&&&%%%%%%%$$$$$####$######"""""""""#"""""""""""""""""!!!!!!!``````````!!!""##$$%%&&''(())**++,,--.--,,++**))(('''''''''''(())))((((((''&&%%$$##$$#######$$%%&&''(''''''&&%%$$##""!!``!!""##""!!!!!""####"""""""!!```!!!!!""#""""""""""""!!`@@@@`!!!!!!!!!!!!!!!!!!!!!""!!""""""##$$%%&&''(((())**++++++++++++++,,,,,,-,--------,,,,++***********+++++++++++++++++,,,,,,,--..//0000//..--,,++**))((''&&%%$$$$$%%%%$$########"######$$$$##########$$$$$$$$$$$$$%%%%&&%%%%%%%$$##""!!!!!!!""##$$%%&&&%%$$######$$%%&&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566777777777777776666666666677766555555556666666666666666666666666667766554433222211111111111111111112233445566778899::;;<<==>>???????????????????????<<;;:::999999999888888877665554444444444433333332333333322221111111112222222322222222233334443333343333333444444444554444445555555555555555555566666666667666666667778888888899887766666666666677766666666555554555444433221100//..--,,++**))((''&&%%$$##"""!!!!!!!!!!!````!!`````````!!!!!```!!!!!!!!!!!!!``````!!""#######""!!```!!!!!!!""""!!!!!!!!!!!!!!!!!!!!!!!!!"!!`Ʉ```!!!!!!!!!!!`````````@`!!"""""""""####$$%%%$$##""!!!!`````!!""##$$%%&&''(())**++,,,,,,,,,,-----..//00112233445566778899::;;<<==>>????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$$$####$$$###""!!``!!!!!""##$$$##""!!!!!!!!!!``````!!!!""""!!!!""##$$%%&&''(())**++,,--..//001122334455666777777777777777888888999999::::::::99887766554433221100//..--,,+++*******))))))))))))))))))))((((((((())*)))))))))))))((''&&%%%%%%%$$$$$$$$$$########"""""""""""""""""""""!"!!!!!!!!!!```````!!""##$$%%&&''(())**++,,---,,++++**))(('''''''''(())))(('''(''&&%%$$#############$$%%&&'''&&''&&&%%$$##""!!``!!""###""!!!""###"""!!!!"!!``!!!!!!""""!!!!!!!!!!!`€``!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!""##$$%%&&''(((())**************++,+++,,,,,,,,,,,,,,++*****))))*******************+++++,,,,--..//00//..--,,++**))((''&&%%$$##$$$%%$$####""""""""###########"""#############$$$$$$$%%%%$$$$%$$##""!!!!!!!!!""##$$%%&%%$$##""""##$$%%&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455666666666666666665555555556676655555555555555555555666666666666666666655443322111110000000000000011112233445566778899::;;<<==>>>>>>>?????????????????<;;::9998888888888888877665554444334433333332222222222222211100011111111111222222222222233333333333333333333333344444444444444455554444444445555555566666666666666677777788888887766666666666666666665555555544444444433221100//..--,,++**))((''&&%%$$##""!!!!!!!!!`````!!``!!!!!!!!!!!!!!!!!!!``!!""###""""""!!!`````````!!!!!!!"!!!!`````````!!!!!!````!!!!!!`Ä`!!!!``````````!!""#######$$$$%%%%%$$##""!!!!!!``!!""##$$%%&&''(())**++,,,,,,,-------..//00112233445566778899::;;<<==>>??????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$$$$$$$$$$$##""!!`````!!""""##$$%$$##""!!!!!!""!!!!!!!!!!""""!!!`!!""##$$%%&&''(())**++,,--..//001122334455566666666777777777778888899999999:::::99887766554433221100//..--,,++++++++*******))))))))***)))))))))))))*********)))))((''&&%%%%%%%$$$$$$$#####""""#""""""!!!!!!!!!"!!!!!!!!!!!!!!!!!``Ǎ`!!""##$$%%&&''(())**++,,-,,+++++***))((((((((((())))((''''''&&%%$$##""##"""""""##$$%%&&'&&&&&&&&%%%$$##""!!``````!!""#####"""""##""""!!!!!!!````!!````!!"!!!!!!!!!!!!````````````````````````!!``!!!!!!""##$$%%&&''''(())**************++++++,+,,,,,,,,++++**)))))))))))*****************+++++++,,--..////..--,,++**))((''&&%%$$#####$$$$##""""""""!""""""####""""""""""#############$$$$%%$$$$$$$##""!!```````!!""##$$%%%$$##""""""##$$%%&&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566666666666666666555555555556665544444444555555555555555555555555555665544332211110000000000000000000112233445566778899::;;<<==>>>>>>>>???????????????;;::9998888888887777777665544433333333333222222212222222111100000000011111112111111111222233322222322222223333333334433333344444444444444444444555555555565555555566677777777887766555555555555666555555554444434443333221100//..--,,++**))((''&&%%$$##""!!!`````````````!!!!!!!""""""!!`````!!"""""""""""!!!!!``````!!!!````````````!!``````!!""#######$$$$%%&&&%%$$##""""!!!!``````!!""##$$%%&&''(())**++,,---------.....//00112233445566778899::;;<<==>>????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%%%$$$$%%%$$$##""!!!!!````!!""""##$$%%%$$##""""""""""!!!!!!""""""!!```!!""##$$%%&&''(())**++,,--..//0011223344555666666666666666777777888888999999::::99887766554433221100//..--,,,+++++++********************)))))))))**+******))))(((''&&%%$$$$$$$##########""""""""!!!!!!!!!!!!!!!!!!!!!`!`````````!!""##$$%%&&''(())**++,,,,++*****)))))((((((((())))((''&&&'&&%%$$##"""""""""""""##$$%%&&&%%&&%%%%%$$$$##""!!``!!!!!!""#######"""##"""!!!````!``!``!!!!```````````````!``!!""##$$%%&&''''(())))))))))))))**+***++++++++++++++**)))))(((()))))))))))))))))))*****++++,,--..//..--,,++**))((''&&%%$$##""###$$##""""!!!!!!!!"""""""""""!!!"""""""""""""#######$$$$####$##""!!``!!""##$$%$$##""!!!!""##$$%%&&&%%$$##""!!!""##$$%%&&''(())**++,,--..//0011223344555555555555555555555444444444556554444444444444444444455555555555555555554433221100000//////////////0000112233445566778899::;;<<=======>>>??????????????;::9988877777777777777665544433332233222222211111111111111000///000000000001111111111111222222222222222222222222333333333333333444433333333344444444555555555555555666666777777766555555555555555555544444444333333333221100//..--,,++**))((''&&%%$$##""!!``@```````!!!!!!""""!!```!!"""!!!!!!!!"!!```!``!!```Nj`!!""##$$$$$$%%%%&&&&&%%$$##""""""!!!!`````````````````ǃ`!!""##$$%%&&''(())**++,,-------.......//00112233445566778899::;;<<==>>??????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%%%%%%%%%%%$$##""!!!!!!!````!!""###$$%%&%%$$##""""""##""""""""""""!!``!!""##$$%%&&''(())**++,,--..//001122334444455555555666666666667777788888888999999:99887766554433221100//..--,,,,,,,,+++++++********+++*************+++++**))(((((''&&%%$$$$$$$#######"""""!!!!"!!!!!!`````````!````````ƀ`!!""##$$%%&&''(())**++,,,++*****))))))))))))))))))((''&&&&&&%%$$##""!!""!!!!!!!""##$$%%&%%%%%%%%$$$$$$$##""!!!!!!!!""##""""#"""""""!!!!```@`````!!!````!!""##$$%%&&&&''(())))))))))))))******+*++++++++****))((((((((((()))))))))))))))))*******++,,--....--,,++**))((''&&%%$$##"""""####""!!!!!!!!`!!!!!!""""!!!!!!!!!!"""""""""""""####$$########""!!``!!""##$$$$$##""!!!!!!""##$$%%&&&%%$$##""!""##$$%%&&''(())**++,,--..//001122334444455555555555555555544444444444555443333333344444444444444444444444444455443322110000///////////////////00112233445566778899::;;<<========>>>>???????????::9988877777777766666665544333222222222221111111011111110000/////////000000010000000001111222111112111111122222222233222222333333333333333333334444444444544444444555666666667766554444444444445554444444433333233322221100//..--,,++**))((''&&%%$$##""!!`@@@@@@``!!!!!!""!!``!!!!!!!!!!!!!!!!```!!!!``Àŀ@@````!!""##$$$$$$%%%%&&'''&&%%$$####""""!!!!!!!```!``!!""##$$%%&&''(())**++,,--......../////00112233445566778899::;;<<==>>????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''&&&&%%%%&&&%%%$$##"""""!!!!!!```````!!""###$$%%&&&%%$$##########""""""###""!!``!!""##$$%%&&''(())**++,,--..//0011223344444455555555555555566666677777788888899999999887766554433221100//..---,,,,,,,++++++++++++++++++++*********+++++**))(((('''&&%%$$#######""""""""""!!!!!!!!`````̀ˀ`!!""##$$%%&&''(())**+++,,++**)))))((((((((()))))))((''&&%%%&%%$$##""!!!!!!!!!!!!!""##$$%%%$$%%$$$$$########""!!""""""""""""""""""""!!!``!```````````!!""##$$%%&&&&''(((((((((((((())*)))**************))(((((''''((((((((((((((((((()))))****++,,--..--,,++**))((''&&%%$$##""!!"""##""!!!!```````!!!!!!!!!!!```!!!!!!!!!!!!!"""""""####""""##""""!!``````!!""######$##""!!````!!""##$$%%&&&%%$$##"""##$$%%&&''(())**++,,--..//0011122334444444444444444444444443333333334454433333333333333333333444444444444444444433221100/////..............////00112233445566778899::;;<<<<<<<===>>>>>>????????:998877766666666666666554433322221122111111100000000000000///...///////////00000000000001111111111111111111111112222222222222223333222222222333333334444444444444445555556666666554444444444444444444333333332222222221100//..--,,++**))((''&&%%$$##""!!`@@@@ǀ````!!!"!!```!!!````````!!!!!``!!!!!````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`!!!!!""##$$%%%%%%&&&&'''''&&%%$$######""""!!!!!!```!``!!""###$$%%&&''(())**++,,--....///////00112233445566778899::;;<<==>>??????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''&&&&&&&&&&&&%%$$##"""""""!!!!!!!!!!!""##$$$%%&&'&&%%$$######$$###########""!!``!!""##$$%%&&''(())**++,,--..//001122333333334444444455555555555666667777777788888899999887766554433221100//..--------,,,,,,,++++++++,,,+++++++++++++++***))(('''''&&%%$$#######"""""""!!!!!````!``Ƀ```!!""##$$%%&&''(())*****++++**)))))((((((((((())*))((''&&%%%%%%$$##""!!``!!```````!!""##$$%$$$$$$$$##########"""""""""""""!!!!"!!!!!!!`````!!""##$$%%&%%&&''(((((((((((((())))))*)********))))(('''''''''''((((((((((((((((()))))))**++,,----,,++**))((''&&%%$$##""!!!!!""""!!```ƀ````!!!!```````!!!!!!!!!!!!!""""##""""""""""""!!!!!!!!"""########""!!``!!""##$$%%&&&%%$$##"##$$%%&&''(())**++,,--..//0011111223343334444444444444444443333333333344433222222223333333333333333333333333334433221100////...................//00112233445566778899::;;<<<<<<<<====>>>>>>?????998877766666666655555554433222111111111110000000/0000000////.........///////0/////////000011100000100000001111111112211111122222222222222222222333333333343333333344455555555665544333333333333444333333332222212221111100//..--,,++**))((''&&%%$$##""!!`@@@@``!!!!!```````!!!``!!!!!!!!!```````````@@@@@@@@@@@@@@@@@@@@@@@@@́`!!!!""##$$%%%%%%&&&&''(((''&&%%$$$$####"""""""!!!````ŀ````!```````!``!!""""##$$%%&&''(())**++,,--..////00000112233445566778899::;;<<==>>????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((''''&&&&'''&&&%%$$#####""""""!!!!!!!""##$$$%%&&'''&&%%$$$$$$$$$$######$$$##""!!!!""##$$%%&&''(())**++,,--..//00011222223333334444444444444445555556666667777778888888999887766554433221100//...-------,,,,,,,,,,,,,,,,,,,,+++++++++++***))((''''&&&%%$$##"""""""!!!!!!!!!!`````!!!!""##$$%%&&'''((())*****++**))((((('''''''''(()))((''&&%%$$$%$$##""!!````!!""##$$$##$$#####"""""""""""!!!!!!!!!!!!!!!!!!!!!```!!""##$$%%%%%&&''''''''''''''(()((())))))))))))))(('''''&&&&'''''''''''''''''''((((())))**++,,--,,++**))((''&&%%$$##""!!``!!!""!!``````````````!!!!!!!""""!!!!""!!!!!!!!!!!!""""""""""##""!!``!!""##$$%%&&&&%%$$###$$%%&&''(())**++,,--..//0001000112233333333333333333333333322222222233433222222222222222222223333333333333333333221100//.....--------------....//00112233445566778899::;;;;;;;<<<======>>>>????98877666555555555555554433222111100110000000//////////////...---.........../////////////000000000000000000000000111111111111111222211111111122222222333333333333333444444555555544333333333333333333322222222111111111100//..--,,++**))((''&&%%$$$$##""!!``@@@@@`!!!!``!!!``!!!``!!!!!!``!!!!!!`@@@@@@@@@@@@@@@@`!!""""##$$%%&&&&&&''''(((((''&&%%$$$$$$####""""""!!!!!``````````!```!!!!!`!!!!````````!``!!!""""##$$%%&&''(())**++,,--..//00000112233445566778899::;;<<==>>??????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((''''''''''''&&%%$$#######"""""""""""##$$%%%&&''(''&&%%$$$$$$%%$$$$$$$$$$$##""!!""##$$%%&&''(())**++,,--..//0000011222222222333333334444444444455555666666667777778888899887766554433221100//........-------,,,,,,,,---,,,,,,,,,,,++**)))((''&&&&&%%$$##"""""""!!!!!!!````ˉ`````!!!!!!""##$$%%&&''''''(()))))****))((((('''''''''''(()((''&&%%$$$$$$$##""!!``!!""##$$########""""""""""!!!!!!!!!!!!!````!````````!!""##$$%$$%%&&''''''''''''''(((((()())))))))((((''&&&&&&&&&&&'''''''''''''''''((((((())**++,,,,++**))((''&&%%$$##""!!```!!!!```````!!!!""!!!!!!!!!!!!!!!!!!!!!"!"""""""##""!!````!!""##$$%%&&''&&%%$$#$$%%&&''(())**++,,--..//0//0000001122322233333333333333333322222222222333221111111122222222222222222222222222233221100//....-------------------..//00112233445566778899::;;;;;;;;<<<<======>>???88776665555555554444444332211100000000000///////.///////....---------......./.........////000/////0///////00000000011000000111111111111111111112222222222322222222333444444445544332222222222223332222222211111011100000//..--,,++**))((''&&%%$$$$$###""!!!`````````@Ɗ``````!!`````````````````!!!!!!`@@@@@@@@@@@@@@@@@@@ƌҘ@@@@@`!!""""##$$%%&&&&&&''''(()))((''&&%%%%$$$$#######"""!!!!!!!!``````````!!````!!!!!!!!!!"!!!!!!!!!!!!!``````!``!!`!!!!""##$$%%&&''(())**++,,--..//001112233445566778899::;;<<==>>????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))((((''''((('''&&%%$$$$$######"""""""##$$%%%&&''(((''&&%%%%%%%%%%$$$$$$%%%$$##""""##$$%%&&''(())**++,,--..///////0011111222222333333333333333444444555555666666777777788889887766554433221100///.......--------------------,,,,,,,++**)))((''&&&&%%%$$##""!!!!!!!``````ȋ`````!!!!!!!!""""##$$%%&&&&&&&'''(()))))**))(('''''&&&&&&&&&''(((''&&%%$$###$$$$##""!!`````!!""#####""##"""""!!!!!!!!!!!```````````Ã`!!""##$$$$$$%%&&&&&&&&&&&&&&''('''((((((((((((((''&&&&&%%%%&&&&&&&&&&&&&&&&&&&'''''(((())**++,,++**))((''&&%%$$##""!!``!!````!!!!````!!````````!!!!!!!!!!!!!!""##""!!!!!!""##$$%%&&''''&&%%$$$%%&&''(())**++,,--...//////0///0011222222222222222222222222111111111223221111111111111111111122222222222222222221100//..-----,,,,,,,,,,,,,,----..//00112233445566778899:::::::;;;<<<<<<====>>??877665554444444444444433221110000//00///////..............---,,,-----------.............////////////////////////0000000000000001111000000000111111112222222222222223333334444444332222222222222222222111111110000000000//..--,,++**))((''&&%%$$########""!!!`!!!!!!```!!````````!`````Ą``!!!!`ɎԔ```!!""####$$%%&&''''''(((()))))((''&&%%%%%%$$$$######"""""!!!!!!!!!!!!!`!!!!!!!!!!!"!!!"""""!""""!!!!!!!!!!!`````````````!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))((((((((((((''&&%%$$$$$$$###########$$%%&&&''(()((''&&%%%%%%&&%%%%%%%%%%%$$##""##$$%%&&''(())**++,,--....///////0011111111122222222333333333334444455555555666666777778889887766554433221100////////.......--------...-------,,++**))(((''&&%%%%%$$##""!!!!!!!`````````````!!!!!!!!!!""""""##$$%%&&&&&&&&&&''((((())))(('''''&&&&&&&&&&&''(''&&%%$$#####$$##""!!``!!```!!""#####""""""""!!!!!!!!!!```Lj`!!""##$$$$##$$%%&&&&&&&&&&&&&&''''''('((((((((''''&&%%%%%%%%%%%&&&&&&&&&&&&&&&&&'''''''(())**++,++**))((''&&%%$$##""!!````!!`````````!`!!!!!!!""##""!!!!""##$$%%&&''((''&&%%$%%&&''(())**++,,--.....//..//////00112111222222222222222222111111111112221100000000111111111111111111111111111221100//..----,,,,,,,,,,,,,,,,,,,--..//00112233445566778899::::::::;;;;<<<<<<==>>?776655544444444433333332211000///////////.......-.......----,,,,,,,,,-------.---------....///...../......./////////00//////000000000000000000001111111111211111111222333333334433221111111111112221111111100000/000/////..--,,++**))((''&&%%$$#####""""""""!!!!!!!!!!!!!!!!!!``````````!``!!````````````!!``!!""####$$%%&&&&''''(((())***))((''&&&&%%%%$$$$$$$###""""""""!!!!!!!!!!!""!!!!""""""""""#"""""""""""""!!!!!!!!!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***))))(((()))(((''&&%%%%%$$$$$$#######$$%%&&&''(()))((''&&&&&&&&&&%%%%%%&&&%%$$####$$%%&&''(())**++,,---..........//00000111111222222222222222333333444444555555666666677778898877665544332211000///////....................---,,++**))(((''&&%%%%$$$##""!!````````````!!!!!!!!!!!!!!!!!""""""""####$$%%&%%%%%%%%&&&''((((())((''&&&&&%%%%%%%%%&&'''&&%%$$##"""####""!!``!!!!!""##"""""!!""!!!!!`````````!!""##$$$####$$%%%%%%%%%%%%%%&&'&&&''''''''''''''&&%%%%%$$$$%%%%%%%%%%%%%%%%%%%&&&&&''''(())**++++**))((''&&%%$$##""!!``!``!`````````!!""##""""""##$$%%&&''((((''&&%%%&&''(())**++,,--..---....../...//001111111111111111111111110000000001121100000000000000000000111111111111111111100//..--,,,,,++++++++++++++,,,,--..//0011223344556677889999999:::;;;;;;<<<<==>>76655444333333333333332211000////..//.......--------------,,,+++,,,,,,,,,,,-------------........................///////////////0000/////////00000000111111111111111222222333333322111111111111111111100000000//////////..--,,++**))((''&&%%$$##"""""""""""""!""""""!!!""!!!!!!!!!``!!!``!``!!!`!!!!!!!!````@`!!``!!""##$$$%%%%%&&&''((((())))**))((''&&&&&&%%%%$$$$$$#####"""""""""""""!"""""""""""#"""#####"####"""""""""""!!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***))))))))))))((''&&%%%%%%%$$$$$$$$$$$%%&&'''(())*))((''&&&&&&''&&&&&&&&&&&%%$$##$$%%&&''(())**++,,--------.......//0000000001111111122222222222333334444444455555566666777888776655444433221100000000///////........///...--,,++**))(('''&&%%$$$$$##""!!``````!!!!!!!!!!!!!!!!!!""""""""""######$$%%&%%%%%%%%%%%&&'''''((((''&&&&&%%%%%%%%%%%&&'&&%%$$##"""""####""!!``!!!!!""##"""""!!!!!!!!```!!""##$$##""##$$%%%%%%%%%%%%%%&&&&&&'&''''''''&&&&%%$$$$$$$$$$$%%%%%%%%%%%%%%%%%&&&&&&&''(())**++++**))((''&&%%$$##""!!````!!```!!`€`!!""##""""##$$%%&&''(())((''&&%&&''(())**++,,--..-----..--......//0010001111111111111111110000000000011100////////0000000000000000000000000001100//..--,,,,+++++++++++++++++++,,--..//00112233445566778899999999::::;;;;;;<<==>665544433333333322222221100///...........-------,-------,,,,+++++++++,,,,,,,-,,,,,,,,,----...-----.-------.........//......////////////////////00000000001000000001112222222233221100000000000011100000000/////.///.....--,,++**))((''&&%%$$##"""""!!!!!!!!!!!!!!!!!!!!""""""!!!!!!!!!``!!``!!!!!!!!!!!!!```!!``!!``!!""##$$$$$$%%%%&&'''''(())))**))((''''&&&&%%%%%%%$$$########"""""""""""##""""##########$#############"""""""""!!``````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++****))))***)))((''&&&&&%%%%%%$$$$$$$%%&&'''(())***))((''''''''''&&&&&&'''&&%%$$$$%%&&''(())**++,,,,,,,----------../////0000001111111111111112222223333334444445555555666677877665544333333221110000000/////////////////..--,,++**))(('''&&%%$$$$####""!!```!!!!!!!!!!!"""""""""""""""""########$$$$%%&%%$$$$$$$$%%%&&'''''((''&&%%%%%$$$$$$$$$%%&&&%%$$##""!!!""####""!!```!!"""""#""!!!!!``!!````!!""##$$##""""##$$$$$$$$$$$$$$%%&%%%&&&&&&&&&&&&&&%%$$$$$####$$$$$$$$$$$$$$$$$$$%%%%%&&&&''(())**++++**))((''&&%%$$##""!!`!!!!!!``!!!!``!!""#######$$%%&&''(())))((''&&&''(())**++,,------,,,------.---..//000000000000000000000000/////////00100////////////////////0000000000000000000//..--,,+++++**************++++,,--..//00112233445566778888888999::::::;;;;<<==65544333222222222222221100///....--..-------,,,,,,,,,,,,,,+++***+++++++++++,,,,,,,,,,,,,------------------------...............////.........////////0000000000000001111112222222110000000000000000000////////..........--,,++**))((''&&%%$$##""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"""""!!"!!!`````````@`!!!!```!!""!""""""""!!!```!!!!``!!!```!!""##$$$$$$$%%%&&'''''(((())))))((''''''&&&&%%%%%%$$$$$#############"###########$###$$$$$#$$$$###########"""""!!!``````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++************))((''&&&&&&&%%%%%%%%%%%&&''((())**+**))((''''''(('''''''''''&&%%$$%%&&''(())**+++++,,,,,,,,,-------../////////00000000111111111112222233333333444444555556667776655443333333322111111110000000//////////..--,,++**))((''&&&%%$$######"""!!```!``!!!!!!""""""""""""""""""##########$$$$$$%%&%%$$$$$$$$$$$%%&&&&&''''&&%%%%%$$$$$$$$$$$%%&%%$$##""!!!!!""####""!!!```!!""""""""!!!!!``````!!""##$$##""!!""##$$$$$$$$$$$$$$%%%%%%&%&&&&&&&&%%%%$$###########$$$$$$$$$$$$$$$$$%%%%%%%&&''(())**+++**))((''&&%%$$##""!!!!!!""!!````!!!"!!``````!!""##$####$$%%&&''(())**))((''&''(())**++,,,,,,--,,,,,--,,------..//0///000000000000000000///////////000//........///////////////////////////00//..--,,++++*******************++,,--..//0011223344556677888888889999::::::;;<<=5544333222222222111111100//...-----------,,,,,,,+,,,,,,,++++*********+++++++,+++++++++,,,,---,,,,,-,,,,,,,---------..------....................//////////0////////00011111111221100////////////000////////.....-...-----,,++**))((''&&%%$$##""!!!!!````````````````````!!!!!!!!!!!!!!!!!!!!!!!!`````!```````````````!!""!!``````!!!"""""""""""""!!!``````````````````!!!``!!!!!``!!""########$$$$%%&&&&&''(((())))))((((''''&&&&&&&%%%$$$$$$$$###########$$####$$$$$$$$$$%$$$$$$$$$$$$$#########""!!!`````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,++++****+++***))(('''''&&&&&&%%%%%%%&&''((())**+++**))((((((((((''''''(((''&&%%%%&&''(())**+++++++++++,,,,,,,,,,--.....//////00000000000000011111122222233333344444445555667665544332222222222211111110000000000000//..--,,++**))((''&&&%%$$####"""""!!``!!!!!"""""""""""#################$$$$$$$$%%%%%%%$$########$$$%%&&&&&''&&%%$$$$$#########$$%%%$$##""!!```!!""####""!!!!!!!!!!!!!"!!````````!!""######""!!!!""##############$$%$$$%%%%%%%%%%%%%%$$#####""""###################$$$$$%%%%&&''(())**+**))((''&&%%$$##""!!!!!!""""!!!``````````!!!""""!!!!!!``````!!""##$$$$$$$%%&&''(())****))(('''(())**+++++,,,,,,,+++,,,,,,-,,,--..////////////////////////.........//0//....................///////////////////..--,,++*****))))))))))))))****++,,--..//001122334455667777777888999999::::;;<<544332221111111111111100//...----,,--,,,,,,,++++++++++++++***)))***********+++++++++++++,,,,,,,,,,,,,,,,,,,,,,,,---------------....---------........///////////////000000111111100///////////////////........----------,,++**))((''&&%%$$##""!!`````````!!!!!!!!```!!!!!!!!!!!!!!!!!`````````!!!!````!!````!!!!!!""""!!!!!!!!!""##"#######""""!!!!!!!!!!!!!!``!!!```!!!!!!```ń````!!""###########$$$%%&&&&&''''(((())))((((((''''&&&&&&%%%%%$$$$$$$$$$$$$#$$$$$$$$$$$%$$$%%%%%$%%%%$$$$$$$$$$$#####"""!!!!``!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,++++++++++++**))(('''''''&&&&&&&&&&&''(()))**++,++**))(((((())(((((((((((''&&%%&&''(())*********+++++++++,,,,,,,--.........////////00000000000111112222222233333344444555666554433222222222222222222111111100000///..--,,++**))((''&&%%%$$##""""""!!!`````!!"!!""""""##################$$$$$$$$$$%%%%%%%%%$$###########$$%%%%%&&&&%%$$$$$###########$$%$$##""!!``!!""####"""!!!!!!!!!!!!!```!!""####""!!``!!""##############$$$$$$%$%%%%%%%%$$$$##"""""""""""#################$$$$$$$%%&&''(())***))((''&&%%$$##""!!``!!!!""""!!!!!```````!``````````!!``````````!!!!!!"""#""!!!!!!!!!!`````````````````!!""##$$%$$$$%%&&''(())******))(('(())****++++++++,,+++++,,++,,,,,,--../...//////////////////...........///..--------...........................//..--,,++****)))))))))))))))))))**++,,--..//00112233445566777777778888999999::;;<44332221111111110000000//..---,,,,,,,,,,,+++++++*+++++++****)))))))))*******+*********++++,,,+++++,+++++++,,,,,,,,,--,,,,,,--------------------........../........///000000001100//............///........-----,---,,,,,++**))((''&&%%$$##""!!`€`````````````!!!!!!!!"!!!!``````!!!!!!!!!!!!!!!!!!!!!!!!!!!""""""!!!!!!"""#########"""!!!!!!!!!!!!!!!!``!!"!!!``````````````!!!!!!`````````````````````!`````````!!!!!""""""""""""####$$%%%%%&&''''(((((((((((((('''''''&&&%%%%%%%%$$$$$$$$$$$%%$$$$%%%%%%%%%%&%%%%%%%%%%%%%$$$$$$$$$##"""!!`````!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,,,,++++,,,+++**))(((((''''''&&&&&&&''(()))**++,,,++**))))))))))(((((()))((''&&&&''(())***************++++++++++,,-----......///////////////00000011111122222233333334444556554433221111111111111122221111111100///..--,,++**))((''&&%%%$$##""""!!!!!`````!!!!!"""""###########$$$$$$$$$$$$$$$$$%%%%%%%%&&%%$$$##""""""""###$$%%%%%&&%%$$#####"""""""""##$$%$$##""!!``!!"""""""""!!`````````!!`@@`!!""""""!!``!!""""""""""""""##$###$$$$$$$$$$$$$$##"""""!!!!"""""""""""""""""""#####$$$$%%&&''(())*))((''&&%%$$##""!!````!!"""""!!!!!!!!!```!!!```!!!!!!!!!!!!!!!!!!"""####""""""!!!!!!!!!!!!!!!!!!!!!!!""##$$%%%%%%%&&''(())********))((())*********+++++++***++++++,+++,,--........................---------../..--------------------...................--,,++**)))))(((((((((((((())))**++,,--..//00112233445566666667778888889999::;;4332211100000000000000//..---,,,,++,,+++++++**************)))((()))))))))))*************++++++++++++++++++++++++,,,,,,,,,,,,,,,----,,,,,,,,,--------...............//////0000000//...................--------,,,,,,,,,,,++**))((''&&%%$$##""!!````!!!!"""""!!!```````````````!!!!!!!!!!!!""""!!!!""!!!!!!!!!!!!!!!""""""""##$$#####"""!!!!!!!!!!!```````!!!""!!!```````````````````!!!!!!!!!!!``````````````````````````!!!!!!!````````!!!!!!!!!!!"""""""""""""""###$$%%%%%&&&&''''((((((((((((((''''''&&&&&%%%%%%%%%%%%%$%%%%%%%%%%%&%%%&&&&&%&&&&%%%%%%%%%%%$$$$$###""!!``Á`!!!!!""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,,,,,,,,,,,,++**))((((((('''''''''''(())***++,,,,,++**))))))**)))))))))))((''&&''(())****)))))))*********+++++++,,---------........///////////0000011111111222222333334445554433221111111111111111122222221100//...--,,++**))((''&&%%$$$##""!!!!!!`````!!!!!!!!""#""######$$$$$$$$$$$$$$$$$$%%%%%%%%%%&&&&%%$$$##"""""""""""##$$$$$%%%%$$#####"""""""""""##$$%$$##""!!``!!"""""""""!!````````````@@@@@`!!"""""!!!``!!""""""""""""""######$#$$$$$$$$####""!!!!!!!!!!!"""""""""""""""""#######$$%%&&''(()))(('''&&%%$$##""!!``!!"""""""!!!!!!!!!!!``!!!!!!!!!!!!!""""""###$##""""""""""!!!!!!!!!!!!!!!!!""##$$%%&%%%%&&''(())*)))))))))))())))))))********++*****++**++++++,,--.---..................-----------...--,,,,,,,,---------------------------..--,,++**))))((((((((((((((((((())**++,,--..//00112233445566666666777788888899::;3322111000000000///////..--,,,+++++++++++*******)*******))))((((((((()))))))*)))))))))****+++*****+*******+++++++++,,++++++,,,,,,,,,,,,,,,,,,,,----------.--------...////////00//..------------...--------,,,,,+,,,+++,,,++**))((''&&%%$$##""!!```!!!!!""""!!!!!!!!!!!!!!!!!!!!!""""""""""""""!!!!""!!!!!!!!!!!!!!!""""###$$#####""!!!``````````ǂ```!!"""!!!`ȅ```!!!!!!!!!!!!!!!!!!`````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""##$$$$$%%&&&&'''''''''''''''(((((('''&&&&&&&&%%%%%%%%%%%&&%%%%&&&&&&&&&&'&&&&&&&&&&&&&%%%%%%%%%$$###""!!````!!!!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...----,,,,---,,,++**)))))(((((('''''''(())***++++++++,++**********))))))*))))((''''(()))))))))))))))))))**********++,,,,,------...............//////000000111111222222233334454433221100000000000000111122221100//...--,,++**))((''&&%%$$$##""!!!!````!!!!!!"""""#####$$$$$$$$$$$%%%%%%%%%%%%%%%%%&&&&&&&&%%$$###""!!!!!!!!"""##$$$$$%%$$##"""""!!!!!!!!!""##$$$$$##""!!!!"""!!!!!!!!!``!!!!!`````!!!!!!!!!!!!```!!!!!!!!!!!!!!!!""#"""##############""!!!!!````!!!!!!!!!!!!!!!!!!!"""""####$$%%&&''(()((''&&&&%%$$##""!!``!!""#"""""""""!!!!!`````````!!!!!"""""###$$$$######"""""""""""""""""""""""##$$%%&&&&&&&''(())))))))))))))))))))))))))))*******)))******+***++,,------------------------,,,,,,,,,--.--,,,,,,,,,,,,,,,,,,,,-------------------,,++**))(((((''''''''''''''(((())**++,,--..//00112233445555555666777777888899::32211000//////////////..--,,,++++**++*******))))))))))))))((('''((((((((((()))))))))))))************************+++++++++++++++,,,,+++++++++,,,,,,,,---------------......///////..-------------------,,,,,,,,++++++++++,,++***))((''&&%%$$##""!!````!!!!!!!!!!!!!!!!!!!!!!!""""""""""""###""!!!!!!!!!```````````!!!""###$$##"""""!!!``!!"!!````!!"""!!!!!!`````````!!!!!!!!!``````````!!````````!!!!!!!!!!!!!!!!"""##$$$$$%%%%&&&&'''''''''''''((((((('''''&&&&&&&&&&&&&%&&&&&&&&&&&'&&&'''''&''''&&&&&&&&&&&%%%%%$$##""!!````!``!!!"""""##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...------------,,++**)))))))((((((((((())**++++++++++++++**********)))))))(())((''(((((())))((((((()))))))))*******++,,,,,,,,,--------.........../////000000001111112222233344433221100000000000000000111221100//..---,,++**))((''&&%%$$###""!!```ˈ``!!!""""""""##$##$$$$$$%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&%%$$###""!!!!!!!!!!!""#####$$$$##"""""!!!!!!!!!!!""##$$$$##"""!!"""!!!!!!!!!!```````@@@@@@``!!!!!!!!``````!!!!!!!!!!!!!!!!!!""""""#"########""""!!```````!!!!!!!!!!!!!!!!!"""""""##$$%%&&''(((''&&&&&&%%$$##""!!```!!""###"""""""""!!```!!!!""####$$$$$$##########"""""""""""""""""##$$%%&&'&&&&''(()))))(((((((((((((((((((())))))))**)))))**))******++,,-,,,------------------,,,,,,,,,,,---,,++++++++,,,,,,,,,,,,,,,,,,,,,,,,,,,--,,++**))(((('''''''''''''''''''(())**++,,--..//00112233445555555566667777778899:2211000/////////.......--,,+++***********)))))))()))))))(((('''''''''((((((()((((((((())))***)))))*)))))))*********++******++++++++++++++++++++,,,,,,,,,,-,,,,,,,,---........//..--,,,,,,,,,,,,---,,,,,,,,+++++*+++***++++**)))))((''&&%%$$##""!!````!!!!!!!!""""""""""""""""""""""""###""!!````!!````!!""##$##"""""!!```!!!``!!"!!!!````Ɍ`````````````````````````!!!!""#####$$%%%%&&&&&&&&&&&&&&&''(((((((''''''''&&&&&&&&&&&''&&&&''''''''''('''''''''''''&&&&&&&&&%%$$##""!!`!!``!!!!!"""""#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///....----...---,,++*****))))))((((((())**+++++******++***+****))))))))))((((((((((('((((((((((((((((((())))))))))**+++++,,,,,,---------------......//////0000001111111222233433221100//////////////0000111100//..---,,++**))((''&&%%$$###""!!```!!!""""""#####$$$$$%%%%%%%%%%%&&&&&&&&&&&&&&&&&''''&&%%$$##"""!!````````!!!""#####$$##""!!!!!`````````!!""######""""""""!!``````````````````@@@`````````````````````````!!"!!!""""""""""""""!!`````````````````!!!!!""""##$$%%&&''(''&&%%%%%%%%$$##""!!!```!!""##########"""!!`````!!""############$$#######################$$%%&&'''''''(((((((((((((((((((((((((((((((()))))))((())))))*)))**++,,,,,,,,,,,,,,,,,,,,,,,,+++++++++,,-,,++++++++++++++++++++,,,,,,,,,,,,,,,,,,,++**))(('''''&&&&&&&&&&&&&&''''(())**++,,--..//0011223344444445556666667777889921100///..............--,,+++****))**)))))))(((((((((((((('''&&&'''''''''''((((((((((((())))))))))))))))))))))))***************++++*********++++++++,,,,,,,,,,,,,,,------.......--,,,,,,,,,,,,,,,,,,,++++++++**********++**)))))((''&&%%$$##""!!!````````!!""!!!""""""""""!!!!!!""""""!!````!!""###""!!!!!``!!!```!!"!!!``ɎÀ@Ώ``!!!""#####$$$$%%%%&&&&&&&&&&&&&''''(((((((('''''''''''''&'''''''''''('''((((('(((('''''''''''&&&&&%%$$##""!!!!!````!!!"""#####$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///............--,,++*******)))))))))))**++++****************))))))(((((((''((''('''''''(((('''''''((((((((()))))))**+++++++++,,,,,,,,-----------.....////////00000011111222333221100/////////////////0001100//..--,,,++**))((''&&%%$$##""""!!!````!!!!"""########$$%$$%%%%%%&&&&&&&&&&&&&&&&&&''''''&&&&%%$$##"""!!```!!"""""####""!!!!!``!!""####""!!!!""!!`Ć@@@`!!!!!!"!""""""""!!!!``!!!!!!!""##$$%%&&'''&&%%%%%%%%%%$$##""!!!!``!!""##$$$######""!!``!!""###################################$$%%&&''(''''(((((((((''''''''''''''''''''(((((((())((((())(())))))**++,+++,,,,,,,,,,,,,,,,,,+++++++++++,,,++********+++++++++++++++++++++++++++,,++**))((''''&&&&&&&&&&&&&&&&&&&''(())**++,,--..//00112233444444445555666666778891100///.........-------,,++***)))))))))))((((((('(((((((''''&&&&&&&&&'''''''('''''''''(((()))((((()((((((()))))))))**))))))********************++++++++++,++++++++,,,--------..--,,++++++++++++,,,++++++++*****)***)))****))(((((''&&%%$$##""!!``````!!!!!!!!!!!!"""!!!!!!!!!""""!!````!!""##""!!!!!```!!!```!!!"!!``@ˀ``!!"""""##$$$$%%%%%%%%%%%%%%%&&'''''''(((((((('''''''''''((''''(((((((((()((((((((((((('''''''''&&%%$$##""!""!!!``!!"""#####$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000////....///...--,,+++++******)))))))**++++***))))))**)))*))))(((((((((('''''''''''&'''''''''''''''''''(((((((((())*****++++++,,,,,,,,,,,,,,,------......//////00000001111223221100//..............////0000//..--,,,++**))((''&&%%$$##"""!!!`````!!!!"""######$$$$$%%%%%&&&&&&&&&&&''''''''''''''''&&&&&%%$$##""!!!``!!"""""##""!!```!``!!"""""""!!!!!!!!`@@@@@`!!```!!!!!!!!!!!!!!!`````!!!!""##$$%%&&'&&%%$$$$$$%%%%$$##"""!!!!!""##$$$$$$$##""!!``!!"""""""""""""##################$$$$$$$%%&&&'''(((((''''''''''''''''''''''''''''''''((((((('''(((((()((())**++++++++++++++++++++++++*********++,++********************+++++++++++++++++++**))((''&&&&&%%%%%%%%%%%%%%&&&&''(())**++,,--..//001122333333344455555566667788100//...--------------,,++***))))(())(((((((''''''''''''''&&&%%%&&&&&&&&&&&'''''''''''''(((((((((((((((((((((((()))))))))))))))****)))))))))********+++++++++++++++,,,,,,-------,,+++++++++++++++++++********))))))))))**))(((((''&&%%$$##""!!`````!!```!!!!!!!!!!``````!!!!!!!``!!""#""!!````````!!``!!!!"!!`@@`!!"""""####$$$$%%%%%%%%%%%%%&&&&''''''''((((((((((((('((((((((((()((()))))())))((((((((((('''''&&%%$$##"""""!!!```````!!""###$$$$$%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000////////////..--,,+++++++***********++++**))))))))))))))))(((((('''''''&&''&&'&&&&&&&''''&&&&&&&'''''''''((((((())*********++++++++,,,,,,,,,,,-----........//////000001112221100//.................///00//..--,,+++**))((''&&%%$$##""!!!!`Ā`!!!""""###$$$$$$$$%%&%%&&&&&&''''''''''''''''''(''&&&%%%%$$##""!!!!``!!!!!!""""!!```````!!""""""!!````!!``````!`!!!!!!!!````````!!""##$$%%&&&%%$$$$$$$$%%%%$$##""""!!""##$$%%%$$$##""!!```!!""""""""""""""""""""""""""#######$$$$%%%%%&&&''''''''''''''&&&&&&&&&&&&&&&&&&&&''''''''(('''''((''(((((())**+***++++++++++++++++++***********+++**))))))))***************************++**))((''&&&&%%%%%%%%%%%%%%%%%%%&&''(())**++,,--..//0011223333333344445555556677800//...---------,,,,,,,++**)))((((((((((('''''''&'''''''&&&&%%%%%%%%%&&&&&&&'&&&&&&&&&''''((('''''('''''''((((((((())(((((())))))))))))))))))))**********+********+++,,,,,,,,--,,++************+++********)))))()))((())))((''''''&&%%$$##""!!`@@@@@ƈ`!```````!!!```!!!!!``!!""#""!!`````!``!!!""!!`@@@`!!!!!""####$$$$$$$$$$$$$$$%%&&&&&&&''''''''((((((((((())(((())))))))))*)))))))))))))(((((((((''&&%%$$##"##""!!!`@@@`!!!!""###$$$$$%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221110000////000///..--,,,,,++++++*************)))(((((())((()((((''''''''''&&&&&&&&&&&%&&&&&&&&&&&&&&&&&&&''''''''''(()))))******+++++++++++++++,,,,,,------......///////00001121100//..--------------....////..--,,+++**))((''&&%%$$##""!!!`````!!""""###$$$$$$%%%%%&&&&&'''''''''''((((((((((((''&&%%%%%$$##""!!`````!!!!!!""!!````!!``!!!!!!!!!``!!````````````!!""##$$%%&%%$$######$$%%%%$$###"""""##$$$$$$$$$$##""!!`````````````!!!!!!!!!!!!!!!""""""""""""""""""###$$$%%%%%%&&&'''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'''''''&&&''''''('''(())************************)))))))))**+**))))))))))))))))))))*******************))((''&&%%%%%$$$$$$$$$$$$$$%%%%&&''(())**++,,--..//00112222222333444444555566770//..---,,,,,,,,,,,,,,++**)))((((''(('''''''&&&&&&&&&&&&&&%%%$$$%%%%%%%%%%%&&&&&&&&&&&&&''''''''''''''''''''''''((((((((((((((())))((((((((())))))))***************++++++,,,,,,,++*******************))))))))(((((((((())((''''''&&%%$$##""!!`@@@@Ɋ`````````!!!``!!""#""!!````````!!""""!!`@@@`!!!!!""""####$$$$$$$$$$$$$%%%%&&&&&&&&''''''((())))()))))))))))*)))*****)****)))))))))))(((((''&&%%$$###""!!`````!!!!""##$$$%%%%%&&%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111000000000//.....--,,,,,,++++++++********))((((((((((((((((''''''&&&&&&&%%&&%%&%%%%%%%&&&&%%%%%%%&&&&&&&&&'''''''(()))))))))********+++++++++++,,,,,--------....../////00011100//..-----------------...//..--,,++***))((''&&%%$$##""!!````!!!!"""####$$$%%%%%%%%&&'&&''''''(((((((((((((((((''&&%%%$$$$##""!!``````!!"!!```!!````!!!!!!!!!``!!``!!""##$$%%%%$$########$$$$$$$$####""##$$$$$$$$$$##""!!!!!!`````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"""""""##$$$$$$$%%%&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%&&&&&&&&''&&&&&''&&''''''(())*)))******************)))))))))))***))(((((((()))))))))))))))))))))))))))**))((''&&%%%%$$$$$$$$$$$$$$$$$$$%%&&''(())**++,,--..//001122222222333344444455667//..---,,,,,,,,,+++++++**))((('''''''''''&&&&&&&%&&&&&&&%%%%$$$$$$$$$%%%%%%%&%%%%%%%%%&&&&'''&&&&&'&&&&&&&'''''''''((''''''(((((((((((((((((((())))))))))*))))))))***++++++++,,++**))))))))))))***))))))))((((('((('''((((''&&&&&&%%$$##""!!``@@@@ƅ`@`````!!""##""!!`````!!""""!!``@@@``````!!""""###############$$%%%%%%%&&&&&&&&'''((()))))**))))**********+*************))))))))((''&&%%$$##""!!````!!""""##$$$%%%%%&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433222111100000//....---,,,++++++***++***)))))))(((''''''(('''(''''&&&&&&&&&&%%%%%%%%%%%$%%%%%%%%%%%%%%%%%%%&&&&&&&&&&''((((())))))***************++++++,,,,,,------.......////00100//..--,,,,,,,,,,,,,,----....--,,++***))((''&&%%$$##""!!``!!!!!""####$$$%%%%%%&&&&&'''''((((((((((())))))))((''&&%%$$$$$##""!!``!!!!``!!!!!!!````````!!!``!!""##$$%%%$$##""""""##$$$$$#####################""!!```````````````````````!!!!!!!!!!!!!!!!!!"""###$$$$$$%%%&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&%%%&&&&&&'&&&''(())))))))))))))))))))))))((((((((())*))(((((((((((((((((((()))))))))))))))))))((''&&%%$$$$$##############$$$$%%&&''(())**++,,--..//00111111122233333344445566/..--,,,++++++++++++++**))(((''''&&''&&&&&&&%%%%%%%%%%%%%%$$$###$$$$$$$$$$$%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&&'''''''''''''''(((('''''''''(((((((()))))))))))))))******+++++++**)))))))))))))))))))((((((((''''''''''((''&&&&&&%%$$##""!!`@@Ɉ``!!""##""!!`````````````!!!""""!!`@@@@@`!!!!""""#############$$$$%%%%%%%%&&&&&&'''(()))***********+***+++++*++++***********)))((''&&%%$$##""!!``!!!""""##$$%%%&&&&&''&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????>>>==<<;;::998877665544332221111100//..-----,,++++++********))))))))((''''''''''''''''&&&&&&%%%%%%%$$%%$$%$$$$$$$%%%%$$$$$$$%%%%%%%%%&&&&&&&''((((((((())))))))***********+++++,,,,,,,,------.....///000//..--,,,,,,,,,,,,,,,,,---..--,,++**)))((''&&%%$$##""!!!!``!!!""""###$$$$%%%&&&&&&&&''(''(((((()))))))))))))((''&&%%$$$#####""!!``!!"!!`````!!!!``@@@@@``!!!``!!""##$$%%%$$##""""""""##########################""!!``````````````!!!!!!!""#######$$$%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$%%%%%%%%&&%%%%%&&%%&&&&&&''(()((())))))))))))))))))((((((((((()))((''''''''((((((((((((((((((((((((((())((''&&%%$$$$###################$$%%&&''(())**++,,--..//0011111111222233333344556..--,,,+++++++++*******))(('''&&&&&&&&&&&%%%%%%%$%%%%%%%$$$$#########$$$$$$$%$$$$$$$$$%%%%&&&%%%%%&%%%%%%%&&&&&&&&&''&&&&&&''''''''''''''''''''(((((((((()(((((((()))********++**))(((((((((((()))(((((((('''''&'''&&&''''&&%%%%%%$$##""!!````Ɔ```!!""###""!!```!```!!!!!!!!!!""""!!`@@@`!!!!"""""""""""""""##$$$$$$$%%%%%%%%&&&'''(())**+****++++++++++,+++++++++++++*******))((''&&%%$$##""!!````!!!""####$$%%%&&&&&'''''(())**++,,--..//00112233445566778899::;;<<==>>??????????>>>>>>?????????????????????????????????????????????????????????????????>>>>>>===<<;;::9988776655443332221100//..----,,,+++******)))**)))((((((('''&&&&&&''&&&'&&&&%%%%%%%%%%$$$$$$$$$$$#$$$$$$$$$$$$$$$$$$$%%%%%%%%%%&&'''''(((((()))))))))))))))******++++++,,,,,,-------....//0//..--,,++++++++++++++,,,,----,,++**)))((''&&%%$$##""!!``!```!!"""""##$$$$%%%&&&&&&'''''(((((((((((((((((((())((''&&%%$$#####"""!!``!!!!!!!!``!!!```````!!""##$$%$$##""!!!!!!""#####"""""""""""""""""""""!!``````!!!"""######$$$%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%$$$%%%%%%&%%%&&''(((((((((((((((((((((((('''''''''(()((''''''''''''''''''''(((((((((((((((((((''&&%%$$#####""""""""""""""####$$%%&&''(())**++,,--..//000000011122222233334455.--,,+++**************))(('''&&&&%%&&%%%%%%%$$$$$$$$$$$$$$###"""###########$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&&&&''''&&&&&&&&&''''''''((((((((((((((())))))*******))(((((((((((((((((((''''''''&&&&&&&&&&''&&%%%%%%$$##""!!`````!``!!""###""!!!````!!!``!!!!!!!!!"""#""!!`@@@````!!!!"""""""""""""####$$$$$$$$%%%%%%&&&''(())**++++++++,+++,,,,,+,,,,+++++++++++***))((''&&%%$$##""!!!``!!""####$$%%&&&'''''(('(())**++,,--..//00112233445566778899::;;<<==>>??????????>>>>>>>>??????????????????????????????????????????????????????????????>>>>>====<<<<;;:::99887766554433221100//..--,,,,,++******))))))))((((((((''&&&&&&&&&&&&&&&&%%%%%%$$$$$$$##$$##$#######$$$$#######$$$$$$$$$%%%%%%%&&'''''''''(((((((()))))))))))*****++++++++,,,,,,-----...///..--,,+++++++++++++++++,,,--,,++**))(((''&&%%$$##""!!```!!"""####$$$%%%%%%%%&&&&'''''''''''''((((((((((((((''&&%%$$###"""""!!``!!!!!!!````!``````!!""##$$$##""!!!!!!!!""""""""""""""""""""""""""!!```!!"""""""###$$$$$$$$$$$$$$####################$$$$$$$$%%$$$$$%%$$%%%%%%&&''('''(((((((((((((((((('''''''''''(((''&&&&&&&&'''''''''''''''''''''''''''((''&&%%$$####"""""""""""""""""""##$$%%&&''(())**++,,--..//00000000111122222233445--,,+++*********)))))))((''&&&%%%%%%%%%%%$$$$$$$#$$$$$$$####"""""""""#######$#########$$$$%%%$$$$$%$$$$$$$%%%%%%%%%&&%%%%%%&&&&&&&&&&&&&&&&&&&&''''''''''(''''''''((())))))))**))((''''''''''''(((''''''''&&&&&%&&&%%%&&&&%%$$$$%$$##""!!``````!!""###""!!!!!`````!!!!``!!""""""""""##""!!`@`!!!!!!!!!!!!!!!""#######$$$$$$$$%%%&&&''(())**+++,,,,,,,,,,-,,,,,,,,,,,,,+++++++**))((''&&%%$$##""!!``!!""##$$$$%%&&&'''''((((())**++,,--..//00112233445566778899::;;<<==>>?????????>>>======>>????????????????????????????????????????????????????????????>>>======<<<;;;:::99887766554433221100//..--,,,,+++***))))))((())((('''''''&&&%%%%%%&&%%%&%%%%$$$$$$$$$$###########"###################$$$$$$$$$$%%&&&&&''''''((((((((((((((())))))******++++++,,,,,,,----../..--,,++**************++++,,,,++**))(((''&&%%$$##""!!``!!""####$$$%%%%%%%%%%%&&&&''''''''''''''''''''''((''&&%%$$##"""""!!!!``!!```````@@@@@@@`!!""##$$##""!!``````!!"""""!!!!!!!!!!!!!!!!!!!!!!!``!!!""""""###$$$$$################################$$$$$$$###$$$$$$%$$$%%&&''''''''''''''''''''''''&&&&&&&&&''(''&&&&&&&&&&&&&&&&&&&&'''''''''''''''''''&&%%$$##"""""!!!!!!!!!!!!!!""""##$$%%&&''(())**++,,--..///////00011111122223344-,,++***))))))))))))))((''&&&%%%%$$%%$$$$$$$##############"""!!!"""""""""""#############$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%&&&&%%%%%%%%%&&&&&&&&'''''''''''''''(((((()))))))(('''''''''''''''''''&&&&&&&&%%%%%%%%%%&&%%$$$$$$$##""!!`````````!!""####"""!!!!!`!!````!!!````!!!"""""""####""!!````!!!!!!!!!!!!!""""########$$$$$$%%%&&''(())**++,,,,,,,,-----,----,,,,,,,,,,,++**))((''&&%%$$##""!!````!!""##$$%%&&'''((((())())**++,,--..//000112233445566778899::;;<<==>>????????>>>========>>??????????????????????????????????????????????????????????>>=====<<<<;;;;::999887766554433221100//..--,,+++++**))))))((((((((''''''''&&%%%%%%%%%%%%%%%%$$$$$$#######""##""#"""""""####"""""""#########$$$$$$$%%&&&&&&&&&''''''''((((((((((()))))********++++++,,,,,---...--,,++*****************+++,,++**))(('''&&%%$$##""!!``!!"""######$$%%$$$$$$%%%%&&&&&&&&&&&&&''''''''''''''&&%%$$##"""!!!!!!``!!`@@@@@@`!!""######""!!``!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``!!!!!!!"""##############""""""""""""""""""""########$$#####$$##$$$$$$%%&&'&&&''''''''''''''''''&&&&&&&&&&&'''&&%%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&&&&&''&&%%$$##""""!!!!!!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..////////000011111122334,,++***)))))))))(((((((''&&%%%$$$$$$$$$$$#######"#######""""!!!!!!!!!"""""""#"""""""""####$$$#####$#######$$$$$$$$$%%$$$$$$%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&'&&&&&&&&'''(((((((())((''&&&&&&&&&&&&'''&&&&&&&&%%%%%$%%%$$$%%%%$$####$$##""!!``!!!``!!""####"""""!!!!!!!!``!````!!""########""!!`````````````!!"""""""########$$$%%%&&''(())**++++,,,,,----------------,,,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(((()))))**++,,--..//00000112233445566778899::;;<<==>>??????>>===<<<<<<==>>????????????????????????????????????????????????????????>>===<<<<<<;;;:::999887766554433221100//..--,,++++***)))(((((('''(('''&&&&&&&%%%$$$$$$%%$$$%$$$$##########"""""""""""!"""""""""""""""""""##########$$%%%%%&&&&&&'''''''''''''''(((((())))))******+++++++,,,,--.--,,++**))))))))))))))****++++**))(('''&&&%%$$##""!!``!!!""""####$$$$$$$$$$$%%%%&&&&&&&&&&&&&&&&&&&&&&''&&%%$$##""!!!!!`````!``@@@`!!"""""##""!!``!!!!!!````````````````````````````!!!!!!"""#####""""""""""""""""""""""""""""""""#######"""######$###$$%%&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%&&'&&%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&%%$$##""!!!!!``````````````!!!!""##$$%%&&''(())**++,,--.......///00000011112233,++**)))((((((((((((((''&&%%%$$$$##$$#######""""""""""""""!!!```!!!!!!!!!!!"""""""""""""########################$$$$$$$$$$$$$$$%%%%$$$$$$$$$%%%%%%%%&&&&&&&&&&&&&&&''''''(((((((''&&&&&&&&&&&&&&&&&&&%%%%%%%%$$$$$$$$$$%%$$##########""!!```````````!!!!``!!""#####"""""!""!!!!`````````!!""###$##""!!``!!!!""""""""######$$$%%&&''(())**+++++,,,,-------..--------,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()))**)**++,,--..//00///00112233445566778899::;;<<==>>????>>===<<<<<<<<==>>??????????????????????????????????????????????????????>>==<<<<<;;;;::::998887766554433221100//..--,,++*****))((((((''''''''&&&&&&&&%%$$$$$$$$$$$$$$$$######"""""""!!""!!"!!!!!!!""""!!!!!!!"""""""""#######$$%%%%%%%%%&&&&&&&&'''''''''''((((())))))))******+++++,,,---,,++**)))))))))))))))))***++**))((''&&&&&&%%$$##""!!``!!!""""""##$$######$$$$%%%%%%%%%%%%%&&&&&&&&&&&&&&%%$$##""!!!````!`@@Ã`!!!"""""""!!``````````````!!!""""""""""""""!!!!!!!!!!!!!!!!!!!!""""""""##"""""##""######$$%%&%%%&&&&&&&&&&&&&&&&&&%%%%%%%%%%%&&&%%$$$$$$$$%%%%%%%%%%%%%%%%%%%%%%%%%%%&&%%$$##""!!!!`````!!""##$$%%&&''(())**++,,--........////00000011223++**)))((((((((('''''''&&%%$$$###########"""""""!"""""""!!!!``````!!!!!!!"!!!!!!!!!""""###"""""#"""""""#########$$######$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%&%%%%%%%%&&&''''''''((''&&%%%%%%%%%%%%&&&%%%%%%%%$$$$$#$$$###$$$$##""""######""!!!!!!!!!!!```!!"!!`````!!""""""###""""""""!!!!````````!!`ƀ`!!""######""!!``!!!!!!!""""""""###$$$%%&&''(())****+++++,,,,,------.....---,,++**))((''&&%%$$##""!!`@@`!!""##$$%%&&''(())****++,,--../////////00112233445566778899::;;<<==>>??>>==<<<;;;;;;<<==>>????????????????????????????????????????????????????>>==<<<;;;;;;:::9998887766554433221100//..--,,++****)))(((''''''&&&''&&&%%%%%%%$$$######$$###$####""""""""""!!!!!!!!!!!`!!!!!!!!!!!!!!!!!!!""""""""""##$$$$$%%%%%%&&&&&&&&&&&&&&&''''''(((((())))))*******++++,,-,,++**))(((((((((((((())))****))((''&&&%%%%%%$$##""!!```!!!!""""###########$$$$%%%%%%%%%%%%%%%%%%%%%%&&%%$$##""!!`````@@@`!!!!!!!""!!``!!!"""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"""""""!!!""""""#"""##$$%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$%%&%%$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%$$##""!!````!!""##$$%%&&''(())**++,,-------...//////00001122+**))(((''''''''''''''&&%%$$$####""##"""""""!!!!!!!!!!!!!!````````!!!!!!!!!!!!!""""""""""""""""""""""""###############$$$$#########$$$$$$$$%%%%%%%%%%%%%%%&&&&&&'''''''&&%%%%%%%%%%%%%%%%%%%$$$$$$$$##########$$##""""""""####""!!!!!!!!!!!!`````!!"""!!!!``!!"""""""""##"##""""!!!!``!!!!!!``!!"""####""!!````!!!!!!!!""""""###$$%%&&''(())*****++++,,,,,,,-----.....--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())***++,,--.....///...//00112233445566778899::;;<<==>>>>==<<<;;;;;;;;<<==>>??????????????????????????????????????????????????>>==<<;;;;;::::99998877766554433221100//..--,,++**)))))((''''''&&&&&&&&%%%%%%%%$$################""""""!!!!!!!``!!``!``````!!!!```````!!!!!!!!!"""""""##$$$$$$$$$%%%%%%%%&&&&&&&&&&&'''''(((((((())))))*****+++,,,++**))((((((((((((((((()))**))((''&&%%%%%%%%%$$##""!!`````!!!!!!""##""""""####$$$$$$$$$$$$$%%%%%%%%%%%%%%$$##""!!``````!!!!!!!```!!!!!!!!!!!!!!````````````````````!!!!!!!!""!!!!!""!!""""""##$$%$$$%%%%%%%%%%%%%%%%%%$$$$$$$$$$$%%%$$########$$$$$$$$$$$$$$$$$$$$$$$$$$$%%$$##""!!`Ɓ`!!""##$$%%&&''(())**++,,---------....//////00112**))((('''''''''&&&&&&&%%$$###"""""""""""!!!!!!!`!!!!!!!```!`````````!!!!"""!!!!!"!!!!!!!"""""""""##""""""####################$$$$$$$$$$%$$$$$$$$%%%&&&&&&&&''&&%%$$$$$$$$$$$$%%%$$$$$$$$#####"###"""####""!!!!""""####"""""""""""!!!```````!!!!!""#""!!!```!!!!!!!!"""""""#""!!!!"!!``````!!!!!!``!!!""""###""!!```````!!!!!!!!"""###$$%%&&''(())))*****+++++,,,,,,----....--,,++**))((''&&%%$$##""!!!````````@@@`!!""##$$%%&&''(())**+++,,--.............//00112233445566778899::;;<<==>>==<<;;;::::::;;<<==>>????????????????????????????????????????????????>>==<<;;;::::::99988877766554433221100//..--,,++**))))((('''&&&&&&%%%&&%%%$$$$$$$###""""""##"""#""""!!!!!!!!!!`````````````!!!!!!!!!!""#####$$$$$$%%%%%%%%%%%%%%%&&&&&&''''''(((((()))))))****++,++**))((''''''''''''''(((())))((''&&%%%$$$$%%%%$$##""!!!!````!!!!"""""""""""####$$$$$$$$$$$$$$$$$$$$$$%%$$##""!!````````!!``!!!!!````````````!!!!!!!```!!!!!!"!!!""##$$$$$$$$$$$$$$$$$$$$$$$$#########$$%$$####################$$$$$$$$$$$$$$$$$$$##""!!`Ņ`!!""##$$%%&&''(())**++,,,,,,,,,---......////0011*))(('''&&&&&&&&&&&&&&%%$$###""""!!""!!!!!!!```````````````!!!!!!!!!!!!!!!!!!!!!!!!"""""""""""""""####"""""""""########$$$$$$$$$$$$$$$%%%%%%&&&&&&&%%$$$$$$$$$$$$$$$$$$$########""""""""""##""!!!!!!!!""####""""""""""""!!````!!!!!!!!!!""###""!!``!!!!!!!!!!""""""!!!!!!"!!!!`!`!!!"""!!``!!!!!"""###""!!!``````!!!!!!"""##$$%%&&''(()))))****+++++++,,,,,---....--,,++**))((''&&%%$$##""!!!!!!````@@@@@@@`!!""##$$%%&&''(())**++,,--------...---..//00112233445566778899::;;<<====<<;;;::::::::;;<<==>>??????????????????????????????????????????????>>==<<;;:::::9999888877666554433221100//..--,,++**))(((((''&&&&&&%%%%%%%%$$$$$$$$##""""""""""""""""!!!!!!````````````!!!!!!!""#########$$$$$$$$%%%%%%%%%%%&&&&&''''''''(((((()))))***+++**))(('''''''''''''''''((())((''&&%%$$$$$$$$$%%$$##""!!!!``````!!""!!!!!!""""#############$$$$$$$$$$$$$$##""!!``!!````````````!!``!!``!!!!!!""##$###$$$$$$$$$$$$$$$$$$###########$$$##""""""""###########################$$$##""!!``!!""##$$%%&&''(())**++,,,,,,,,,,,----......//001))(('''&&&&&&&&&%%%%%%%$$##"""!!!!!!!!!!!`````!!!`````!```````!!!!!!!!!""!!!!!!""""""""""""""""""""##########$########$$$%%%%%%%%&&%%$$############$$$########"""""!"""!!!""""!!````!!!!""#######"""""""""!!````!!!!!!!!!"""""####""!!````````!!!!!!!"!!````!!"!!!!!!!!""""!!````!!!!""###""!!`É````!!!"""##$$%%&&''(((()))))*****++++++,,,,--....--,,++**))((''&&%%$$##"""!!``̓@@À@@`!!""##$$%%&&''(())**++,,---------------..//00112233445566778899::;;<<==<<;;:::999999::;;<<==>>???????????????????>>???????????????????????>>==<<;;:::999999888777666554433221100//..--,,++**))(((('''&&&%%%%%%$$$%%$$$#######"""!!!!!!""!!!"!!!!``````````!!"""""######$$$$$$$$$$$$$$$%%%%%%&&&&&&''''''((((((())))**+**))((''&&&&&&&&&&&&&&''''((((''&&%%$$$####$$$$$%$$##""""!!!!```!!!!!!!!!!!""""######################$$$##""!!``!!``!````!```!!""########################"""""""""##$##""""""""""""""""""""######################""!!``````!!""##$$%%&&''(())**++++++++++++,,,------....//00)((''&&&%%%%%%%%%%%%%%$$##"""!!!!``!!``````````````!!!!!!!!!!!!!!!""""!!!!!!!!!""""""""###############$$$$$$%%%%%%%$$###################""""""""!!!!!!!!!!""!!````!!""#####""!!!!!""""!!!!!!!!""""""""""######""!!``````!!!!!!``!!"""!"!"""""""!!```!!!""###""!!```!!!""##$$%%&&''((((())))*******+++++,,,--...--,,++**))((''&&%%$$##""!!`Ɍ€@@@`!!""##$$%%&&''(())**++,,--,,,,,,---,,,--..//00112233445566778899::;;<<<<;;:::99999999::;;<<==>>??????????????>>>>>>>?????????????????????>>==<<;;::9999988887777665554433221100//..--,,++**))(('''''&&%%%%%%$$$$$$$$########""!!!!!!!!!!!!!!!!``ł`!!"""""""""########$$$$$$$$$$$%%%%%&&&&&&&&''''''((((()))***))((''&&&&&&&&&&&&&&&&&'''((''&&%%$$#########$$$%$$##""""!!!!`!`````!!!``````!!!!"""""""""""""#############$##""!!`@`!!!```!````!!``!``!!""#"""##################"""""""""""###""!!!!!!!!"""""""""""""""""""""""""""#######""!!`````````````````!!!!!!""##$$%%&&''(())**+***+++++++++++,,,,------..//0((''&&&%%%%%%%%%$$$$$$$##""!!!````````!!``````!!!!!!!!!!!!!!!!!!!!""""""""""#""""""""###$$$$$$$$%%$$##""""""""""""###""""""""!!!!!`!!!```!!!!!``!!"""##""!!!!!!!""""!!!!""""""""""""########""!!!!```@@@@@@@@@@@@@````!``!!""""""""!"!!!!!```!!"""##""!!```!!!""##$$%%&&''''((((()))))******++++,,--.--,,++**))((''&&%%$$##""!!`@@@@@`!!""##$$%%&&''(())**++,,,,,,,,,,,,,,,,--..//00112233445566778899::;;<<;;::99988888899::;;<<==>>????????????>>>>>==>>???????????????????>>==<<;;::9998888887776665554433221100//..--,,++**))((''''&&&%%%$$$$$$###$$###"""""""!!!``````!!```!``@`!!!!!""""""###############$$$$$$%%%%%%&&&&&&'''''''(((())*))((''&&%%%%%%%%%%%%%%&&&&''''&&%%$$###""""#####$$%$$####""""!!!!!!!``````````!!!```!!!!""""""""""""""""""""""#####""!!`@`!!!``!!!!!!!!!!```!!""""""""""""""""""""""""""!!!!!!!!!""#""!!!!!!!!!!!!!!!!!!!!""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!""##$$%%&&''(())****************+++,,,,,,----..//(''&&%%%$$$$$$$$$$$$$$##""!!!```````!!!!`````````!!!!!!!!"""""""""""""""######$$$$$$$##"""""""""""""""""""!!!!!!!!``````!!!!``!!"""""!!`````!!""""!!!!!!!!!!!"""""""""####""!!!!!!`````````!!""##"""!!!!!!!!``!!""""#""!!!`````!!""##$$%%&&'''''(((()))))))*****+++,,----,,++**))((''&&%%$$##""!!`ą̓@@@``!!""##$$%%&&''(())**++,,,,++++++,,,+++,,--..//00112233445566778899::;;;;::9998888888899::;;<<==>>??????????>>=======>>?????????????????>>==<<;;::9988888777766665544433221100//..--,,++**))((''&&&&&%%$$$$$$########""""""""!!`````ŀ`!!!!!!!!!!""""""""###########$$$$$%%%%%%%%&&&&&&'''''((()))((''&&%%%%%%%%%%%%%%%%%&&&''&&%%$$##"""""""""###$$%$$####""""!"!!!!!!!!!```!!``!``````!!!!```!!!!!!!!!!!!!"""""""""""""####""!!``!!!``!!!""!!"!!!!!"""""!!!""""""""""""""""""!!!!!!!!!!!"""!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!"""""""""""!!!!!!!!!!!!!!!!!""""""##$$%%&&''(((())))*)))***********++++,,,,,,--../''&&%%%$$$$$$$$$#######""!!`````````!!!!!!!!!!"!!!!!!!!"""########$$##""!!!!!!!!!!!!"""!!!!!!!!``````!``!!!""!!``!!""!!!!!!!!!!!!!!!!""""""""""""""!!`ǁ`!!!!""##""!!!!`!```!``!!!!"""#""!!!!!``ˊ`!!""##$$%%&&&&'''''((((())))))****++,,----,,++**))((''&&%%$$##""!!``ǐ@ŕ΍Ɍ``!!!""##$$%%&&''(())**++,,,,++++++++++++++,,--..//00112233445566778899::;;::998887777778899::;;<<==>>????????>>=====<<==>>???????????????>>==<<;;::9988877777766655544433221100//..--,,++**))((''&&&&%%%$$$######"""##"""!!!!!!!``!!```!!!!!!"""""""""""""""######$$$$$$%%%%%%&&&&&&&''''(()((''&&%%$$$$$$$$$$$$$$%%%%&&&&%%$$##"""!!!!"""""##$$$$$$$####"""""""!!!!!!!!!!!!!!!!!!!!!!!```!!!!!!!!!!!!!!!!!!!!!!"""""##""!!```!!``!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`````````!!"!!````````````!!!!!!!!!!!!!!!!!!!!!!!!!!"""""""""""""""""""""""##$$%%&&'''''((())))))))))))))))***++++++,,,,--..'&&%%$$$##############""!!``````!!!!!!!!!!!!!!!""""""#######""!!!!!!!!!!!!!!!!!!!````````!!!!!``!!!!!```````````!!!!!!!!!""""""""!!``!!!""""""!!!````!``!!!!!!""""""!!!!!`````````````````ņ@@@@`!!""##$$%%&&&&&''''((((((()))))***++,,---,,++**))((''&&%%$$##""!!`Ï`!!!""##$$%%&&''(())****++++++******+++***++,,--..//00112233445566778899::::99888777777778899::;;<<==>>??????>>==<<<<<<<==>>?????????????>>==<<;;::9988777776666555544333221100//..--,,++**))((''&&%%%%%$$######""""""""!!!!!!!!``````````````!!!!!!!!"""""""""""#####$$$$$$$$%%%%%%&&&&&'''(((''&&%%$$$$$$$$$$$$$$$$$%%%&&%%$$##""!!!!!!!!!"""##$$$$$$$####"#"""""""""!!!""!!"!!!!!!"""!!````````````!!!!!!!!!!!!!"""""""!!``!!``!!!!!!!!!!!!!!!!!!!```!!!!!!!!!!!!!!!!!!``!!!`````````````````!!!!!!!!!!!!!!""""""""""""""######$$%%&&&&&'''''(((()((()))))))))))****++++++,,--.&&%%$$$#########"""""""!!``````!````````!!!""""""""##""!!````````````!!!`````!!!```!!!`````!!!!!!!!!!!""!!``!!""""""!!```````````!!!"""!!!""!!!!!````!````````````@@`!!""##$$%%%%&&&&&'''''(((((())))**++,,--,,++**))((''&&%%$$##""!!``!!"""##$$%%&&''(())******++++**************++,,--..//00112233445566778899::9988777666666778899::;;<<==>>????>>==<<<<<;;<<==>>???????????>>==<<;;::9988777666666555444333221100//..--,,++**))((''&&%%%%$$$###""""""!!!""!!!```````!!!!!!!!!!!!!!!""""""######$$$$$$%%%%%%%&&&&''(''&&%%$$##############$$$$%%%%$$##""!!!````!!!!!""###############""""""""""""""""""""""""""!!````````````!!!!!"""!!``!````````````````````````````````````````!```````````!!!!!!""""""###########$$%%%%%&&&&&&'''(((((((((((((((()))******++++,,--&%%$$###""""""""""""""!!```!!!!!!"""""""!!```````````````!!!!!!!!"!!``!!!""!!!!```!!!!!!!!!""!!!!``````!!!`ɍ````````````````!!""##$$%%%%%&&&&'''''''((((()))**++,,-,,++**))((''&&%%$$##""!!```````!!"""##$$%%&&''(())***)))******))))))***)))**++,,--..//00112233445566778899998877766666666778899::;;<<==>>??>>==<<;;;;;;;<<==>>?????????>>==<<;;::9988776666655554444332221100//..--,,++**))((''&&%%$$$$$##""""""!!!!!!!!`````````!!!!!!!!!!!"""""########$$$$$$%%%%%&&&'''&&%%$$#################$$$%%$$##""!!`````!!!""##########"""""""""""""""""""#""""""###""!!``````!!!!!!!!``!```````!!!!"""""""#######$$$$$%%%%%%&&&&&''''('''((((((((((())))******++,,-%%$$###"""""""""!!!!!!!!`΍``!!!!!!!!""!!```````!!!!!!``@@`!!!!!!!!!!`@`!!!```!!!!"""!!!!!!!!!!````!``!``````````!!""##$$$$%%%%%&&&&&''''''(((())**++,,-,,++**))((''&&%%$$##""!!``!```!!!!!!""###$$%%&&''(())***)))))****))))))))))))))**++,,--..//00112233445566778899887766655555566778899::;;<<==>>>>==<<;;;;;::;;<<==>>???????>>==<<;;::9988776665555554443332221100//..--,,++**))((''&&%%$$$$###"""!!!!!!```!!`````````!!!!!!""""""######$$$$$$$%%%%&&'&&%%$$##""""""""""""""####$$$$##""!!```!!"""""""""""""""!!!!!!!!!!!!""""""""""""""!!!`````````!!!!!!``!!`@`!!```!!!!!!"""""""#####$$$$$$%%%%%%&&&''''''''''''''''((())))))****++,,%$$##"""!!!!!!!!!!!!!!``````!!!!!!!````!!!!!!``@`!!``!!````@@@@@@`!````!!!!""!!!!!!"!!`````!!!!``!!```!``!!""##$$$$$%%%%&&&&&&&'''''((())**++,,-,,++**))((''&&%%$$##""!!```Ȁ`!!!````!!!!!!!""###$$%%&&''(()))))))((())))))(((((()))((())**++,,--..//00112233445566778888776665555555566778899::;;<<==>>==<<;;:::::::;;<<==>>?????>>==<<;;::9988776655555444433332211100//..--,,++**))((''&&%%$$#####""!!!!!!```!````!!!!!""""""""######$$$$$%%%&&&%%$$##"""""""""""""""""###$$##""!!``!!""""""""""!!!!!!!!!!!!!!!!!""""""""""""!!!``!!`````!!!`````!!!`````!!!``````!!!!!!!"""""""#####$$$$$$%%%%%&&&&'&&&'''''''''''(((())))))**++,$$##"""!!!!!!!!!``````````!!``````!`!````````@@``!````@@@```!!!""""""""!!``!!!!```!!``!`@`!!""#####$$$$$%%%%%&&&&&&''''(())**++,,-,,++**))((''&&%%$$##""!!!!````````!!!````!!!!!""""""##$$$%%&&''(()))))))((((())))(((((((((((((())**++,,--..//00112233445566778877665554444445566778899::;;<<====<<;;:::::99::;;<<==>>???>>==<<;;::9988776655544444433322211100//..--,,++**))((''&&%%$$####"""!!!`````````!!!!!!""""""#######$$$$%%&%%$$##""!!!!!!!!!!!!!!""""####""!!``!!"!!!!!!!!!!!!!````````````!!!!!!!!!!!!!!`````!!!`````!```!``!!``!!!!!`````!!!!!!!"""""######$$$$$$%%%&&&&&&&&&&&&&&&&'''(((((())))**++$##""!!!````````Ë``````@@@@@@@@@@@@`!!``@@@@``!!""""""""!!``!!"!!!!!```!!!``!!""########$$$$%%%%%%%&&&&&'''(())**++,,-,,++**))((''&&%%$$##""!!!!!`````!!!!!!!!!```!!!!!!"""""""##$$$%%&&''(())((((((('''((((((''''''((('''(())**++,,--..//00112233445566777766555444444445566778899::;;<<==<<;;::9999999::;;<<==>>?>>==<<;;::9988776655444443333222211000//..--,,++**))((''&&%%$$##"""""!!``@``!!!!!!!!""""""#####$$$%%%$$##""!!!!!!!!!!!!!!!!!"""###""!!``!!!!!!!!!!!!`````!!!!!!!!!!!!``!!!!``````!```!!!`@`````````!!!!!!!"""""######$$$$$%%%%&%%%&&&&&&&&&&&''''(((((())**+##""!!!`DŽÃ@@@@@``!!!```@@@@`!!""!!!"!!``!!"!!!!``!!!"!!`````````!!!""""""""#####$$$$$%%%%%%&&&&''(())**++,,-,,++**))((''&&%%$$##""""!!!!!!`````````!````!!!!!"""""######$$%%%&&''((((((((((('''''((((''''''''''''''(())**++,,--..//00112233445566776655444333333445566778899::;;<<<<;;::999998899::;;<<==>>>==<<;;::9988776655444333333222111000//..--,,++**))((''&&%%$$##""""!!!`````!!!!!!"""""""####$$%$$##""!!``````````````!!!!""##""!!``!!!`````````@````````````````````!`````!````````!!!!!""""""######$$$%%%%%%%%%%%%%%%%&&&''''''(((())**#""!!```€@@Ņ@@@@@@@@@Lj`````!!!``!!`@@@`!!"!!!!!!``!!""""!!``!!""!!!`````!!!!!""""""""####$$$$$$$%%%%%&&&''(())**++,,-,,++**))((''&&%%$$##"""""!!!```!!!!!""""""#######$$%%%&&''('''(('''''''&&&''''''&&&&&&'''&&&''(())**++,,--..//00112233445566665544433333333445566778899::;;<<;;::99888888899::;;<<==>==<<;;::998877665544333332222111100///..--,,++**))((''&&%%$$##""!!!!!!`````!!!!!!"""""###$$$##""!!```!!!""##""!!`````!!``@@@@`„````````!!`@```!!!!!""""""#####$$$$%$$$%%%%%%%%%%%&&&&''''''(())*""!!`@@@@@@@@@@ă`````````````````!!!!```!!````@@@@@@@`!!!```!!`č`!!"""""!!``!!"""!!!`````@```!!!!!!!!"""""#####$$$$$$%%%%&&''(())**++,,-,,++**))((''&&%%$$####""!!````````!!!!"""""#####$$$$$$%%&&&''(''''''''''''&&&&&''''&&&&&&&&&&&&&&''(())**++,,--..//00112233445566554433322222233445566778899::;;;;::9988888778899::;;<<===<<;;::998877665544333222222111000///..--,,++**))((''&&%%$$##""!!!!``````!!!!!!!""""##$$##""!!`Â``!!""##""!!``````!``!!!``@@@@```!```!!!!!!""""""###$$$$$$$$$$$$$$$$%%%&&&&&&''''(())""!!`@@@@@@@@@@@@@@@@@```!!!!``!!!!!!```!!"!!!``!!!```@@@@@@@`!!``````!!""#""!!``!!"""!!``@``!!!!!!!!""""#######$$$$$%%%&&''(())**++,,-,,++**))((''&&%%$$###""!!```````!!!!!!!!"""""######$$$$$$$%%&&&''(''&&&''&&&&&&&%%%&&&&&&%%%%%%&&&%%%&&''(())**++,,--..//00112233445555443332222222233445566778899::;;::998877777778899::;;<<=<<;;::998877665544332222211110000//...--,,++**))((''&&%%$$##""!!```````!!!!!"""##$$##""!!````!!""##""!!!!!!!!!`````!`@```!!!!!!"""""####$###$$$$$$$$$$$%%%%&&&&&&''(()""!!`@@@@@@@@@@@@@@@@```````!!!!!!!!!!!!!``!!``@@`!!````!!!!""##""!!``!!""!!```````!!!!!"""""######$$$$%%&&''(())**++,,-,,++**))((''&&%%$$##""!!`````!!!`!!!!!!!!!!""""#####$$$$$%%%%%%%&&&&'''&&&&&&&&&&&&%%%%%&&&&%%%%%%%%%%%%%%&&''(())**++,,--..//00112233445544332221111112233445566778899::::99887777766778899::;;<<<;;::99887766554433222111111000///...--,,++**))((''&&%%$$##""!!`@```!!!!""##$$##""!!!!```!!""""!!!```!!``À`!!````!!!!!!"""################$$$%%%%%%&&&&''((#""!!`````@@@@@@@@@@@@@@@@```!``!!!!``````````@@``!!!``!!!""####""!!```!!"""!!`@``!!!!"""""""#####$$$%%&&''(())**++,,,++**))((''&&%%$$##""!!```€````!!!!!!!!!!!""""""""#####$$$$$$%$$$$$$%%%&&&&'&&%%%&&%%%%%%%$$$%%%%%%$$$$$$%%%$$$%%&&''(())**++,,--..//00112233444433222111111112233445566778899::9988776666666778899::;;<;;::9988776655443322111110000////..---,,++**))((''&&%%$$##""!!`@``!!!""##$$##""!!!!``!!""!!!````!!!!`````!!!!!""""#"""###########$$$$%%%%%%&&''(##""!!!!!!````@@@@@@@@@@@@†@@@`````@@@Ɔ`!!!!```!!""####""!!`!!!"""!!`````!!!!!""""""####$$%%&&''(())**++,++**))((''&&%%$$##""!!`````````````!!!!!!!!"""!""""""""""####$$$$$%%%$$$$$$$$$%%%%&&&%%%%%%%%%%%%$$$$$%%%%$$$$$$$$$$$$$$%%&&''(())**++,,--..//00112233443322111000000112233445566778899998877666665566778899::;;;::9988776655443322111000000///...---,,++**))((''&&%%$$##""!!````````!!""######""!!``!!!!````!!!!!````!!!""""""""""""""""###$$$$$$%%%%&&''$##""!!!!!!!!!``NJ@@ć```!``!!""####""!!!!""""!!`````!!!!!!!"""""###$$%%&&''(())**++++**))((''&&%%$$##""!!``!!!!!`!!!!!!!!!!!"""""""""""########$$$$$%%%%$$$######$$$%%%%&%%$$$%%$$$$$$$###$$$$$$######$$$###$$%%&&''(())**++,,--..//00112233332211100000000112233445566778899887766555555566778899::;::99887766554433221100000////....--,,,,,++**))((''&&%%$$##""!!`````!!!```!!""#####""!!``!!!!``!!`````!!!!"!!!"""""""""""####$$$$$$%%&&'$$##""""""!!!!!!````@@@@```!!""####""!"""#""!!``````````!!``````!!!!!!""""##$$%%&&''(())**++**))((''&&%%$$##""!!``````!!!!!!!!!!!!!!""""""""###"##########$$$$%%%%%$$$#########$$$$%%%$$$$$$$$$$$$#####$$$$##############$$%%&&''(())**++,,--..//001122332211000//////00112233445566778888776655555445566778899:::998877665544332211000//////...---,,,++++++**))((''&&%%$$##""!!`!!!!!!``!!""#"""""!!````````!!!!```!!``!!!!!!!!!!!!!!!!"""######$$$$%%&&%$$##"""""""""!!!!!!```!!""##$##""""##""!!``!!!!!!!!!!!````!!!!!"""##$$%%&&''(())**+**))((''&&%%$$##""!!``!!!!!!"""""!"""""""""""###########$$$$$$$$%%%%%%%$$###""""""###$$$$%$$###$$#######"""######""""""###"""##$$%%&&''(())**++,,--..//0011222211000////////00112233445566778877665544444445566778899:99887766554433221100/////....----,,+++++++++**))((''&&%%$$##""!!!!!!!``!!"""""""!!```!!!!!!!!!!```!!!````!```!!!!!!!!!!!""""######$$%%&%%$$######""""""!!!!!``!!""##$$##"#####""!!```!!!!!!!!!!!!`````!!!!""##$$%%&&''(())****))((''&&%%$$##""!!``!!!!!""""""""""""""########$$$#$$$$$$$$$$%%%%&%%$$###"""""""""####$$$############"""""####""""""""""""""##$$%%&&''(())**++,,--..//0011221100///......//001122334455667777665544444334455667788999887766554433221100///......---,,,+++****+++**))((''&&%%$$$##""!!!````!!"!!!""!!``!!!!!!!!!``!!!!!```````````!!!""""""####$$%%%$$###""""""!!!!!!!!!``!!""##$$$$####$$##""!!``````````!!!"""""!!!!````!!!""##$$%%&&''(())***))((''&&%%$$##""!!``!!"""""#####"###########$$$$$$$$$$$%%%%%%%%&&&%%$$##"""!!!!!!"""####$##"""##"""""""!!!""""""!!!!!!"""!!!""##$$%%&&''(())**++,,--..//00111100///........//0011223344556677665544333333344556677889887766554433221100//.....----,,,,++**********))((''&&%%$$$##"""!!``!!!!!!!!!!```````````!!!!````!!!!""""""##$$%$$##""""""!!!!!!!!!!!!````!!""##$$%$$#$$$$$##""!!!!!!!!!!!!!"""!!!!!!```!!""##$$%%&&''(())**))((''&&%%$$##""!!``!!"""""##############$$$$$$$$%%%$%%%%%%%%%%&&&%%$$##"""!!!!!!!!!""""###""""""""""""!!!!!""""!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//001100//...------..//00112233445566665544333332233445566778887766554433221100//...------,,,+++***))))***))((''&&%%$$###"""!!```!!!```!!!!!```€``!!!```!!!!!!""""##$$$##"""!!!!!!`````````````````````!!""##$$%%%$$$$%%$$##""!!!!!!!!!!""""!!!!````!!""##$$%%&&''(())**))((''&&%%$$##""!!```!!""#####$$$$$#$$$$$$$$$$$%%%%%%%%%%%&&&&&&&&&%%$$##""!!!``````!!!""""#""!!!""!!!!!!!```!!!!!!``````!!!```!!""##$$%%&&''(())**++,,--..//0000//...--------..//001122334455665544332222222334455667787766554433221100//..-----,,,,++++**))))))))))((''&&%%$$###""!!!``!!`````!!!!``!!```@@```!!!!!!""##$##""!!!!!!```!!!`````!!!!!""##$$%%&%%$%%%%$$$##""""""""""""""!!````!!""##$$%%&&''(())***))((''&&%%$$##""!!```!!""#####$$$$$$$$$$$$$$%%%%%%%%&&&%&&&&&&&&&&&%%$$##""!!!```!!!!"""!!!!!!!!!!!!``!!!!`````!!""##$$%%&&''(())**++,,--..//00//..---,,,,,,--..//0011223344555544332222211223344556677766554433221100//..---,,,,,,+++***)))(((()))((''&&%%$$##"""!!!`@@``!````!`````ƒ```!!!!""###""!!!``````!``!!```!!!!!!""##$$%%&&&%%%%%$$$##""""""""""""""!!```!!""##$$%%&&''(())***))((''&&%%$$##""!!```!!!""##$$$$$%%%%%$%%%%%%%%%%%&&&&&&&&&&&'''''&&%%$$##""!!````!!!!"!!```!!``````````!``````!!""##$$%%&&''(())**++,,--..//0//..---,,,,,,,,--..//00112233445544332211111112233445566766554433221100//..--,,,,,++++****))((((((((((''&&%%$$##"""!!`````````!!`````!!""#""!!```````@@`!!!"""""##$$%%&&'&&%%%$$###""""""""""""""!!`@`!!""##$$%%&&''(())****))((''&&%%$$##""!!``!!!!""##$$$$$%%%%%%%%%%%%%%&&&&&&&&'''&'''''''&&%%$$##""!!`ɀ```!!!`````!!"""##$$%%&&''(())**++,,--..///..--,,,++++++,,--..//001122334444332211111001122334455666554433221100//..--,,,++++++***)))(((''''(((''&&%%$$##""!!!``!!`````````!!"""!!`Ƃ@@@`!!""""""##$$%%&&''&&%%$$###""!!!!!""""""""!!````!!""##$$%%&&''(())**+**))((''&&%%$$##""!!`````!!!"""##$$%%%%%&&&&&%&&&&&&&&&&&'''''''''''(''&&%%$$##""!!``!``!!!!""##$$%%&&''(())**++,,--../..--,,,++++++++,,--..//0011223344332211000000011223344556554433221100//..--,,+++++****))))((''''''''''&&%%$$##""!!!``!!!!``````````````!!""!!``!!"""#####$$%%&&''&&%%$$##"""!!!!!!!!!!!!!!!!!``````!!!""##$$%%&&''(())**+++**))((''&&%%$$##""!!```!!!!!""""##$$%%%%%&&&&&&&&&&&&&&''''''''((('(((''&&%%$$##""!!```````!!!!""##$$%%&&''(())**++,,--...--,,+++******++,,--..//0011223333221100000//00112233445554433221100//..--,,+++******)))((('''&&&&'''&&%%$$##""!!`````!!!!!!!!!!!````````!``````!!""#!!`ņ`!!""#####$$$%%%&&&&%%$$##"""!!`````!!!!!!!!!``!```!!!``!!!""##$$%%&&''(())**++,++**))((''&&%%$$##""!!```!!!!!!"""###$$%%&&&&&'''''&'''''''''''((((((((((''&&%%$$##""!!`````!!""##$$%%&&''(())**++,,--.--,,+++********++,,--..//00112233221100///////001122334454433221100//..--,,++*****))))((((''&&&&&&&&&&%%$$##""!!```!!!!!!!!!!!!!!```````!!!````````!!""##`!`Ɍ@@`!!"""###$$$$$$%%&&%%$$##""!!!`````````````!!!!````!!""##$$%%&&''(())**++,,,++**))((''&&%%$$##""!!``````!!!!"""""####$$%%&&&&&''''''''''''''(((((((()))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,---,,++***))))))**++,,--..//001122221100/////..//0011223344433221100//..--,,++***))))))((('''&&&%%%%&&&%%$$##""!!!````````````!!!!!!!!!!!!!!!!!!!!!!!!`‰````!!!!""##$``````````!!""""""##$$#$$$%%%%$$##""!!!``!!!!!!```````!!""##$$%%&&''(())**++,,-,,++**))((''&&%%$$##""!!`````````!```````!!!!!!""""""###$$$%%&&'''''((((('((((((((((())))))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--,,++***))))))))**++,,--..//0011221100//.......//00112233433221100//..--,,++**)))))((((''''&&%%%%%%%%%%$$##""!!!!!```!!!!!!!!!`````!!!`````!!````!!!!!!!!!!!``!```````!!!!""##$$`!``!``!!!!!!"""######$$%%$$##""!!````!!!!!!``!!!!!!""##$$%%&&''(())**++,,---,,++**))((''&&%%$$##""!!!``!!!!!!!!!!!!!!!!!!""""#####$$$$%%&&'''''(((((((((((((())))))))*))((''&&%%$$##""!!````````````!!""##$$%%&&''(())**++,,,,++**)))(((((())**++,,--..//00111100//.....--..//001122333221100//..--,,++**)))(((((('''&&&%%%$$$$%%%$$##""!!``!``````!!!!!!!!!!````!!``````!!!!!!!!``!!!`````````!!!`````````!!!!""""##$$%!!!``!```!!!!!!""##"###$$$$##""!!`````!!!```!!!!!""##$$%%&&''(())**++,,--.--,,++**))((''&&%%$$##""!!!```!!!!!!!"!!!!!!!""""""######$$$%%%&&''((((()))))()))))))))))******))((''&&%%$$##""!!!!`````!!""##$$%%&&''(())**++,,,++**)))(((((((())**++,,--..//001100//..-------..//0011223221100//..--,,++**))(((((''''&&&&%%$$$$$$$$$$##""!!```!!!!!""""""!!````````!!!!!!``!!!!!!!!!!!!!!!!!``!!!!!!!""""##$$%%!"!!``!`````!!!""""""##$$$##""!!````!!````!!"""""##$$%%&&''(())**++,,--...--,,++**))((''&&%%$$##"""!!``!!!""""""""""""""""""####$$$$$%%%%&&''((((())))))))))))))********+**))((''&&%%$$##""!!`dž`!!""##$$%%&&''(())**++,,++**))(((''''''(())**++,,--..//0000//..-----,,--..//00112221100//..--,,++**))(((''''''&&&%%%$$$####$$$##""!!``!!!!!"""""""!!````````!!!````!!""!!!!!!!!!"""!!``!!!!!""""####$$$$$"""!!```!!```!!""!"""##$##""!!``!!!!````!!"""""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!```!!!"""""""#"""""""######$$$$$$%%%&&&''(()))))*****)***********+++++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,++**))(((''''''''(())**++,,--..//00//..--,,,,,,,--..//001121100//..--,,++**))(('''''&&&&%%%%$$##########"""!!``!!"""""#"""!!!``!```````````!!!""""""""""""""""!!``!!"""""####$$$$$$"#""!!`ŀ````!!``!!!!!!""####""!!``!!!!!!`!!""#####$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""!!``!!""##################$$$$%%%%%&&&&''(()))))**************++++++++++**))((''&&%%$$##""!!````````````!!""##$$%%&&''(())**++,,++**))(('''&&&&&&''(())**++,,--..////..--,,,,,++,,--..//0011100//..--,,++**))(('''&&&&&&%%%$$$###""""###""!!!``!!""""""!!!!``````!`````!!!!!""##"""""""""###""!!````````!!"""##""############""!!````````````!``!!!!```!!`!!!""####""!!``!!!!!!!""#####$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!``!!""#####$#######$$$$$$%%%%%%&&&'''(())*****+++++*+++++++++++,,,,,++**))((''&&%%$$##""!!!!!!!!!!``!!!!""##$$%%&&''(())**++,,++**))(('''&&&&&&&&''(())**++,,--..//..--,,+++++++,,--..//00100//..--,,++**))((''&&&&&%%%%$$$$##""""""""""!!!``!!""""!!!```!`@@```!!!!!!!"""################""!!!!!!!!```!!"""""""""""#######$##""!!!!!````````!!!!!`````!!!!!``!!!!``````!!""####""!!```````````!!!"!""##$$$$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!```!!""##$$$$$$$$$$$$$$$$%%%%&&&&&''''(())*****++++++++++++++,,,,,,,,,,++**))((''&&%%$$##""!!!!!!!`````!!!!""##$$%%&&''(())**++,,++**))((''&&&%%%%%%&&''(())**++,,--....--,,+++++**++,,--..//000//..--,,++**))((''&&&%%%%%%$$$###"""!!!!"""!!```!!""!!!!```!```!!!!!"""""##$$#########$$$##""!!!!!!!!!``!!!"""""!!"""""""""$$$##""!!!!!!!!!!!!!!!!!!!!!`!!!!!!!```!!!!``!!""###""!!``````!!!!`!!``!````!!""##$$$$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$%$$$$$$$%%%%%%&&&&&&'''((())**+++++,,,,,+,,,,,,,,,,,-----,,++**))((''&&%%$$##"""""!!``````!!""""##$$%%&&''(())**++,,++**))((''&&&%%%%%%%%&&''(())**++,,--..--,,++*******++,,--..//0//..--,,++**))((''&&%%%%%$$$$####""!!!!!!!!!!`Æ``!!"!!!!!`````````!!""""""###$$$$$$$$$$$$$$$$##""""""""!!!````````!!!!!!!!!!!!!!""""""$%$$##"""""!!!!!!!!"""""!!!!!!!!!!!!!``!!!!``!!""#""!!!!```!`````!!!!!!!!!!!!!!!!```!!""##$$%%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%$$##""!!```!!""##$$%%%%%%%%%%%%%%%&&&&'''''(((())**+++++,,,,,,,,,,,,,,----------,,++**))((''&&%%$$##""""!!````!!!!!!""""##$$%%&&''(())**++,,++**))((''&&%%%$$$$$$%%&&''(())**++,,----,,++*****))**++,,--..///..--,,++**))((''&&%%%$$$$$$###"""!!!````!!!``!!!"!!!`````!!""#####$$%%$$$$$$$$$%%%$$##"""""""""!!!!!``!!!!!!``!!!!!``!!!!!!!!!%%%$$##"""""""""""!!!!!!!""!!````````````````!!!!```!!"""!!````````````!!!!!""""!""!!"!!!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!!``!!""##$$%%%&%%%%%%%&&&&&&''''''((()))**++,,,,,-----,-----------.....--,,++**))((''&&%%$$###""!!```!!!!!!!!""####$$%%&&''(())**++,,++**))((''&&%%%$$$$$$$$%%&&''(())**++,,--,,++**)))))))**++,,--../..--,,++**))((''&&%%$$$$$####""""!!``````!!!!!```!!""##$$$%%%%%%%%%%%%%%%%$$########"""!!!!!!!!!!!`````````!!!!!!%&%%$$#####""""""!!!!!!!!!!!`’`!`!`!`!!!!!!``!``````!!"""!!```!!""""""""""""""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&&&&&&&&&&''''((((())))**++,,,,,--------------..........--,,++**))((''&&%%$$###""!!`````````````````````!!!!!""""""####$$%%&&''(())**++,,++**))((''&&%%$$$######$$%%&&''(())**++,,,,++**)))))(())**++,,--...--,,++**))((''&&%%$$$######"""!!!```!!!!!``!!!""##$$%%&%%%%%%%%%&&&%%$$#########"""""!!""!!`nj``````&&&%%$$#######""!!```````!!`````!!!!!!!!!!""!!``````````!!!!!!``````!!!""""!!`@`!!""####"""""""""!!`````!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'&&&&&&&''''''(((((()))***++,,-----.....-.........../////..--,,++**))((''&&%%$$$##""!!!!!!!!!!!!!!``!!!!!!!!!""""""""##$$$$%%&&''(())**++,,++**))((''&&%%$$$########$$%%&&''(())**++,,++**))((((((())**++,,--.--,,++**))((''&&%%$$#####""""!!!!`````!`!!``````!!""##$$%%&&&&&&&&&&&&&%%$$$$$$$$###""""""""!!`&'&&%%$$$$###""!!````!!!"!"!"!""""""!!```!!!!``!!!!!!!!!!!!!!``````!!!"""""!!```!!""""""""!!"""""""!!!!`@`!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&'''''''''''''(((()))))****++,,-----..............//////////..--,,++**))((''&&%%$$$##""!!!!!!!!!!!!!`````````````!!!!!!!!"""""######$$$$%%&&''(())**++,,++**))((''&&%%$$###""""""##$$%%&&''(())**++++**))(((((''(())**++,,---,,++**))((''&&%%$$###""""""!!!`````!!!!!!!``!!""##$$%%&&&&&&&&'''&&%%$$$$$$$$$#####""#""!!``'''&&%%$$###""!!``!!""""""""""##""!!!!!!!!!``!!!!``````````!!!!!!!!""""""""!!`````!!""""""""!!!!!!!""""!!!!````!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''('''''''(((((())))))***+++,,--...../////.///////////00000//..--,,++**))((''&&%%%$$##"""""""""""""!!`!!!!!!!``!!!!!!"""""""""########$$%%%%&&''(())**++,,++**))((''&&%%$$###""""""""##$$%%&&''(())**++**))(('''''''(())**++,,-,,++**))((''&&%%$$##"""""!!!!````!!!!!!!``!!""##$$%%&&''''''''''&&%%%%%%%%$$$########""!!````!```''&&%%$$##"""!!``!!"""#"#"######""!!!"""!!`````!!!!``!!!!!!"""!!!!"""!!```!!!!!!!!!!!!!!!``!!!!!!!""""!!````!!""##$$%%&&''(())**++,,--..//00112221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''((((((((((((())))*****++++,,--.....//////////////0000000000//..--,,++**))((''&&%%%$$##"""""""""""""!!!!!!!!!!!!!!!!""""""""#####$$$$$$%%%%&&''(())**++,,++**))((''&&%%$$##"""!!!!!!""##$$%%&&''(())****))(('''''&&''(())**++,,,++**))((''&&%%$$##"""!!!!!!````!!!""""!!``!!""##$$%%&&'''''(((''&&%%%%%%%%%$$$$$##$##""!!!!!!!!!```````'&&%%$$##"""!!```!!""#########$$##""""""""!!``!!!!!!!``!!""""""!!!!!!"""!!``````````!!!!!!!!!`````!!!!""""!!````!!!""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%$$##""!!```!!"""##$$%%&&''(()((((((())))))******+++,,,--../////00000/000000000001111100//..--,,++**))((''&&&%%$$#############""!"""""""!!""""""#########$$$$$$$$%%&&&&''(())**++,,++**))((''&&%%$$##"""!!!!!!!!""##$$%%&&''(())**))((''&&&&&&&''(())**++,++**))((''&&%%$$##""!!!!!````!!!!"""""!!``!!""##$$%%&&''(((((((''&&&&&&&&%%%$$$$$$$$##""!!!!"!!!!!``!!!!&&%%$$##""!!!``!!""###$#$#$$$$$$##"""###""!!!!!!!!!``!!"""""!!````!!"!!`````````!````!!!!!"!!!``````````!!""##$$%%&&''(())**++,,--..//00112233221100//..--,,++**))((''&&%%$$##""!!!```!!"""##$$%%&&''(()))))))))))))****+++++,,,,--../////00000000000000111111111100//..--,,++**))((''&&&%%$$#############""""""""""""""""########$$$$$%%%%%%&&&&''(())**++,,++**))((''&&%%$$##""!!!``````!!""##$$%%&&''(())))((''&&&&&%%&&''(())**+++**))((''&&%%$$##""!!!``````!!!"""#""!!``!!""##$$%%&&''((()))((''&&&&&&&&&%%%%%$$%$$##"""""""""!!!``!!!!!&%%$$##""!!!``````!!""##$$$$$$$$$%%$$########""!!""""!!```!!""#""!!``!!!!`````!!!!!"!!!!!``!!``!!``!!""##$$%%&&''(())**++,,--..//001122333221100//..--,,++**))((''&&%%$$##""!!``!!!""###$$%%&&''(())*)))))))******++++++,,,---..//0000011111011111111111222221100//..--,,++**))(('''&&%%$$$$$$$$$$$$$##"#######""######$$$$$$$$$%%%%%%%%&&''''(())**++,,++**))((''&&%%$$##""!!!``!!""##$$%%&&''(())((''&&%%%%%%%&&''(())**+**))((''&&%%$$##""!!```!!!!""""###""!!`@@Â`!!""##$$%%&&''(())))))((''''''''&&&%%%%%%%%$$##""""#"""""!!!!""""%%$$##""!!````!!!!!!""##$$$%$%$%%%%%%$$###$$$##"""""""!!``!!!""#""!!``!!!`ŀ````!!""!!!!```!!!!``!!```!!""##$$%%&&''(())**++,,--..//00112233433221100//..--,,++**))((''&&%%$$##""!!``!!!""###$$%%&&''(())*************++++,,,,,----..//000001111111111111122222222221100//..--,,++**))(('''&&%%$$$$$$$$$$$$$################$$$$$$$$%%%%%&&&&&&''''(())**++,,++**))((''&&%%$$##""!!````!!""##$$%%&&''((((''&&%%%%%$$%%&&''(())***))((''&&%%$$##""!!```!!!!"""#####""!!`@@`````````````!!""##$$%%&&''(()))***))(('''''''''&&&&&%%%%%$$#########"""!!"""""%$$##""!!```!!!!!!!""##$$%%%%%%%%%&&%%$$$$$$$$##""###""!!``!!!""#""!!``!!!``!!!"""!!!!!""!!````!!`````!!""##$$%%&&''(())**++,,--..//0011223344433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**+*******++++++,,,,,,---...//00111112222212222222222233333221100//..--,,++**))(((''&&%%%%%%%%%%%%%$$#$$$$$$$##$$$$$$%%%%%%%%%&&&&&&&&''(((())**++,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((((''&&%%$$$$$$$%%&&''(())*))((''&&%%$$##""!!``!!"""####$##""!!`@@`!!!!!!!!!!!````!!""##$$%%&&''(())******))(((((((('''&&&%%$$%%%$$####$#####""""####%$$##""!!``!!!""""""##$$%%%&%&%&&&&&&%%$$$%%%$$#######""!!``````!!"""##""!!``!!!``!!!"""!!!""""!!!!```````!``!!""##$$%%&&''(())**++,,--..//001122334454433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++++++++++++,,,,-----....//0011111222222222222223333333333221100//..--,,++**))(((''&&%%%%%%%%%%%%%$$$$$$$$$$$$$$$$%%%%%%%%&&&&&''''''(((())**++,,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((('''&&%%$$$$$##$$%%&&''(()))((''&&%%$$##""!!``!!"""###$$$##""!!`@@````!!!!!!!!!!!!!!!`!!""##$$%%&&''(())***+++**))((((((((''&&%%$$$$%$%$$$$$$$$$###""#####$$##""!!``!!"""""""##$$%%&&&&&&&&&''&&%%%%%%%%$$##$$$##""!!`!!!!!!"""###""!!``!!!!```!!""""""""""!!!!!!!!!`````````!!""##$$%%&&''(())**++,,--..//001122334454433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++++++++,,,,,,------...///001122222333332333333333334444433221100//..--,,++**)))((''&&&&&&&&&&&&&%%$%%%%%%%$$%%%%%%&&&&&&&&&''''''''(())))**++,,-,,++**))((''&&%%$$##""!!``````!!""##$$%%&&''((('''&&%%$$#######$$%%&&''(())((''&&%%$$##""!!``!!""###$$$$$$##""!!`@@``!!!!!"""""""""""!!!!!""##$$%%&&''(())**++++++**))))))((''&&%%$$##$$$$%$$$$%$$$$$####$$$$$$##""!!````!!"""######$$%%&&&'&'&''''''&&%%%&&&%%$$$$$$$##""!!!!!!!""###$##""!!``!!"!!``!!!!!!!"!!""""!!!!!!!!!!!```````!!""##$$%%&&''(())**++,,--..//001122334454433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,,,,,,,,,,----.....////00112222233333333333333444444444433221100//..--,,++**)))((''&&&&&&&&&&&&&%%%%%%%%%%%%%%%%&&&&&&&&'''''(((((())))**++,,---,,++**))((''&&%%$$##""!!!!``!!""##$$%%&&''((''&&&%%$$#####""##$$%%&&''(()((''&&%%$$##""!!``!!""##$$$$####""!!````````````@``````!!!!!!"""""""""""""""!""##$$%%&&''(())**+++,,,++**))))((''&&%%$$####$#$$%%%%%%%%$$$##$$$$$$$##""!!```!!!!""#######$$%%&&'''''''''((''&&&&&&&&%%$$%%%$$##""!""""""###$$$##""!!````!!"""!!``!!!!!!!!!!!"""""""""!!!!!!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,,,,,,,------......///00011223333344444344444444444555554433221100//..--,,++***))(('''''''''''''&&%&&&&&&&%%&&&&&&'''''''''(((((((())****++,,--.--,,++**))((''&&%%$$##""!!!``!!""##$$%%&&''(''&&&%%$$##"""""""##$$%%&&''(()((''&&%%$$##""!!```!!""###$$######""!!```!!!!!!!!!!!```````````!!!!!!!!"""""###########"""""##$$%%&&''(())**++,,,,,,++**))((''&&%%$$##""####$$%%%&%%%%%$$$$%%%%$####""!!```!!!!!""###$$$$$$%%&&'''('('((((((''&&&'''&&%%%%%%%$$##"""""""##$$$%$$##""!!!`!!!""!!!!`````````!``!!"""""""""""""!!!!!!```!!""##$$%%&&''(())**++,,--..//001122334445554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,----------..../////00001122333334444444444444455555555554433221100//..--,,++***))(('''''''''''''&&&&&&&&&&&&&&&&''''''''((((())))))****++,,--...--,,++**))((''&&%%$$##"""!!```!!""##$$%%&&''''&&%%%$$##"""""!!""##$$%%&&''(((''&&%%$$##""!!``!!""""######"""#""!!```!!!!!!!!!!!!!!``!!!``!```!!!!!!!!!""""""###############"##$$%%&&''(())**++,,,-,,++**))((''&&%%$$##""""#"##$$%%&&&&%%%$$%%%%%##""""""!!!``!!""""##$$$$$$$%%&&''((((((((())((''''''''&&%%&&&%%$$##"######$$$%%%$$##""!!!!!""!!!!````!!"""!!!"""""""""""!!!````!!""##$$%%&&''(())**++,,--..//00112233344445554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,-------......//////0001112233444445555545555555555566666554433221100//..--,,+++**))(((((((((((((''&'''''''&&''''''((((((((())))))))**++++,,--../..--,,++**))((''&&%%$$##"""!!!`!!""##$$%%&&''''&&%%%$$##""!!!!!!!""##$$%%&&''(''&&%%$$##""!!``!!!"""""##"""""""!!``!!!""""""""""!!``!!!!!!``!!!!!""""""""#####$$$$$$$$$$$#####$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!""""##$$%%&&&&&%%%%&&&&#""""""!!!!`@`!!""""##$$$%%%%%%&&''((()()())))))(('''(((''&&&&&&&%%$$#######$$%%%&%%$$##"""!"""!!````!!"!!!!!""###""""""!!!!!!!!""##$$%%&&''(())**++,,--..//001122223333445554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--.........////000001111223344444555555555555556666666666554433221100//..--,,+++**))(((((((((((((''''''''''''''''(((((((()))))******++++,,--..///..--,,++**))((''&&%%$$###""!!!!""##$$%%&&''''&&%%$$$##""!!!!!``!!""##$$%%&&''''&&%%$$##""!!``!!!!!!""""""!!!""!!``!!""""""""""""!!`À``!!!!!``````!!!"""""""""######$$$$$$$$$$$$$$$#$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!!!"!""##$$%%&&&&&%%&&&&&""!!!!!!!!!!````!!""####$$%%%%%%%&&''(()))))))))**))((((((((''&&'''&&%%$$#$$$$$$%%%&&&%%$$##"""""!!``!!!!```!!""#######"""!!```!!""##$$%%&&''(())**++,,--..//001122223333445554433221100//..--,,++**))((''&&%%$$##""!!!``!!""##$$%%&&''(())**++,,--.....//////000000111222334455555666665666666666667777766554433221100//..--,,,++**)))))))))))))(('(((((((''(((((()))))))))********++,,,,--..//0//..--,,++**))((''&&%%$$###"""!""##$$%%&&&&&&&&%%$$$##""!!`````!!""##$$%%&&''''&&%%$$##""!!````!!!!!""!!!!!!!!!```!!"""########""!!`@``!!!`````!!!!"""""########$$$$$%%%%%%%%%%%$$$$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!``!!!!""##$$%%&&'&&&&''''"!!!!!!``````@`!!""####$$%%%&&&&&&''(()))*)*)******))((()))(('''''''&&%%$$$$$$$%%&&&&%%$$##""""""!!```!!!!``!!""######""!!``!!""##$$%%&&''(())**++,,--..//001111222233445554433221100//..--,,++**))((''&&%%$$##""!!!``````!!""##$$%%&&''(())**++,,--..////////000011111222233445555566666666666666777777777766554433221100//..--,,,++**)))))))))))))(((((((((((((((())))))))*****++++++,,,,--..//000//..--,,++**))((''&&%%$$$##""""##$$%%&&&&&&&&%%$$###""!!``!!""##$$%%&&''''&&%%$$##""!!````!!!!!!```!!!``!!!""###########""!!``!!!!````!!!!"""#########$$$$$$%%%%%%%%%%%%%%%$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!``!`!!""##$$%%&&'&&'''''!!`````@@@`!!""##$$$$%%&&&&&&&''(())*********++**))))))))((''(((''&&%%$%%%%%%&&&&%%$$##"""""#""!!```!``!!!``!!""##$##""!!``!!""##$$%%&&''(())**++,,--..//0011111222233445554433221100//..--,,++**))((''&&%%$$##"""!!````!!!!`````!!""##$$%%&&''(())**++,,--..////00000011111122233344556666677777677777777777888887766554433221100//..---,,++*************))()))))))(())))))*********++++++++,,----..//00100//..--,,++**))((''&&%%$$$###"##$$%%&&%%%%%%%%$$####""!!``!!""##$$%%&&''''&&%%$$##""!!```!!```````!!!""###$$$$$$$##""!!`````!!!!````!!!!""""#####$$$$$$$$%%%%%&&&&&&&&&&&%%%%%&&''(())**++,,----,,++**))((''&&%%$$##""!!`````!!""##$$%%&&'''((((!`€``@`!!""##$$$%%&&&''''''(())*******++++++**)))***))(((((((''&&%%%%%%%&&&&%%$$##""!!!""#""!!!!!``!!!``!!""####""!!!``!!""##$$%%&&''(())**++,,--..//0000011112233444454433221100//..--,,++**))((''&&%%$$##"""!!!!!!!!!!!!!`````!!""##$$%%&&''(())**++,,--..//000000011112222233334455666667777777777777788888888887766554433221100//..---,,++*************))))))))))))))))********+++++,,,,,,----..//0011100//..--,,++**))((''&&%%%$$####$$%%&&%%%%%%%%$$##"#""!!```!!""##$$%%&&''((''&&%%$$##""!!```@@@@@@@@``!!!"""##$$$$$$$$$$##""!!``!!!!!!``````````````!!!!!!""""###$$$$$$$$$%%%%%%&&&&&&&&&&&&&&&%&&''(())**++,,--..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&'''(((((!``!``@@@@```````!!""##$$%%%&&'''''''(()))))******++++++********))(()))((''&&%&&&&&&&&%%$$##""!!!!!""#""!!!!!``!!!``!!""####""!!!``!!"""##$$%%&&''(())**++,,--..//0000011112233444454433221100//..--,,++**))((''&&%%$$###""!!!!""""!!!!!!``!!""##$$%%&&''(())**++,,--..//0001111112222223334445566777778888878888888888899999887766554433221100//...--,,+++++++++++++**)*******))******+++++++++,,,,,,,,--....//0011100//..--,,++**))((''''&&%%%$$$#$$%%&&%%$$$$$$$$##""""!!```!!""##$$%%&&''((''&&%%$$##""!!```@@@@@@@@@@`!!!!"""##$$$%%%%%%%$$##""!!!!!!!!````!!!!!!!!!!``!!!!!""""####$$$$$%%%%%%%%&&&&&'''''''''''&&&&&''(())**++,,--....--,,++**))((''&&%%$$##""!!`!!!""##$$%%&&''((())))!``!!``@@````!!!!!!`````!!""##$$$%%&&''((((((((())))))))****++++***+++**)))))))((''&&&&&&&&&%%$$##""!!```!!""#""""!!``!!!!````!!""####""!!```!!!""##$$%%&&''(())**++,,--../////0000112233334454433221100//..--,,++**))((''&&%%$$###"""""""""""""!!!``!!""##$$%%&&''(())**++,,--..//00111112222333334444556677777888888888888889999999999887766554433221100//...--,,+++++++++++++****************++++++++,,,,,------....//0011100//..--,,++**))((''&&''&&&%%$$$$$$%%%%$$$$$$$$##""!""!!````!!""##$$%%&&''(((''&&%%$$##""!!```@@@@@@@@@@@@@``!!!"""###$$%%%%%%%%%%$$##""!!!!!```````!!!!!!!!!!!!!``!!!""""""####$$$%%%%%%%%%&&&&&&'''''''''''''''&''(())**++,,--..//..--,,++**))((''&&%%$$##""!!!!""##$$%%&&''((()))))!!```!!!!`@@`!!!!!!!!!!!!``````````````!!""####$$%%&&''('''''((((())))))****++++++++++**))***))((''&''''&&%%$$##""!!``!!""#"""!!```!!"!!!!!!""####""!!``!!!""##$$%%&&''(())**++,,--../////0000112233334454433221100//..--,,++**))((''&&%%$$$##""""####""""""!!```!!""##$$%%&&''(())**++,,--..//001122222233333344455566778888899999899999999999:::::99887766554433221100///..--,,,,,,,,,,,,,++*+++++++**++++++,,,,,,,,,--------..////0011100//..--,,++**))((''&&&&'&&%%$%$$$$$$%%$$########""!!!!!!!`!``!!""##$$%%&&''((((''&&%%$$##""!!````````````@@@@@@@@@@@@@@```!!!!""##$$%%%%%%%%%$$$##""!!!!`````!!``!!!!!"""""""""!!```!!"""""####$$$$%%%%%&&&&&&&&'''''((((((((((('''''(())**++,,--..////..--,,++**))((''&&%%$$##""!"""##$$%%&&''((())****"!!!````````!!"!!!````````````@@````````````!!!!!`!!"""!!!``````!!!!!!!!!!!!```!!"""####$$%%&&'''''''''(((((((())))**++++++,,++*******))(('''''&&%%$$##""!!``!!"""""!!``!!""!!!!""#####""!!```!!""##$$%%&&''(())**++,,--.....////00112222334454433221100//..--,,++**))((''&&%%$$$#############"""!!!```````````!!""##$$%%&&''(())**++,,--..//001122222333344444555566778888899999999999999::::::::::99887766554433221100///..--,,,,,,,,,,,,,++++++++++++++++,,,,,,,,-----......////0011100//..--,,++**))((''&&%%&&&%%$$$$$###$$$$########""!!`!!!!!!!```!!""##$$%%&&''(()((''&&%%$$##""!!``!!!!``````!!!!!!````````````@@@@@@`!`!!""##$$%%%%%%%$$$##""!!!``ˁ`````!```!!!!!```!!!"""""""""""""!!!``!!"""######$$$$%%%&&&&&&&&&''''''((((((((((((((('(())**++,,--..//00//..--,,++**))((''&&%%$$##""""##$$%%&&'''''(())***""!!!!!!!``!!!!""""!!!!!!!!!!!!!`@@@```!!!!!!!!!!!!!"!!``!!""""!!!!!!!!!!!!!!!!!!!!!```````!!""""""##$$%%&&'&&&&&'''''(((((())))***+++++++++**+++**))(('(''&&%%$$##""!!```!!"""""!!``!!""""""####""""!!``!!""##$$%%&&''(())**++,,--.....////00112222334454433221100//..--,,++**))((''&&%%%$$####$$$$######""!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//001122333333444444555666778899999:::::9:::::::::::;;;;;::998877665544332211000//..-------------,,+,,,,,,,++,,,,,,---------........//000011100//..--,,++**))((''&&%%%%&%%$$#$######$$##""""""""!!`````!!``!!""##$$%%&&''(())((''&&%%$$##""!!``!!!!!!!!!!!!!!!!!!!!!!!``````````!!""##$$%$$$$$$###""!!```!!!!`!!!!!""!!!!!"""""#########""!!!!!""#####$$$$%%%%&&&&&''''''''((((()))))))))))((((())**++,,--..//0000//..--,,++**))((''&&%%$$##"###$$%%&&'''''''(())**#"""!!!!!!!!!!""#"""!!!!!!!!!!!`@@`!!!!!!!!!!!!!!!"!!``!!"""""!!!!!!""""""""""""!!!!!!!!```!!"!!""""##$$%%&&&&&&&&&''''''''(((())******+++++++++++**))(((''&&%%$$##""!!``!!!"""!!!!``!!!!""""##"""!!!``!!""##$$%%&&''(())**++,,-----....//00111122334454433221100//..--,,++**))((''&&%%%$$$$$$$$$$$$$###"""!!!!!!!!!!!""##$$%%&&''(())**++,,--..//001122333334444555556666778899999::::::::::::::;;;;;;;;;;::998877665544332211000//..-------------,,,,,,,,,,,,,,,,--------.....//////000011100//..--,,++**))((''&&%%$$%%%$$#####"""####"""""""""!!``!!`!!""##$$%%&&''(()))((''&&%%$$##""!!``!!""!!!!!!"""!!!!!`!!!`Ʌć`!!!!!``@@@`!!""##$$$$$$$###""!!``!!```!!"""""!!!"""#############"""!!""###$$$$$$%%%%&&&'''''''''(((((()))))))))))))))())**++,,--..//001100//..--,,++**))((''&&%%$$####$$%%&&''''&&&''(())*##"""""""!!""""####""""""""""!!`@@@@``!!!!""""""""""""""!!``!!""###"""""""""""""""""""""!!!!!!!!```!!!!!!!!""##$$%%&%%%%%&&&&&''''''(((()))*******+++++++++**))((''&&%%$$##""!!``!!"""!!!!``!!!!!"""""!!!!!``!!""##$$$%%&&''(())**++,,-----....//00111122334454433221100//..--,,++**))((''&&&%%$$$$%%%%$$$$$$##""""""""""""""##$$%%&&''(())**++,,--..//001122334444445555556667778899:::::;;;;;:;;;;;;;;;;;<<<<<;;::998877665544332211100//.............--,-------,,------.........////////001111100//..--,,++**))((''&&%%$$$$%$$##"#""""""##""!!!!!!!!!``!!!!""##$$%%&&''(())))((''&&%%$$##""!!``!!"""""""""""!!`````````````````````````!!!!``ύā``!!""##$$$######"""!!!`````!!""#"""""#####$$$$$$$$$##"""""##$$$$$%%%%&&&&'''''(((((((()))))***********)))))**++,,--..//00111100//..--,,++**))((''&&%%$$#$$$%%&&''''&&&&&''(())$###""""""""""##$###"""""""""!!`Ɓ@@````!!!"""""""""""""""#""!!!!""#####""""""############""""""""!!!!``````!``!!!!""##$$%%%%%%%%%&&&&&&&&''''(())))))******++++++**))((''&&%%$$##""!!``!!""!!```````!!!!""!!!````!!""###$$%%&&''(())**++,,,,,----..//00001122334454433221100//..--,,++**))((''&&&%%%%%%%%%%%%%$$$###"""""""""""##$$%%&&''(())**++,,--..//001122334444455556666677778899:::::;;;;;;;;;;;;;;<<<<<<<<<<;;::998877665544332211100//.............----------------......../////0000001111100//..--,,++**))((''&&%%$$##$$$##"""""!!!""""!!!!!!!!!``!!"!""##$$%%&&''(())**))((''&&%%$$##""!!```!!""#"""""""!!``````!!!!!!!!!!!````!!`!```!!````!!"!!``€``!`!!""####$######"""!!!`@É`!!""##"""###$$$$$$$$$$$$$###""##$$$%%%%%%&&&&'''((((((((())))))***************)**++,,--..//0011221100//..--,,++**))((''&&%%$$$$%%&&''''&&%%%&&''(()$$#######""####$$$$########""!!``@@````!!!!!!""""##############""!!""##$$$#####################""""""""!!!!!``````!!""##$$%$$$$$%%%%%&&&&&&''''((()))))))************))((''&&%%$$##""!!`!!""!!```!!!!!```!!""###$$%%&&''(())**++,,,,,----..//00001122334454433221100//..--,,++**))(('''&&%%%%&&&&%%%%%%$$##############$$%%&&''(())**++,,--..//001122334455555566666677788899::;;;;;<<<<<;<<<<<<<<<<<=====<<;;::998877665544332221100/////////////..-.......--....../////////000000001121100//..--,,++**))((''&&%%$$####$##""!"!!!!!!""!!``````````!!""""##$$%%&&''(())****))((''&&%%$$##""!!```!````!!!!""######""!!````!!!!!!!!!!!!!!!!!!`!`!!!!!!!!!!!!!``!!""!!`````````!```!!!!""#######""""""!!!``@`!!""######$$$$$%%%%%%%%%$$#####$$%%%%%&&&&''''((((())))))))*****+++++++++++*****++,,--..//001122221100//..--,,++**))((''&&%%$%%%&&''''&&%%%%%&&''((%$$$##########$$%$$$######""!!`@@@`!!!!!!!!"""###############$##""""##$$$$$######$$$$$$$$$$$$########""""!!!!!```!!""##$$$$$$$$$%%%%%%%%&&&&''(((((())))))**********))((''&&%%$$##""!!!""""!!````!!```!!"""##$$%%&&''(())**+++++,,,,--..////001122334454433221100//..--,,++**))(('''&&&&&&&&&&&&&%%%$$$###########$$%%&&''(())**++,,--..//001122334455555666677777888899::;;;;;<<<<<<<<<<<<<<==========<<;;::998877665544332221100/////////////................////////0000011111121100//..--,,++**))((''&&%%$$##""###""!!!!!```!!!!`À`!!"""##$$%%&&''(())**++**))((''&&%%$$##""!!`````!!!``````!!!``!!""####""!!``!!!!!!!!"""""""""""!!!!!!""!"!!!""!!!!!!""""!!``!```````!!!!!!`!!!!!!"!""####""#""""""!!!`````!!""##$###$$$%%%%%%%%%%%%%$$$##$$%%%&&&&&&''''((()))))))))******+++++++++++++++*++,,--..//00112233221100//..--,,++**))((''&&%%%%&&''''&&%%$$$%%&&''(%%$$$$$$$##$$$$%%%%$$$$$$##""!!```````````@@@`!!!""""""####$$$$$$$$$$$$$$##""##$$%%%$$$$$$$$$$$$$$$$$$$$$########"""""!!!!```!!""##$$#####$$$$$%%%%%%&&&&'''((((((()))))))))))))*))((''&&%%$$##""!""#"""!!````!!"""##$$%%&&''(())**+++++,,,,--..////001122334454433221100//..--,,++**))(((''&&&&''''&&&&&&%%$$$$$$$$$$$$$$%%&&''(())**++,,--..//001122334455666666777777888999::;;<<<<<=====<===========>>>>>==<<;;::99887766554433322110000000000000//.///////..//////0000000001111111121100//..--,,++**))((''&&%%$$##""""#""!!`!```!!``!!"""##$$%%&&''(())**+++**))((''&&%%$$##""!!```!!!!!"!!```!`!!!!!!``!!""###""!!```!!!!""""""""""""""""""!"!"""""""""""""!!""##""!!!!!!````!!!!!!!!!!!!!"!!!""""####"""""!!!!!!````!!`````!!""##$$$$$$%%%%%&&&&&&&&&%%$$$$$%%&&&&&''''(((()))))********+++++,,,,,,,,,,,+++++,,--..//0011223333221100//..--,,++**))((''&&%&&&''''&&%%$$$$$%%&&''&%%%$$$$$$$$$$%%&%%%$$$$$$##""!!````!```!!!!!!!``````@@@`!!""""###$$$$$$$$$$$$$$$%$$####$$%%%%%$$$$$$%%%%%%%%%%%%$$$$$$$$####"""""!!!!```!!""##########$$$$$$$$%%%%&&''''''(((((())))))))))))))((''&&%%$$##"""#"""""!!````!!!!""##$$%%&&''(())*****++++,,--....//001122334454433221100//..--,,++**))((('''''''''''''&&&%%%$$$$$$$$$$$%%&&''(())**++,,--..//001122334455666667777888889999::;;<<<<<==============>>>>>>>>>>==<<;;::99887766554433322110000000000000////////////////0000000011111222221100//..--,,++**))((''&&%%$$##""!!"""!!``À`!``!!""""##$$%%&&''(())**+++**))((''&&%%$$##""!!``!!!!!!"!!``!!!!!!!!!``!!""###""!!````!!!""""""""###########""""""##"#"""##""""""####""!!"!!!!!!!!!!!""""""!""""""#"####""!!"!!!!!!`ŀ`!!!!```!!!!!""##$$%$$$%%%&&&&&&&&&&&&&%%%$$%%&&&''''''(((()))*********++++++,,,,,,,,,,,,,,,+,,--..//001122334433221100//..--,,++**))((''&&&&''''&&%%$$###$$%%&&'&&%%%%%%%$$%%%%&&&&%%%%%%$$##""!!!!!!!!!!!!!!!!!````!!!!`@@`!!""####$$$$%%%%%%%%%%%%%%$$##$$%%&&&%%%%%%%%%%%%%%%%%%%%%$$$$$$$$#####""""!!!!````!!""###"""""#####$$$$$$%%%%&&&'''''''((((((((((((()))))((''&&%%$$##"#""!""""!!!!```!!!""##$$%%&&''(())*****++++,,--....//001122334454433221100//..--,,++**)))((''''((((''''''&&%%%%%%%%%%%%%%&&''(())**++,,--..//00112233445566777777888888999:::;;<<=====>>>>>=>>>>>>>>>>>?????>>==<<;;::99887766554443322111111111111100/0000000//00000011111111122222221100//..--,,++**))((''&&%%$$##""!!!!""!!``!``!!!!!!""##$$%%&&''(())**+++**))((''&&%%$$##""!!`````!!!""!!!!!``!!!""!!!!```!!""###""!!```!````!!!!""""##################"#"#############""##$$##""""""!!!!"""""""""""""#"""######""!!!!!````````!!!`!!!!!!""##$$%%%%%%&&&&&'''''''''&&%%%%%&&'''''(((())))*****++++++++,,,,,-----------,,,,,--..//00112233444433221100//..--,,++**))((''&'''''&&%%$$#####$$%%&&'&&&%%%%%%%%%%&&'&&&%%%%%%$$##""!!!!"!!!"""""""!!!!!!!!!`@@@`!!""##$$$%%%%%%%%%%%%%%%&%%$$$$%%&&&&&%%%%%%&&&&&&&&&&&&%%%%%%%%$$$$#####""""!!!!``!!"""""""""""########$$$$%%&&&&&&''''''((((((((((((((((((''&&%%$$##""!!!""""!!!!`````!!""##$$%%&&''(()))))****++,,----..//001122334454433221100//..--,,++**)))((((((((((((('''&&&%%%%%%%%%%%&&''(())**++,,--..//0011223344556677777888899999::::;;<<=====>>>>>>>>>>>>>>??????????>>==<<;;::998877665544433221111111111111000000000000000011111111222223221100//..--,,++**))((''&&%%$$##""!!``!!"!!```````!!!!!!!!""##$$%%&&''(())**+++**))((''&&%%$$##""!!!!```!!!"""!!!!!!!```!!""!!!````!!""###""!!`````!!!!!```!!!!"""########$$$$$$$$$$$######$$#$###$$######$$$$##""#"""""""""""######"######$###""!!``!`````!!!"""""##$$%%&%%%&&&'''''''''''''&&&%%&&'''(((((())))***+++++++++,,,,,,---------------,--..//0011223344554433221100//..--,,++**))((''''''&&%%$$##"""##$$%%&''&&&&&&&%%&&&&''''&&&&&&%%$$##"""""""""""""""""!!!!!!!```````!!""##$$$%%%%&&&&&&&&&&&&&&%%$$%%&&'''&&&&&&&&&&&&&&&&&&&&&%%%%%%%%$$$$$####""""!!!``!!""""!!!!!"""""######$$$$%%%&&&&&&&'''''''''''''(((((((''&&%%$$##""!!`!!"""""!!!!!``!!""##$$%%&&''(()))))****++,,----..//001122334454433221100//..--,,++***))(((())))((((((''&&&&&&&&&&&&&&''(())**++,,--..//0011223344556677888888999999:::;;;<<==>>>>>?????>??????????????????>>==<<;;::9988776655544332222222222222110111111100111111222222222333221100//..--,,++**))((''&&%%$$##""!!``!!!```````````````!!""##$$%%&&''(())**+++**))((''&&%%$$##""!!!!```!!!!"""!!`````!!``!!"!!!``!!""###""!!!`````!!!!"!!!`…`!!!""""####$$$$$$$$$$$$$$$$$$#$#$$$$$$$$$$$$$##$$%%$$######""""#############$###$$##""!!```!!""""##$$%%&&&&&&'''''(((((((((''&&&&&''((((())))****+++++,,,,,,,,-----...........-----..//001122334455554433221100//..--,,++**))(('(''&&%%$$##"""""##$$%%('''&&&&&&&&&&''('''&&&&&&%%$$##""""#"""#######""""!!!``````!!!""##$$%%%&&&&&&&&&&&&&&&'&&%%%%&&'''''&&&&&&''''''''''''&&&&&&&&%%%%$$$$$####""""!!``!!!!!!!!!!!!""""""""####$$%%%%%%&&&&&&''''''''''''''''''&&%%$$##""!!``!!"""!!!!!!!```!!""##$$%%&&''(((((())))**++,,,,--..//001122334454433221100//..--,,++***)))))))))))))((('''&&&&&&&&&&&''(())**++,,--..//0011223344556677888889999:::::;;;;<<==>>>>>??????????????????????????>>==<<;;::998877665554433222222222222211111111111111112222222233333221100//..--,,++**))((''&&%%$$##""!!``!!!``!!""##$$%%&&''(())**+++**))((''&&%%$$##""""!!````````!!!!!!!!!!``!!``!!"!!```!!""###""!!`````!!"""!!`…`!!""""###$$$$$$$$%%%%%%%%%%%$$$$$$%%$%$$$%%$$$$$$%%%%$$##$###########$$$$$$#$$$$$$$##""!!`ƒ`!!""##$$%%&&'&&&'''((((((((((((('''&&''((())))))****+++,,,,,,,,,------...............-..//00112233445566554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%(('''''''&&''''((((''''''&&%%$$################"""!!```````!!""##$$%%&&&&''''''''''''''&&%%&&''((('''''''''''''''''''''&&&&&&&&%%%%%$$$$####"""!!``!!!!`````!!!!!""""""####$$$%%%%%%%&&&&&&&&&&&&&''''''''&&%%$$##""!!``!!"!!`!!""!!``!!""##$$%%&&'''(((((())))**++,,,,--..//001122334454433221100//..--,,+++**))))****))))))((''''''''''''''(())**++,,--..//001122334455667788999999::::::;;;<<<==>>???????????????????????????????>>==<<;;::998877666554433333333333332212222222112222223333333334433221100//..--,,++**))((''&&%%$$##""!!`!!!!``!!""##$$%%&&''(())**+++**))((''&&%%$$##""""!!!!!!!!!!!!!!!!!!````!!```!!!```!!""###""!!``!!!!"!!```!!"""####$$$$%%%%%%%%%%%%%%%%%%$%$%%%%%%%%%%%%%$$%%&&%%$$$$$$####$$$$$$$$$$$$$%$$$$$##"""!!`†`!!""##$$%%&&&&&&''((((()))))))))(('''''(()))))****++++,,,,,--------.....///////////.....//00112233445566554433221100//..--,,++**))((''&&%%$$##""!!!!!""##$$)(((''''''''''((((''''''&&%&%%$$####$######""""""!!```!!``!!""##$$%%&&''''''''''''''(''&&&&''(((((''''''((((((((((((''''''''&&&&%%%%%$$$$####""!!`@@`!`````!!!!!!!!""""##$$$$$$%%%%%%&&&&&&&&&&&&&&&&&&&&%%$$##""!!``!!!!``!!"!!```!!""##$$%%&&&''''''(((())**++++,,--..//001122334454433221100//..--,,+++*************)))((('''''''''''(())**++,,--..//00112233445566778899999::::;;;;;<<<<==>>?????????????????????????????????>>==<<;;::998877666554433333333333332222222222222222333333334444433221100//..--,,++**))((''&&%%$$##""!!!""!!```!!""##$$%%&&''(())**++++**))((''&&%%$$####""!!!!!!!!"!!````````!``!!``!!""##""!!```!!!!!``!!!""####$$$%%%%%%%%&&&&&&&&&&&%%%%%%&&%&%%%&&%%%%%%&&&&%%$$%$$$$$$$$$$$%%%%%%$%%%%$$##""!!!``!!""##$$%%&&&&&&&&''(())))))))))))(((''(()))******++++,,,---------......///////////////.//00112233445566554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$))(((((((''((((((''''&&&&%%%%%%$$$$$#####""""""!!!```!!!!```!!""##$$%%&&''((((((((((((((''&&''(()))(((((((((((((((((((((''''''''&&&&&%%%%$$$$##""!!``````!!!!!!""""###$$$$$$$%%%%%%%%%%%%%&&&&&&&&&&&%%$$##""!!``!!!!``!!!!``!!""##$$%%&&&''''''(((())**++++,,--..//001122334454433221100//..--,,,++****++++******))(((((((((((((())**++,,--..//00112233445566778899::::::;;;;;;<<<===>>???????????????????????????????????>>==<<;;::998877766554444444444444332333333322333333444444444554433221100//..--,,++**))((''&&%%$$##""!"""!!````!!""##$$%%&&''(())**++,,++**))((''&&%%$$####"""""""""!!```!`@`!!``!!""###""!!```!!```!!!""###$$$$%%%%&&&&&&&&&&&&&&&&&&%&%&&&&&&&&&&&&&%%&&''&&%%%%%%$$$$%%%%%%%%%%%%%%%$$##""!!!```!!""##$$%%&&&&%%%%&&''(())********))((((())*****++++,,,,-----......../////00000000000/////00112233445566554433221100//..--,,++**))((''&&%%$$##""!!``!!""##*)))((((((((((((''&&&&&&%%$%%$$$########"""!!!!!!```!!!"!!```!`!!""##$$%%&&''((((((((((((()((''''(()))))(((((())))))))))))((((((((''''&&&&&%%%%$$$##""!!``````!!!!""######$$$$$$%%%%%%%%%%%%%%%%%%&&%%$$##""!!``!!!!!!``!!"!!``!!""##$$%%%%&&&&&&''''(())****++,,--..//001122334454433221100//..--,,,+++++++++++++***)))((((((((((())**++,,--..//00112233445566778899:::::;;;;<<<<<====>>?????????????????????????????????????>>==<<;;::998877766554444444444444333333333333333344444444555554433221100//..--,,++**))((''&&%%$$##""""!!``!``!!""##$$%%&&''(())**++,,,,++**))((''&&%%$$$$##"""""""!!```!!!``!!!``!!""###""!!```````!!"""##$$$$%%%&&&&&&&&'''''''''''&&&&&&''&'&&&''&&&&&&''''&&%%&%%%%%%%%%%%&&&&&&%%%$$##""!!```!!""##$$%%&&&%%%%%%&&''(())********)))(())***++++++,,,,---.........//////000000000000000/001122334455666554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##**))))((((((('(''&&&&%%%%$$$$$$#####"""""!!!!!!```!!""""!!```!!!!!""##$$%%&&''(())))))))))))))((''(())***)))))))))))))))))))))(((((((('''''&&&&%%%$$##""!!``!!!!"""#######$$$$$$$$$$$$$%%%%%%%%%%%$$##""!!````!``!``!!!!!!``!!""##$$%%%%%&&&&&&''''(())****++,,--..//001122334454433221100//..---,,++++,,,,++++++**))))))))))))))**++,,--..//00112233445566778899::;;;;;;<<<<<<===>>>???????????????????????????????????????>>==<<;;::998887766555555555555544344444443344444455555555566554433221100//..--,,++**))((''&&%%$$##"""!!``!!``!!""##$$%%&&''(())**++,,--,,++**))((''&&%%$$$$#####""!!``!``!``!``!!!``!!""###""!!``!!!!"""##$$$%%%%&&&&''''''''''''''''''&'&'''''''''''''&&''((''&&&&&&%%%%&&&&&&&&&&&%%$$##""!!```!!""##$$%%&%%$$$$%%&&''(())**++++**)))))**+++++,,,,----.....////////000001111111111100000112233445566766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!""#)*))(((((''(''''&&%%%%%%$$#$$###""""""""!!!``````!!"""""!!````!!!!"!""##$$%%&&''(()))))))))))))*))(((())*****))))))************))))))))(((('''''&&&&%%$$##""!!``…```!!""""""######$$$$$$$$$$$$$$$$$$%%%$$##""!!```!!!!`!!!!``!!""##$$$$$%%%%%%&&&&''(())))**++,,--..//001122334454433221100//..---,,,,,,,,,,,,,+++***)))))))))))**++,,--..//00112233445566778899::;;;;;<<<<=====>>>>?????????????????????????????????????????>>==<<;;::998887766555555555555544444444444444445555555566666554433221100//..--,,++**))((''&&%%$$###""!!``!!``!!""##$$%%&&''(())**++,,---,,++**))((''&&%%%%$$####""!!````!``!``!!"!!``!!""####""!!``!!!!""###$$%%%%&&&''''''''(((((((((((''''''(('('''((''''''((((''&&'&&&&&&&&&&&'''&&%%$$##""!!``!!""##$$%%%$$$$$$%%&&''(())**++++***))**+++,,,,,,----.../////////000000111111111111111011223344556677766554433221100//..--,,++**))((''&&%%$$##""!!!!```!!"")))((('''''''&'&&%%%%$$$$######"""""!!!!!```!!!"""""!!``!!!!"""""##$$%%&&''(())**************))(())**+++*********************))))))))(((((''''&&&%%$$##""!!!``@`!!!"""""""#############$$$$$$$$$%%$$##""!!````!!```!!``!!""###$$$$$%%%%%%&&&&''(())))**++,,--..//001122334454433221100//...--,,,,----,,,,,,++**************++,,--..//00112233445566778899::;;<<<<<<======>>>????????????????????????????????????????????>>==<<;;::9998877666666666666655455555554455555566666666666554433221100//..--,,++**))((''&&&&%%$$###""!!!!``!!""##$$%%&&''(())**++,,--.--,,++**))((''&&%%%%$$##""!!``!``!!!``!!"""!!`!!""##$##""!!```!!""""###$$%%%&&&&'&&&&''((((((((((((((('('(((((((((((((''(())((''''''&&&&''''''''&&%%$$##""!!``!!""##$$%%$$####$$%%&&''(())**++++*****++,,,,,----..../////0000000011111222222222221111122334455667787766554433221100//..--,,++**))((''&&%%$$##""!!``!!"()(('''''&&'&&&&%%$$$$$$##"##"""!!!!!!!!`````!!""!!!!``!!""""#"##$$%%&&''(())*************+**))))**+++++******++++++++++++********))))(((((''''&&%%$$##""!!!`@`!!!!!!""""""##################$$$$##""!!``!``!!``!!""#######$$$$$$%%%%&&''(((())**++,,--..//001122334454433221100//...-------------,,,+++***********++,,--..//00112233445566778899::;;<<<<<====>>>>>???????????????????????????????????????????????>>==<<;;::99988776666666666666555555555555555566666666766554433221100//..--,,++**))((''&&&&&&%%$$$##""!!``!!""##$$%%&&''(())****++,,--.--,,++**))((''&&&%%$$##""!!``!!!!!!``!!""""!!!""##$$##""!!``!!""""##$$$%%&&&&''&&&&&&''(())))))))))(((((())()((())(((((())))((''('''''''''''''&&%%$$##""!!``!!""##$$$$######$$%%&&''(())**+++++**++,,,------....///00000000011111122222222222222212233445566778887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""((('''&&&&&&&%&%%$$$$####""""""!!!!!`````````!!!!!!!!```````!!"""#####$$%%&&''(())**++++++++++++++**))**++,,,+++++++++++++++++++++********)))))(((('''&&%%$$##"""!!`@€``!!!!!!!"""""""""""""#########$$$##""!!``!``!``!!!""""#####$$$$$$%%%%&&''(((())**++,,--..//001122334454433221100///..----....------,,++++++++++++++,,--..//00112233445566778899::;;<<======>>>>>>?????????????????????????????????????????????????>>==<<;;:::99887777777777777665666666655666666777777766554433221100//..--,,++**))((''&&%%%%%%%$$####""!!````!!!""##$$%%&&''(())****++,,--.--,,++**))((''&&%%$$##""!!``!!!``!``!!""##""!""##$$$##""!!```!!""####$$$%%&&&'''&&%%%%&&''(()))))))))))()()))))))))))))(())**))((((((''''(((((''&&%%$$##""!!``!!""##$$$##""""##$$%%&&''(())**+++++++,,-----....////00000111111112222233333333333222223344556677889887766554433221100//..--,,++**))((''&&%%$$##""!!!!!""#'(''&&&&&%%&%%%%$$######""!""!!!```````!!!``!!!``!!!!!!!!!!!""####$#$$%%&&''(())**+++++++++++++,++****++,,,,,++++++,,,,,,,,,,,,++++++++****)))))((((''&&%%$$##"""!!`@````!!!!!!""""""""""""""""""##$$##""!!``!!````!````!!"""""""######$$$$%%&&''''(())**++,,--..//001122334454433221100///.............---,,,+++++++++++,,--..//00112233445566778899::;;<<=====>>>>??????????????????????????????????????????????????????>>==<<;;:::998877777777777776666666666666666777777766554433221100//..--,,++**))((''&&%%%%%%%$$##""""""!!!!```!!""##$$%%&&''(())))**++,,---,,++**))(((''&&%%$$##""!!`@`!```````!!""###"""##$$$$##""!!``!!""####$$%%%&&''''&&%%%%%%&&''(())******))))))**)*)))**))))))****))(()(((((((((((''&&%%$$##""!!``!!""##$$$##""""""##$$%%&&''(())**++,++,,---......////0001111111112222223333333333333332334455667788999887766554433221100//..--,,++**))((''&&%%$$##""!!!""##'''&&&%%%%%%%$%$$####""""!!!!!!```!!!!!!``!!``!!!!!!!!!""###$$$$$%%&&''(())**++,,,,,,,,,,,,,,++**++,,---,,,,,,,,,,,,,,,,,,,,,++++++++*****))))(((''&&%%$$###""!!`````!!!!!!!!!!!!!"""""""""##$$##""!!``!!!!!!!``!!!!"""""######$$$$%%&&''''(())**++,,--..//0011223344544332211000//....////......--,,,,,,,,,,,,,,--..//00112233445566778899::;;<<==>>>>>>?????????????????????????????????????????????????????????>>==<<;;;::9988888888888887767777777667777778887766554433221100//..--,,++**))((''&&%%$$$$$$$##""""!!!!!!``!!""##$$%%&&''(())))**++,,-,,++**))((''''&&%%$$##""!!`@@````!``````!``!!""#####"##$$$$$##""!!````!!""##$$$$$%%&&''''&&%%$$$$%%&&''(())*******)*)*************))**++**))))))(((())((''&&%%$$##""!!````!!""##$$$##""!!!!""##$$%%&&''(())**++,,,--.....////00001111122222222333334444444444433333445566778899:99887766554433221100//..--,,++**))((''&&%%$$##"""""##$&'&&%%%%%$$%$$$$##""""""!!`!!````!!!!"""!!`!!!``!!""""""""##$$$$%$%%&&''(())**++,,,,,,,,,,,,,-,,++++,,-----,,,,,,------------,,,,,,,,++++*****))))((''&&%%$$###""!!````!!!!!!!!!!!!!!!!!!""##$##""!!``!!"!!!!``!!!!!!!""""""####$$%%&&&&''(())**++,,--..//0011223344544332211000/////////////...---,,,,,,,,,,,--..//00112233445566778899::;;<<==>>>>>????????????????????????????????????????????????????????????>>==<<;;;::99888888888888877777777777777778887766554433221100//..--,,++**))((''&&%%$$$$$$$##""!!!!!!!!``!!""##$$%%&&''(((())**++,,,++**))(('''&&&&%%$$##""!!`@`````!!!!``!!!!!""##########$$$##"""!!``!!!!""##$##$$$$%%&&&'&&%%$$$$$$%%&&''(())**++******++*+***++******++++**))*))))))))((''&&%%$$##""!!``!!```!!""##$$$##""!!!!!!""##$$%%&&''(())**++,,--..//////00001112222222223333334444444444444443445566778899:::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$&&&%%%$$$$$$$#$##""""!!!!```@````!!!!""""""!!!"!!``!!""""""""##$$$%%%%%&&''(())**++,,--------------,,++,,--...---------------------,,,,,,,,+++++****)))((''&&%%$$$##""!!`````````````!!!!!!!!!""##$##""!!``````!!!!!!`````!!!!!""""""####$$%%&&&&''(())**++,,--..//0011223344544332211100////0000//////..--------------..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????>>==<<<;;::999999999999988788888887788888887766554433221100//..--,,++**))((''&&%%$$#######""!!!!``````@`!!""##$$%%&&''(((())**++,++**))((''&&&&&&%%$$##""!!`@``!`…```!!!!!!"!!""#"""""""""#####""""!!```!!!!!""########$$%%&&&&%%$$####$$%%&&''(())**+++*+*+++++++++++++**++,,++******))))))((''&&%%$$##""!!``!!!!!!!""##$$$##""!!````!!""##$$%%&&''(())**++,,--..//0000111122222333333334444455555555555444445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$#####$$%%&%%$$$$$##$####""!!!!!!``!!!!!!""""###""!"""!!!!""########$$%%%%&%&&''(())**++,,-------------.--,,,,--.....------............--------,,,,+++++****))((''&&%%$$$##""!!!`````````!!""#####""!!!!!!!!!!!``````!!!!!!""""##$$%%%%&&''(())**++,,--..//001122334454433221110000000000000///...-----------..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????>>==<<<;;::9999999999999888888888888888887766554433221100//..--,,++**))((''&&%%$$#######""!!`````````!!"""##$$%%&&''''(())**+++**))((''&&&%%%%%%$$##""!!`@ń``!````!!!!"""""""""""""""""###""!!!!````!!````!!""##""####$$%%%&%%$$######$$%%&&''(())**++++++,,+,+++,,++++++,,,,++**+******))((''&&%%$$##""!!``!!"!!!""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//00111122233333333344444455555555555555545566778899::;;;::99887766554433221100//..--,,++**))((''&&%%$$###$$%%%%%$$$#######"#""!!!!`````!!!""""######"""#""!!""########$$%%%&&&&&''(())**++,,--..............--,,--..///.....................--------,,,,,++++***))((''&&%%%$$##""!!!``!!""#"###""!!!!!!!!```!!!!!!""""##$$%%%%&&''(())**++,,--..//0011223344544332221100001111000000//..............//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????>>===<<;;:::::::::::::998999999988999887766554433221100//..--,,++**))((''&&%%$$##"""""""!!```````!!"""##$$%%&&''''(())**+**))((''&&%%%%%%%%%$$##""!!``@``!!``````!!""""""""!!!!!!!!!"""""!!!!``!`````!!""""""""##$$%%%%$$##""""##$$%%&&''(())**++,+,,,,,,,,,,,,,++,,--,,++++++****))((''&&%%$$##""!!``!!"""""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//0011222333334444444455555666666666665555566778899::;;<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$%%&$%$$#####""#""""!!``````!!""####$$$##"###""""##$$$$$$$$%%&&&&'&''(())**++,,--............./..----../////......////////////........----,,,,,++++**))((''&&%%%$$##""!!``!!"""""#""!!`````````````!!!!""##$$$$%%&&''(())**++,,--..//0011223344544332221111111111111000///...........//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????>>===<<;;:::::::::::::9999999999999887766554433221100//..--,,++**))((''&&%%$$##"""""""!!``!```!!!""##$$%%&&&&''(())***))((''&&%%%$$$$$$%$$$##""!!`@@`!!```!!`!``!!""!!!!!!!!!!!!!!!"""!!`````!``!!""!!""""##$$$%$$##""""""##$$%%&&''(())**++,,--,-,,,--,,,,,,----,,++,++++**))((''&&%%$$##""!!``!!"""##$$%$$##""!!```!!""##$$%%&&''(())**++,,--..//001122333444444444555555666666666666666566778899::;;<<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%&&$$$###"""""""!"!!```!!````!!""##$$$$$###$##""##$$$$$$$$%%&&&'''''(())**++,,--..//////////////..--..//000/////////////////////........-----,,,,+++**))((''&&&%%$$##""!!`````!!""!"""!!`ƒ`!!!!""##$$$$%%&&''(())**++,,--..//0011223344544333221111222211111100//////////////00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????>>>==<<;;;;;;;;;;;;;::9:::::::999887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!````!!!!""##$$%%&&&&''(())*))((''&&%%$$$$$$$$$$$##""!!`@````!!!!!!!!!``!!""!!!!!!`````````!!!!!```!!``!!!!!!!!!""##$$$$##""!!!!""##$$%%&&''(())**++,,-----------,,--..--,,,,,,++**))((''&&%%$$##""!!``!!""##$$%%$$##""!!!``!!""##$$%%&&''(())**++,,--..//001122334444455555555666667777777777766666778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%%%%&&'#$##"""""!!"!!!!`Ɂ```!!!!!!````!!""##$$%%%$$#$$$####$$%%%%%%%%&&''''('(())**++,,--../////////////0//....//00000//////000000000000////////....-----,,,,++**))((''&&%%$$##""!!`````@`!!"!!!""!!`````!!""####$$%%&&''(())**++,,--..//00112233445443332222222222222111000///////////00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????>>>==<<;;;;;;;;;;;;;:::::::::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!`````!!""##$$%%%%&&''(()))((''&&%%$$$######$#####""!!````````````!!!!```!!!!!!``````!!!!``````!!!!``!!!!""###$##""!!!!!!""##$$%%&&''(())**++,,-----..------....--,,-,,++**))((''&&%%$$##""!!``!!""##$$%%%$$##""!!!`!!""##$$%%&&''(())**++,,--..//001122334445555555556666667777777777777776778899::;;<<===<<;;::99887766554433221100//..--,,++**))((''&&%%%&&''###"""!!!!!!!`!```!!!!!""!!!``!!``!!""##$$%%%%%$$$%$$##$$%%%%%%%%&&'''((((())**++,,--..//00000000000000//..//00111000000000000000000000////////.....----,,,++**))((''&&%%$$##""!!`!```!!``!!"!!`!!"!!``!!""####$$%%&&''(())**++,,--..//0011223344544433222233332222221100000000000000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????>>==<<<<<<<<<<<<<;;:;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````````````!!""##$$%%%%&&''(()((''&&%%$$############"""!!!!`@@`````!!!!!!!!!!!`````@@@`!``````!!""####""!!````!!""##$$%%&&''(())**++,,--.......--..//..-----,,++**))((''&&%%$$##""!!``!!""##$$%%&%%$$##"""!!!""##$$%%&&''(())**++,,--..//001122334455555666666667777788888888888777778899::;;<<==>==<<;;::99887766554433221100//..--,,++**))((''&&&&&''("#""!!!!!``!```````````!!""""""!!!!!!!!""##$$%%&&&%%$%%%$$$$%%&&&&&&&&''(((()())**++,,--..//0000000000000100////001111100000011111111111100000000////.....----,,++**))((''&&%%$$##""!!!````!``!`!!``!!!!``!!"!!``!!"""""##$$%%&&''(())**++,,--..//00112233445444333333333333322211100000000000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<<<<<<<<<<<<;;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````````!``!!""##$$$$%%&&''(((''&&%%$$###""""""#"""""!!``!!`@@``````!!!!!!``````@`!``````!!"""#""!!``!!""##$$%%&&''(())**++,,--../......////..----,,++**))((''&&%%$$##""!!```!!""##$$%%&&&%%$$##"""!""##$$%%&&''(())**++,,--..//001122334455566666666677777788888888888888878899::;;<<==>>>==<<;;::99887766554433221100//..--,,++**))((''&&&''(("""!!!````````!!!!!!``!!""##"""!!""!!""##$$%%&&&&&%%%&%%$$%%&&&&&&&&''((()))))**++,,--..//001111111111111100//001122211111111111111111111100000000/////....--,,++**))((''&&%%$$##""!!``````!```!!!!``!!"!!``!!!!"""""##$$%%&&''(())**++,,--..//001122334455443333444433333322111111111111112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????>>=============<<;<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ǀ`!``!``!!""##$$$$%%&&''(''&&%%$$##""""""""""""!!!`````````!!````!`̀`!!"""""!!``!!""##$$%%&&''(())**++,,--..///..//00//...--,,++**))((''&&%%$$##""!!```!`````!!""##$$%%&&'&&%%$$###"""##$$%%&&''(())**++,,--..//001122334455666667777777788888999999999998888899::;;<<==>>?>>==<<;;::99887766554433221100//..--,,++**))(('''''(()!"!!```!```!!!!!!!!````!!""#####""""""""##$$%%&&'''&&%&&&%%%%&&''''''''(())))*)**++,,--..//00111111111111121100001122222111111222222222222111111110000/////..--,,++**))((''&&%%$$##""!!``!!``!!!!`!!"!!`!``!!!!!!!!""##$$%%&&''(())**++,,--..//0011223344554444444444444333222111111111112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????>>=============<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!``!!``!!""####$$%%&&'''&&%%$$##"""!!!!!!"!!!!!!``!``````!```!!!""""!!``!!""##$$%%&&''(())**++,,--..//////0000//..--,,++**))((''&&%%$$##""!!``!!!!!!!!!""##$$%%&&'''&&%%$$###"##$$%%&&''(())**++,,--..//001122334455666777777777888888999999999999999899::;;<<==>>???>>==<<;;::99887766554433221100//..--,,++**))(('''(())!!!`Ά`!!``!!!""""""!!!!!!""##$$###""##""##$$%%&&'''''&&&'&&%%&&''''''''(()))*****++,,--..//001122222222222222110011223332222222222222222222221111111100000//..--,,++**))((''&&%%$$##""!!``!!``!!"!!!"!!``!`````!!!!!""##$$%%&&''(())**++,,--..//00112233445544445555444444332222222222222233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!``!!!!``!!""#####$$%%&&'&&%%$$##""!!!!!!!!!!!!````````@`ŀ``!!!!""!!!``!!""##$$%%&&''(())**++,,--..//0//001100//..--,,++**))((''&&%%$$##""!!``!!!"!!!!!""##$$%%&&''(''&&%%$$$###$$%%&&''(())**++,,--..//00112233445566777778888888899999:::::::::::99999::;;<<==>>?????>>==<<;;::99887766554433221100//..--,,++**))((((())*`!!``!!!``!!!""""""""!!!!""##$$$$$########$$%%&&''(((''&'''&&&&''(((((((())****+*++,,--..//0011222222222222232211112233333222222333333333333222222221111000//..--,,++**))((''&&%%$$##""!!``!!``!!!!!""!!```!`````!!""##$$%%&&''(())**++,,--..//001122334455555555555554443332222222222233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!"!!``!!!!!!``!!"""""##$$%%&&&%%$$##""!!!``````!``````!!!!!````!!""##$$%%&&''(())**++,,--..//000011100//..--,,++**))((''&&%%$$##""!!``!!"""""""""##$$%%&&''(((''&&%%$$$#$$%%&&''(())**++,,--..//00112233445566777888888888999999:::::::::::::::9::;;<<==>>???????>>==<<;;::99887766554433221100//..--,,++**))((())**```!!"!!!!"""######""""""##$$%%$$$##$$##$$%%&&''((((('''(''&&''(((((((())***+++++,,--..//001122333333333333332211223344433333333333333333333322222222111100//..--,,++**))((''&&%%$$##""!!``!!!``!!!!!!"!!`````!!""##$$%%&&''(())**++,,--..//0011223344555566665555554433333333333333445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""!!``````````!!"""""##$$%%&%%$$##""!!```À``!!``!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!``!!"""""""##$$%%&&''(()((''&&%%%$$$%%&&''(())**++,,--..//00112233445566778888899999999:::::;;;;;;;;;;;:::::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**)))))**+``!!"""!!"""########""""##$$%%%%%$$$$$$$$%%&&''(()))(('(((''''(())))))))**++++,+,,--..//0011223333333333333433222233444443333334444444444443333333322221100//..--,,++**))((''&&%%$$##""!!``!!!!```````!!!````!!""##$$%%&&''(())**++,,--..//001122334455666666666655544433333333333445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"!!``!!!!!!""##$$%%%$$##""!!````!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!``!!""######$$%%&&''(()))((''&&%%%$%%&&''(())**++,,--..//0011223344556677888999999999::::::;;;;;;;;;;;;;;;:;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**)))**++``!!!""#""""###$$$$$$######$$%%&&%%%$$%%$$%%&&''(()))))((()((''(())))))))**+++,,,,,--..//001122334444444444444433223344555444444444444444444444333333332221100//..--,,++**))((''&&%%$$##""!!``!!!!```!!``!``!!""##$$%%&&''(())**++,,--..//00112233445566777766666655444444444444445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"!!``!!!!!!!""##$$%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!``!!""#####$$%%&&''(())*))((''&&&%%%&&''(())**++,,--..//00112233445566778899999::::::::;;;;;<<<<<<<<<<<;;;;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++*****++,```!!!!""###""###$$$$$$$$####$$%%&&&&&%%%%%%%%&&''(())***))()))(((())********++,,,,-,--..//0011223344444444444445443333445555544444455555555555544444444333221100//..--,,++**))((''&&%%$$##""!!``!!!!!``!!``!``!!""##$$%%&&''(())**++,,--..//0011223344556677777777666555444444444445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!````````!!""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$%%&&''(())***))((''&&&%&&''(())**++,,--..//001122334455667788999:::::::::;;;;;;<<<<<<<<<<<<<<<;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++***++,,```!!!!!"""##$####$$$%%%%%%$$$$$$%%&&''&&&%%&&%%&&''(())*****)))*))(())********++,,,-----..//001122334455555555555555443344556665555555555555555555554444444433221100//..--,,++**))((''&&%%$$##""!!``!!"!!!```!``!``!!""##$$%%&&''(())**++,,--..//001122334455667788777777665555555555555566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!!!``!!""##$$##""!!`@@`!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!`````!!""##$$$%%&&''(())**+**))(('''&&&''(())**++,,--..//00112233445566778899:::::;;;;;;;;<<<<<===========<<<<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,+++++,,-!!!!!!""""##$$$##$$$%%%%%%%%$$$$%%&&'''''&&&&&&&&''(())**+++**)***))))**++++++++,,----.-..//00112233445555555555555655444455666665555556666666666665555555544433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!!``!!```!!``!!""##$$%%&&''(())**++,,--..//00112233445566778888887776665555555555566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!!!``!!""##$$##""!!`@`!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!````!!!`!!""##$$%%%&&''(())**+++**))(('''&''(())**++,,--..//00112233445566778899:::;;;;;;;;;<<<<<<===============<==>>???????????????????>>==<<;;::99887766554433221100//..--,,+++,,--!!!"""""###$$%$$$$%%%&&&&&&%%%%%%&&''(('''&&''&&''(())**+++++***+**))**++++++++,,---.....//0011223344556666666666666655445566777666666666666666666666555555554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!`````!!!``!``!!""##$$%%&&''(())**++,,--..//0011223344556677888888887766666666666666778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!""!!````!!""####""!!`@`!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!""##$$%%%&&''(())**++,++**))((('''(())**++,,--..//00112233445566778899::;;;;;<<<<<<<<=====>>>>>>>>>>>=====>>?????????????????????>>==<<;;::99887766554433221100//..--,,,,,--.""""""####$$%%%$$%%%&&&&&&&&%%%%&&''(((((''''''''(())**++,,,++*+++****++,,,,,,,,--...././/001122334455666666666666676655556677777666666777777777777666666665554433221100//..--,,++**))((''&&%%$$##""!!```!!"""!!```!``!!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899988877766666666666778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!"!!!!```!!""####""!!`@`!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!``!!!"""!""##$$%%&&&''(())**++,,,++**))((('(())**++,,--..//00112233445566778899::;;;<<<<<<<<<======>>>>>>>>>>>>>>>=>>???????????????????????>>==<<;;::99887766554433221100//..--,,,--.."""#####$$$%%&%%%%&&&''''''&&&&&&''(())(((''((''(())**++,,,,,+++,++**++,,,,,,,,--.../////00112233445566777777777777776655667788877777777777777777777766666666554433221100//..--,,++**))((''&&%%$$##""!!!```!!"""!!!````!!!"!!````!!""##$$%%&&''(())**++,,--..//0011223344556677889999988777777777777778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`À`!!!!````!!""##"""!!!``!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!``!!""""""##$$%%&&&''(())**++,,-,,++**)))((())**++,,--..//00112233445566778899::;;<<<<<========>>>>>???????????>>>>>?????????????????????????>>==<<;;::99887766554433221100//..-----../######$$$$%%&&&%%&&&''''''''&&&&''(()))))(((((((())**++,,---,,+,,,++++,,--------..////0/0011223344556677777777777778776666778888877777788888888888877777777666554433221100//..--,,++**))((''&&%%$$##""!!!``!!""""!!!``!!!!!`@``!!""##$$%%&&''(())**++,,--..//00112233445566778899:999888777777777778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!``!!"""""""!!```!!""##$$%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$##""!!``!!""##"##$$%%&&'''(())**++,,---,,++**)))())**++,,--..//00112233445566778899::;;<<<=========>>>>>>???????????????>???????????????????????????>>==<<;;::99887766554433221100//..---..//###$$$$$%%%&&'&&&&'''((((((''''''(())**)))(())(())**++,,-----,,,-,,++,,--------..///000001122334455667788888888888888776677889998888888888888888888887777777766554433221100//..--,,++**))((''&&%%$$##"""!!``!!""#"""!!````!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::998888888888888899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!``!!"""""!!!``!!""##$$%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$##""!!``!!""#####$$%%&&'''(())**++,,--.--,,++***)))**++,,--..//00112233445566778899::;;<<=====>>>>>>>>????????????????????????????????????????????????>>==<<;;::99887766554433221100//.....//0$$$$$$%%%%&&'''&&'''((((((((''''(())*****))))))))**++,,--...--,---,,,,--........//000010112233445566778888888888888988777788999998888889999999999998888888877766554433221100//..--,,++**))((''&&%%$$##"""!!``!!""##"""!!``!!`@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899:::9998888888888899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!!!!!``!!"""!!!!!```!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##"""!!``!!""##$$#$$%%&&''((())**++,,--...--,,++***)**++,,--..//00112233445566778899::;;<<===>>>>>>>>>???????????????????????????????????????????????????>>==<<;;::99887766554433221100//...//00$$$%%%%%&&&''(''''((())))))(((((())**++***))**))**++,,--.....---.--,,--........//00011111223344556677889999999999999988778899:::999999999999999999999888888887766554433221100//..--,,++**))((''&&%%$$###""!!``!!""#####""!!``!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;::99999999999999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!!!!!!""!!```!!""!!!!!`````!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""""!!``!!""##$$$$$%%&&''((())**++,,--../..--,,+++***++,,--..//00112233445566778899::;;<<==>>>>>??????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////001%%%%%%&&&&''(((''((())))))))(((())**+++++********++,,--..///..-...----..////////00111121223344556677889999999999999:99888899:::::999999::::::::::::999999998887766554433221100//..--,,++**))((''&&%%$$###""!!!!""##$$##""!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;:::99999999999::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!!!!""""""!!````!!!!!!````!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!!!!``!!""##$$%%$%%&&''(()))**++,,--..///..--,,+++*++,,--..//00112233445566778899::;;<<==>>>??????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///0011%%%&&&&&'''(()(((()))******))))))**++,,+++**++**++,,--../////.../..--..////////001112222233445566778899::::::::::::::998899::;;;:::::::::::::::::::::99999999887766554433221100//..--,,++**))((''&&%%$$$##""!!""##$$$##""!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;::::::::::::::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````````!!!!!!"""""""##""!!```!``!!!!```!!!!``!!""##$$%%&&''(())**++,,--..//00000//..--,,++**))((''&&%%$$##""!!!!!!```!!""##$$%%%%%&&''(()))**++,,--..//0//..--,,,+++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100000112&&&&&&''''(()))(()))********))))**++,,,,,++++++++,,--..//000//.///....//000000001122223233445566778899:::::::::::::;::9999::;;;;;::::::;;;;;;;;;;;;::::::::999887766554433221100//..--,,++**))((''&&%%$$$##""""##$$$##""!!!!!!```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;;:::::::::::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!`!!!!!!!!""""""""######""!!````!!```!!!!``!!""##$$%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%$$##""!!```!!!``!!!""##$$%%&&%&&''(())***++,,--..//000//..--,,,+,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110001122&&&'''''((())*))))***++++++******++,,--,,,++,,++,,--..//00000///0//..//000000001122233333445566778899::;;;;;;;;;;;;;;::99::;;<<<;;;;;;;;;;;;;;;;;;;;;::::::::99887766554433221100//..--,,++**))((''&&%%%$$##""##$$$##""!!```````!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;;;;;;;;;;;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!!!!""""""#########"""!!`‡``!!``!!!!``!!""##$$%%&&''(())**++,,--..//0///..--,,++**))((''&&%%$$##""!!``````!!!""##$$%%&&&&&''(())***++,,--..//00100//..---,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211111223''''''(((())***))***++++++++****++,,-----,,,,,,,,--..//0011100/000////001111111122333343445566778899::;;;;;;;;;;;;;<;;::::;;<<<<<;;;;;;<<<<<<<<<<<<;;;;;;;;:::99887766554433221100//..--,,++**))((''&&%%%$$####$$$##""!!`ƈ``!!!!``!!""###$$%%&&''(())**++,,--..//00112233445566778899::;;<;;;;;;;;;;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!""""""""#########"""""!!!!``!!`Ć`!!"!!``!!""##$$%%&&''(())**++,,--../////...--,,++**))((''&&%%$$##""!!```!!"""##$$%%&&''&''(())**+++,,--..//0011100//..---,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221112233'''((((()))**+****+++,,,,,,++++++,,--..---,,--,,--..//0011111000100//001111111122333444445566778899::;;<<<<<<<<<<<<<<;;::;;<<===<<<<<<<<<<<<<<<<<<<<<;;;;;;;;::99887766554433221100//..--,,++**))((''&&&%%$$##$$%$$##""!!```!!!!!``!!""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<<<<<<<<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""""""""######$$##"""""!!!!```````!!`Ç`!!"!!`ː`!!""##$$%%&&''(())**++,,--..///...---,,++**))((''&&%%$$##""""!!````!!!"""##$$%%&&'''''(())**+++,,--..//001121100//...---..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322222334(((((())))**+++**+++,,,,,,,,++++,,--.....--------..//001122211011100001122222222334444545566778899::;;<<<<<<<<<<<<<=<<;;;;<<=====<<<<<<============<<<<<<<<;;;::99887766554433221100//..--,,++**))((''&&&%%$$$$%%%$$##""!!!```!!!"!!`````!!""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<<<<<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####"########$$$$$##""!!!!!``````````!!!```!!!!!``!!""!!`Ȍ`!!""##$$%%&&''(())**++,,--../...---,,++**))((''&&%%$$##""""!!``!!!!""###$$%%&&''(('(())**++,,,--..//00112221100//...-..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332223344((()))))***++,++++,,,------,,,,,,--..//...--..--..//001122222111211001122222222334445555566778899::;;<<==============<<;;<<==>>>=====================<<<<<<<<;;::99887766554433221100//..--,,++**))(('''&&%%$$%%&%%$$##""!!!```!!!""!!`@`!!""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<========>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##########$$$$$$##""!!!!!``!!!````!!```!!!!!!!!!!!!``!!"!!``!!""##$$%%&&''(())**++,,--....---,,,++**))((''&&%%$$##""!!!!``!!!"""###$$%%&&''((((())**++,,,--..//0011223221100///...//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433333445))))))****++,,,++,,,--------,,,,--../////........//001122333221222111122333333334455556566778899::;;<<=============>==<<<<==>>>>>======>>>>>>>>>>>>========<<<;;::99887766554433221100//..--,,++**))(('''&&%%%%&&&%%$$##"""!!``!!!!"""!!```!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<======>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$#$$$$$$$$%$$##""!!`````!!!!!!!!!!!!!!!"""!!!!!!``!!!!``!!""##$$%%&&''(())**++,,--...---,,,++**))((''&&%%$$##""!!!!!``!!""""##$$$%%&&''(())())**++,,---..//001122333221100///.//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443334455)))*****+++,,-,,,,---......------..//00///..//..//001122333332223221122333333334455566666778899::;;<<==>>>>>>>>>>>>>>==<<==>>???>>>>>>>>>>>>>>>>>>>>>========<<;;::99887766554433221100//..--,,++**))(((''&&%%&&'&&%%$$##""!!``````````````````````````````!!!"""""!!``!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$$$$%%$$##""!!``````````!!""!!!!!!!!!!!""""!!`````!!!!``!!""##$$%%&&''(())**++,,--.--,,,+++**))((''&&%%$$##""!!``!!``!!"""###$$$%%&&''(()))))**++,,---..//001122334332211000///00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544444556******++++,,---,,---........----..//00000////////001122334443323332222334444444455666676778899::;;<<==>>>>>>>>>>>>>?>>====>>?????>>>>>>????????????>>>>>>>>===<<;;::99887766554433221100//..--,,++**))(((''&&&&'''&&%%$$##""!!````!`!!!!!!!`````!!````!!!!!!!!!""""""!!``!``````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%$%%%%%%%%%$$##""!!`````!!!!!!!!!""!!`!```````!!!!!!`ņ`!!"!!``!!""##$$%%&&''(())**++,,----,,,+++**))((''&&%%$$##""!!``````!!""####$$%%%&&''(())**)**++,,--...//00112233444332211000/00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554445566***+++++,,,--.----...//////......//0011000//00//001122334444433343322334444444455666777778899::;;<<==>>??????????????>>==>>??????????????????????????>>>>>>>>==<<;;::99887766554433221100//..--,,++**)))((''&&''(''&&%%$$##""!!!!````!!!!!!!!!!!```!!!!!!!!!!!!"""#""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%%%%%&&%%$$##""!!``!!`!`!!!!!!!!!""!!```!!!!``!!"!!``!!""##$$%%&&''(())**++,,,-,,+++****))((''&&%%$$##""!!````!!!""###$$$%%%&&''(())*****++,,--...//00112233445443322111000112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655555667++++++,,,,--...--...////////....//0011111000000001122334455544344433334455555555667777878899::;;<<==>>????????????????>>>>?????????????????????????????????>>>==<<;;::99887766554433221100//..--,,++**)))((''''(((''&&%%$$##""!!!!!``!!!!`!`````!!!````!!!"""""""""##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&%&&&&&&&&&%%$$##""!!!!!!!!!"""""""""!!`@`````!!"!!``!!""##$$%%&&''(())**++,,,,,+++****))))((''&&%%$$##""!!``Á`!!!""##$$$$%%&&&''(())**++*++,,--..///00112233445554433221110112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665556677+++,,,,,---../....///000000//////0011221110011001122334455555444544334455555555667778888899::;;<<==>>??????????????????>>????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***))((''(()((''&&%%$$##""""!!!``!```````!!!``!!""""""""##"""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&&&&&&''&&%%$$##""!!""!"!""""""""!!!!``!!"!!`Í`!!""##$$%%&&''(())**++++,++***))))()((''&&%%$$##""!!!!``!!"""##$$$%%%&&&''(())**+++++,,--..///00112233445565544332221112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766666778,,,,,,----..///..///00000000////0011222221111111122334455666554555444455666666667788889899::;;<<==>>??????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***))(((()))((''&&%%$$##"""""!!``@```ψȆ`!!!``!!""######""!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''&'''''''''&&%%$$##""""""""""!!!!!!!!!!!````!!"!!``!!""##$$%%&&''(())**++++++***))))((((''&&%%$$##""!!`!``!!""##$$%%%%&&'''(())**++,,+,,--..//000112233445566655443322212233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776667788,,,-----...//0////00011111100000011223322211221122334455666665556554455666666667788899999::;;<<==>>????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++**))(())*))((''&&%%$$####"""!!!`@@@@͉`!!!````!!""#####""!!!``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''''''''((''&&%%$$##""##"""!!!!!!!!`````!!```!!"!!```````!!""##$$%%&&''(())*****+**)))(((('(''&&%%$$##""!!````!!""##$$%%%&&&'''(())**++,,,,,--..//000112233445566766554433322233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877777889------....//000//000111111110000112233333222222223344556677766566655556677777777889999:9::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++**))))***))((''&&%%$$#####""!!!``@@@Ɏ`!!!!!```````!!""##$##""!!```ď````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((('(((((((((''&&%%$$#####""!!!`````````````!!"!!`Í`!!!!!``!!""##$$%%&&''(())******)))((((''''&&&%%$$##""!!```!!""##$$%%&&&&''((())**++,,--,--..//001112233445566777665544333233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887778899---.....///0010000111222222111111223344333223322334455667777766676655667777777788999:::::;;<<==>>????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,++**))**+**))((''&&%%$$$$###"""!!!```Ɉ@@`!!!!!!!!!`!!!!""##$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((((((((())((''&&%%$$###""!!```!!"!!``!!!!!!``!!""##$$%%&&''(())*)))*))(((''''&'&&%%%$$##""!!!``!!!""##$$%%&&&'''((())**++,,-----..//001112233445566778776655444333445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998888899:......////001110011122222222111122334444433333333445566778887767776666778888888899::::;:;;<<==>>??????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,++****+++**))((''&&%%$$$$$##"""!!!!!``@@@@@@@ˍ`!!"""!!!!!!!!""##$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))())))))))((''&&%%$$##""!!``!!"""!!``!!"""!!``!!""##$$%%&&''(())))))))(((''''&&&&%%%$$##""!!!!!``!!!""##$$%%&&''''(()))**++,,--..-..//001122233445566778887766554443445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988899::.../////0001121111222333333222222334455444334433445566778888877787766778888888899:::;;;;;<<==>>????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,,++**++,++**))((''&&%%%%$$$###"""!!!!!`@@@@@@@Ϗ`!!"""""""!"""""##$##""!!`@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))))))))((''&&%%$$##""!!``!!""""!!``!!""""!!``!!""##$$%%&&''(()())((()(('''&&&&%&%%$$$##""!!`!!!!!!"""##$$%%&&'''((()))**++,,--.....//001122233445566778898877665554445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99999::;//////00001122211222333333332222334455555444444445566778899988788877778899999999::;;;;<;<<==>>??????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,,++++,,,++**))((''&&%%%%%$$###"""""!!`Ç@@@@@̎``!!""##"""""""!!""#####""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****)******))((''&&%%$$##""!!````!!""""!!``!!""#""!!!!""##$$%%&&''(()((((((((('''&&&&%%%%$$$##""!!``!!!!"""##$$%%&&''(((())***++,,--..//.//001122333445566778899988776655545566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::999::;;///0000011122322223334444443333334455665554455445566778899999888988778899999999::;;;<<<<<==>>????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...--,,++,,-,,++**))((''&&&&%%%$$$###"""!!`@@ʋ@`!!""######""!!!!!""###""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***********))((''&&%%$$##""!!!``!!""#""!!``!!""###""!!""##$$%%&&''(()(('(('''(''&&&%%%%$%$$###"""!!``!!""###$$%%&&''((()))***++,,--../////001122333445566778899:99887766655566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::;;<000000111122333223334444444433334455666665555555566778899:::998999888899::::::::;;<<<<=<==>>??????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...--,,,,---,,++**))((''&&&&&%%$$$###""!!`@@Lj`!!""####""!!!``!!"""""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++*++++++**))((''&&%%$$##""!!```!!""##""!!``!!""####""""##$$%%&&''(()(('''''''''&&&%%%%$$$$###""!!!```!!""##$$%%&&''(())))**+++,,--..//00/001122334445566778899:::998877666566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::;;<<00011111222334333344455555544444455667766655665566778899:::::999:998899::::::::;;<<<=====>>????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///..--,,--.--,,++**))((''''&&&%%%$$$##""!!`@@@@@Ɍ`!!""####""!!```!!"""""!!`ȋ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++++++++++**))((''&&%%$$##""!!```!!!""##""!!``!!""##$##""##$$%%&&''(()((''&''&&&'&&%%%$$$$#$##"""!!!```!!""##$$%%&&''(()))***+++,,--..//000001122334445566778899::;::9988777666778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;<<=1111112222334443344455555555444455667777766666666778899::;;;::9:::9999::;;;;;;;;<<====>=>>??????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///..----...--,,++**))(('''''&&%%%$$##""!!`@@@@@@ˋ`!!!""###""!!``!!!!""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,+,,,,,,++**))((''&&%%$$##""!!!```````!!!""###""!!``!!""##$####$$%%&&''(()((''&&&&&&&&&%%%$$$$####"""!!``!``!!!""##$$%%&&''(())****++,,,--..//001101122334455566778899::;;;::99887776778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;<<==111222223334454444555666666555555667788777667766778899::;;;;;:::;::99::;;;;;;;;<<===>>>>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000//..--../..--,,++**))(((('''&&%%$$##""!!`@@@@@@@@ȍ`!!!!!""""""!!```!!!!!!""!!``````````````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,,,,,,,++**))((''&&%%$$##""!!!!!!!``!!"""####""!!``!!""##$##$$%%&&''(((((''&&%&&%%%&%%$$$####"#""!!!``!!!!""##$$%%&&''(())***+++,,,--..//001111122334455566778899::;;<;;::998887778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<==>22222233334455544555666666665555667788888777777778899::;;<<<;;:;;;::::;;<<<<<<<<==>>>>?>??????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000//....///..--,,++**))(((((''&&%%$$##""!!`@@@@̋@@@@Ώ`!!``!!"""""!!``!!!!```!!""!!!!!!!!!!!!!!!!`@@``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..----,-,,++,+++***))((''&&%%$$##"""!!!!!```!!""##$##""!!``!!""##$$$%%&&''(((((''&&%%%%%%%%%$$$####""""!!!``!!"""##$$%%&&''(())**++++,,---..//001122122334455666778899::;;<<<;;::9988878899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<==>>2223333344455655556667777776666667788998887788778899::;;<<<<<;;;<;;::;;<<<<<<<<==>>>???????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211100//..//0//..--,,++**))))((''&&%%$$##""!!`@@@̏@@@͌```!!!!!!!!``!!!``!!""!!!!!!!!!!!!!!!`@````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..----,,+++++******))((''&&%%$$##""""""!!``!```!!""##$$##""!!```!!""##$$%%&&'''(''''&&%%$%%$$$%$$###""""!"!!```!!"""##$$%%&&''(())**+++,,,---..//001122222334455666778899::;;<<=<<;;::99988899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=====>>?333333444455666556667777777766667788999998888888899::;;<<===<<;<<<;;;;<<========>>??????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211100////000//..--,,++**))))((''&&%%$$##""!!`@@@@@@@ʋ@@@@ɉ`!``!!!!!!!!!``!!!``!!"""""""""""""""!!``!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**+***)))**))((''&&%%$$###"""""!!!!!`@@@@@@@``!!""##$$$##""!!``!!""##$$%%&&''''''&&%%$$$$$$$$$###""""!!!!``!!""###$$%%&&''(())**++,,,,--...//001122332334455667778899::;;<<===<<;;::999899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===>>??3334444455566766667778888887777778899::99988998899::;;<<=====<<<=<<;;<<========>>????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332221100//00100//..--,,++***))((''&&%%$$##""!!`@@@@@̏@@@@@@@@@@@@@͎```````````!!!``!!""""""""""""""!!``!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*****))))))))))((''&&%%$$######""!!!!````@@@@@@@@`!!""##$$$##""!!``!!""##$$%%&&&&'&&&&%%$$#$$###$##"""!!!!`!!``!!""###$$%%&&''(())**++,,,---...//001122333334455667778899::;;<<==>==<<;;:::999::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>???444444555566777667778888888877778899:::::99999999::;;<<==>>>==<===<<<<==>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322211000011100//..--,,++**))((''&&%%$$##""!!`ѐ@@@@@ɋ`!!``!!!""###########""!!````````!!!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))*)))((())))))((''&&%%$$$#####""""!!```````@@@`!!""##$$$$##""!!``!!""##$$%%&&&&&&&&%%$$#########"""!!!!``!!```!!""##$$$%%&&''(())**++,,----..///001122334434455667788899::;;<<==>>>==<<;;:::9::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>????44455555666778777788899999988888899::;;:::99::99::;;<<==>>>>>===>==<<==>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544333221100111100//..--,,++**))((''&&%%$$##""!!`@@@ʊ````!!""###########""!!!!!!!!!!""!!!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))((((((((((((((''&&%%$$$$$$##""""!!!`````````!`!!!`@@@@@`!!""##$$$$##""!!`````!!""##$$%%&&%%&%%%%$$##"##"""#""!!!````!!!!!!""##$$$%%&&''(())**++,,---...///001122334444455667788899::;;<<==>>?>>==<<;;;:::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????5555556666778887788899999999888899::;;;;;::::::::;;<<==>>???>>=>>>====>>????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433322111121100//..--,,++**))((''&&%%$$##""!!`ɉ@`!!""##$$$$$$$##""!!!!!!!!""""!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(()((('''((((((((((''&&%%%$$$$$####""!!!```!!```!!!!!!!!!!`@@`!!""##$$%$$##""!!``!!``!!""##$$%%%%%%%%%$$##"""""""""!!!```!!"!!!""##$$%%%&&''(())**++,,--....//0001122334455455667788999::;;<<==>>???>>==<<;;;:;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????555666667778898888999::::::999999::;;<<;;;::;;::;;<<==>>?????>>>?>>==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554443322112221100//..--,,++**))((''&&%%$$##""!!`ɉɉ@@@`!!""##$$$$$$$##""""""""""##""""!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((((''''''''''''''''''&&%%%%%%$$####"""!!``!!!``!!!!!!"!!"!!`@@@`!!""##$$$$##""!!!!`Å`!!!``!!""##$$%%%%$$%$$$$##""!""!!!"!!``Á`!!""""""##$$%%%&&''(())**++,,--...///0001122334455555667788999::;;<<==>>?????>>==<<<;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????66666677778899988999::::::::9999::;;<<<<<;;;;;;;;<<==>>???????>???>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444332222221100//..--,,++**))((''&&%%$$##""!!`@@@ɉˊ@@@`!!""##$$%%%%$$##""""""""####"""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''('''&&&''''''''''''''&&&%%%%%$$$$##""!!``!!!!`````!!!!!!!!!!!!!`@@`!!""##$$$$##""!!!!!``!!!``!!""##$$$%%$$$$$$$##""!!!!!!!!!```!!""#"""##$$%%&&&''(())**++,,--..////001112233445566566778899:::;;<<==>>???????>>==<<<;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????6667777788899:9999:::;;;;;;::::::;;<<==<<<;;<<;;<<==>>?????????????>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665554433223221100//..--,,++**))((''&&%%$$##""!!`@@@ɉ@@ɉ`!!""##$$%%%%%%$$##########$$####"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''''&&&&&&&&&&&&&&&&&&&&&&&&&&%%$$$$##""!!``!!""!!!!!`````!!`!```!!`!!`@@@`!!""##$$$$##""!!``!!```!!"!!``!!""##$$$$$$$##$####""!!`!!```!``!!!""######$$%%&&&''(())**++,,--..///0001112233445566666778899:::;;<<==>>?????????>>===<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????777777888899:::99:::;;;;;;;;::::;;<<=====<<<<<<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766555443333221100//..--,,++**))((''&&%%$$##""!!`@@@@@@@@@@@@@@@@@ɉ``!!""##$$%%&&&&%%$$########$$$$#########$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&'&&&%%%&&&&&&&&&&&&&&&&&&&&&&%%%$$##""!!```!!""""!!!!````````@@@@@`!!""##$$$$##""!!`````!!""!!!!""##$$$$#$$#######""!!``````!!!""##$###$$%%&&'''(())**++,,--..//00001122233445566776778899::;;;<<==>>???????????>>===<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????77788888999::;::::;;;<<<<<<;;;;;;<<==>>===<<==<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776665544333221100//..--,,++**))((''&&%%$$##""!!`@@@@@@@@@@@@@ɉ````!!!""##$$%%&&&&&&%%$$$$$$$$$$%%$$$$#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&%%%%%%%%%%%%%%%%%%%%&&&&%%%%%%$$##""!!`````!!!""##"""!!``@@@@@@@@`!!""##$$%$$##""!!````!!""!!""##$$$$#####""#""""!!```!```!!"""##$$$$$$%%&&'''(())**++,,--..//00011122233445566777778899::;;;<<==>>?????????????>>>===>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????8888889999::;;;::;;;<<<<<<<<;;;;<<==>>>>>========>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877666554433221100//..--,,++**))((''&&%%$$##""!!`@@ʋ@@@@@ɉ@@`!!!!!""##$$%%&&''''&&%%$$$$$$$$%%%%$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%&%%%$$$%%%%%%%%%%%%%%%%%%%%%%%%%$$##""!!```!!``!!""####""!!``@@`!!""##$$%%$$##""!!``!!""""####$$##"##"""""""!!``!!!!!"""##$$%$$$%%&&''((())**++,,--..//00111122333445566778878899::;;<<<==>>???????????????>>>=>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????88899999:::;;<;;;;<<<======<<<<<<==>>??>>>==>>==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ŏ@@@Ɋ@@ɉ@@ɉ@@@`!!!"""##$$%%&&''''''&&%%%%%%%%%%&&%%%%$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%$$$$$$$$$$$$$$$$$$$$%%%%$$$$%%$$##""!!``!!``!!""##$##""!!````@@@``!!""##$$%%%$$##""!!``!!""""######"""""!!"!!!!````!!!!!""###$$%%%%%%&&''((())**++,,--..//00111222333445566778888899::;;<<<==>>??????????????????>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????999999::::;;<<<;;<<<========<<<<==>>?????>>>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@ʉ@@ɉ@@ɉ```````!!""""##$$%%&&''((((''&&%%%%%%%%&&&&%%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$%$$$###$$$$$$$$$$$$$$$$$$$$$$$$$$$##""!!``!!!``!!""##$$$##""!!!!````@@`!!!""##$$%%&%%$$##""!!````!!""""""##""!""!!!!!!!``!!!!"""""###$$%%&%%%&&''(()))**++,,--..//00112222334445566778899899::;;<<===>>????????????????????>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????999:::::;;;<<=<<<<===>>>>>>======>>???????>>??>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@ˋ@@ɉ@ɉ``````!!!!!"""###$$%%&&''((((((''&&&&&&&&&&''&&&&%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$####################$$$$####$$$$##""!!``!!!!``!!""##$$$$##""!!!!``````!``@@@@@@`!!!""##$$%%&&&%%$$##""!!`!```!!!!""""""!!!!!``!`````!!!!"""""##$$$%%&&&&&&''(()))**++,,--..//00112223334445566778899999::;;<<===>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????::::::;;;;<<===<<===>>>>>>>>====>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@ˋ@@ɉ̊```````!!!!!!""####$$%%&&''(())))((''&&&&&&&&''''&&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##$###"""#############################""!!``!!""!!`````!!""##$$%%$$##"""!!``````!!`!!!!!!`@@@@@`!!"""##$$%%&&'&&%%$$##""!!!`Ċ`!!!!!!""!!`!!`````!!!""""#####$$$%%&&'&&&''(())***++,,--..//00112233334455566778899::9::;;<<==>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????:::;;;;;<<<==>====>>>??????>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@ˌ@@ɉ`````````!!!!!!!"""""###$$$%%&&''(())))))((''''''''''((''''&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####""""""""""""""""""""####""""######""!!``!!!""!!!``!!!!""##$$%%%%$$##""!!``!!!!!!!!!!"!!!````@@@`!!""##$$%%&&''&&%%$$###""!!`Î```!!!!!!`````!!!!""""#####$$%%%&&''''''(())***++,,--..//00112233344455566778899:::::;;<<==>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????;;;;;;<<<<==>>>==>>>????????>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ċ@@ˊ@@@ɉ`!!!!!`````!!!!!!!!""""""##$$$$%%&&''(())****))((''''''''(((('''''''''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""#"""!!!""""""""""""""""""""""""""""""!!``!!!""!!!``!!!!""##$$%%&&%%$$##""!!```!!!!!""!""""""!!!!`€@@``!!""##$$%%&&''&&%%$$##"""!!````!!````!!!"""####$$$$$%%%&&''('''(())**+++,,--..//00112233444455666778899::;;:;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????;;;<<<<<===>>?>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ň@@ʋ@@@@Ɋ```!!!!!!``!!!!!!"""""""#####$$$%%%&&''(())******))(((((((((())(((('''''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""!!!!!!!!!!!!!!!!!!!!""""!!!!"""""""!!````````!!!""!!``!!"""##$$%%&&&&%%$$##""!!````!!!""""""""""#"""!!!!````@@@@`!!!""##$$%%&&''&&%%$$##"""""!!`Č``````!!!""""####$$$$$%%&&&''(((((())**+++,,--..//00112233444555666778899::;;;;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????<<<<<<====>>???>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ê@@ʋ@@@@ɊƆ`!!!!""""!!```!!!!""""""""######$$%%%%&&''(())**++++**))(((((((())))((((((((())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!"!!!```!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``!!!!```!!!""!!``!!""##$$%%&&''&&%%$$##""!!!!!!!"""""##"######""""!!!!!`@@`!!!""##$$%%&&''&&%%$$##""!!"!!`@`````!!""###$$$$%%%%%&&&''(()((())**++,,,--..//00112233445555667778899::;;<<;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????<<<=====>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@ˋ@@@@@Ɋ@@@@@@Ɔ````!!!!"""""!!``!!!""""""#######$$$$$%%%&&&''(())**++++++**))))))))))**))))((((())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!`````````````````!!!!````!!!!!!!!!``!!!!!!````!!""!!``!!""##$$%%&&'''&&%%$$##""!!!!"""##########$###""""!!!!!`@@`!!""##$$%%&&''&&%%$$##""!!!!!`ǎ@`````!!""##$$$$%%%%%&&'''(())))))**++,,,--..//00112233445556667778899::;;<<<<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????======>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@ˊˋ@@ʌ@@@@@@@@Ɔ```!!!!!""""##""!!```!!!""""########$$$$$$%%&&&&''(())**++,,,,++**))))))))****)))))))))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!`Œ`````````````````!!"""!!!!``!!""!!````!!""##$$%%&&''&&&&%%$$##"""""""#####$$#$$$$$$####"""""!!``@@`!!""##$$%%&&''&&%%$$##""!!``!!`Ƈ```!!""##$$%%%%&&&&&'''(())*)))**++,,---..//00112233445566667788899::;;<<==<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????===>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@Ɋ@@@ʌ@@Ɔ```!!!!!!!""""####""!!```!!!"""######$$$$$$$%%%%%&&&'''(())**++,,,,,,++**********++****)))))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``Ā``!!!!!""""!!!!``!!""!!!!```!!""##$$%%&&'&&&%%%%%$$##""""###$$$$$$$$$$%$$$####"""""!!!`@@`!!""##$$%%&&''&&%%$$##""!!````ĉ@```!!""##$$%%%%&&&&&''((())******++,,---..//00112233445566677788899::;;<<=====>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@ɉ@@ʋ@@@@@@@@Lj`!!!!!"""""####$$##""!!!```!!!"""####$$$$$$$$%%%%%%&&''''(())**++,,----,,++********++++*********++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```‡`!!!!!!""""!!!````!!"""!!!!!``!!""##$$%%&&&&&%%%%$$$$$$#######$###$$%$%%%%%%$$$$#####""!!!`@@``!!""##$$%%&&''&&%%$$##""!!```!!!!""##$$%%&&&&'''''((())**+***++,,--...//00112233445566777788999::;;<<==>>=>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʼn@@ɉʊ@@@@@@@@ȇ`!!!"""""""####$$$$##""!!!`!!!"""###$$$$$$%%%%%%%&&&&&'''((())**++,,------,,++++++++++,,++++*****++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!``````Ā``!!!""""""!!!`````!!"""""!!````!!""##$$%%&&&&&%%%$$$$$###############$$$$%%%%%%$$$$#####"""!!``@@`!!!""##$$%%&&'''&&%%$$##""!!``!!!!!""##$$%%&&&&'''''(()))**++++++,,--...//00112233445566777888999::;;<<==>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@ɉʇ`!!"""""#####$$$$%%$$##"""!!!!"""###$$$$%%%%%%%%&&&&&&''(((())**++,,--....--,,++++++++,,,,+++++++++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!!!!!``!!"""""""!!!````!!""""!!``!!!""##$$%%%%%%%%%$$$$##############"""##$$$$%$$%%%%%$$$$$##"""!!`@@@@Å``!!!""##$$%%&&'''&&%%$$##""!!!```!!!""""##$$%%&&''''((((()))**++,+++,,--..///0011223344556677888899:::;;<<==>>??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@Ɋɉ`!!""#######$$$$%%%%$$##"""!"""###$$$%%%%%%&&&&&&&'''''((()))**++,,--......--,,,,,,,,,,--,,,,+++++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""!!!!!!!`````!!"""##""!!``````!!"""""!!````!!""##$$%%%$%%%%%$$$#####"""""""""""""""####$$$$$$%%%%$$$$$###""!!````@@@````!!!"""##$$%%&&'''&&%%$$##""!!````!!!"""""##$$%%&&''''((((())***++,,,,,,--..///0011223344556677888999:::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@ʊ@Ȉ`!!""###$$$$$%%%%&&%%$$###""""###$$$%%%%&&&&&&&&''''''(())))**++,,--..////..--,,,,,,,,----,,,,,,,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""""""!!!!``!!!""###""!!`ʌ```!!!""""!!`!```!!""##$$$$$$$$$$$$####""""""""""""""!!!""####$##$$$$$%%%%%$$###""!!!!!``@@@@ň`!`!```````!!!!"""##$$%%&&'''&&%%$$##""!!```````!!!!"""####$$%%&&''(((()))))***++,,-,,,--..//00011223344556677889999::;;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɍ@@@ʊ@@@@@@Ȉ`!!!""##$$$$%%%%&&&&%%$$###"###$$$%%%&&&&&&'''''''((((()))***++,,--..//////..----------..----,,,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""""""!!!!!!!""###""!!```@```!!!!!!!!!!!```!`````!!""##$$$$$$#$$$$$###"""""!!!!!!!!!!!!!!!""""######$$$$$$$$$$$$##""!!!!!!`@@`!!!!!!````!!!!!!"""###$$%%&&'''&&%%$$##""!!````!!!!!!!!"""#####$$%%&&''(((()))))**+++,,------..//0001122334455667788999:::;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̏@@ʊ@@@@@@@@@@ˎ`!``!!""##$$%%&&&&''&&%%$$$####$$$%%%&&&&''''''''(((((())****++,,--..//0000//..--------....---------..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""#####""""!!"""###""!!``!`````!!!!!!!!!!!!!!!!!```!!""##$############""""!!!!!!!!!!!!!!```!!""""#""#####$$$$$$$#####"""""!!`@@È``!!!"!!!!!!!!!!!""""###$$%%&&'''&&%%$$##""!!`@`````!!!!!!!""""###$$$$%%&&''(())))*****+++,,--.---..//001112233445566778899::::;;<<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@@@@Ɋ@@@@@@ϑ``!!""##$$%%&&''''&&%%$$$#$$$%%%&&&''''''((((((()))))***+++,,--..//000000//..........//....-----..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""######"""""""####""!!``!!``!!```````````!!!!!"!!!!!!```!!""#######"#####"""!!!!!````````````!!!!""""""################""""!!`@@`!!!""""""!!!!""""""###$$$%%&&''''&&%%$$##""!!```!!!!``!!""""""""###$$$$$%%&&''(())))*****++,,,--......//001112233445566778899:::;;;<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɋ@@@@@@͑`!!""##$$%%&&''''&&%%%$$$$%%%&&&''''(((((((())))))**++++,,--..//00111100//........////.........//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$####""###$$##""!!``!!!!!!!!!``!!"""""""!!!!``!!""#""""""""""""!!!!````!!!!!"!!"""""#######"""#####"""!!`@@@@@@@```!!!"""#"""""""""""####$$$%%&&''(''&&%%$$##""!!```!!!!!!``!!""""""####$$$%%%%&&''(())****+++++,,,--../...//001122233445566778899::;;;;<<===>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@ʌ`!!""##$$%%&&''(''&&%%%$%%%&&&'''(((((()))))))*****+++,,,--..//0011111100//////////00////.....//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$#######$$$##""!!``!!!!""!!!!``!!""""""""!!!``!!!"""""""!"""""!!!``ɑ````!!!!!!""""""""""""""""""""!!!`@@@@Ȍ`!!!!"""######""""######$$$%%%&&''(((''&&%%$$##""!!``!`ċ`!!""!!````!!""#######$$$%%%%%&&''(())****+++++,,---..//////001122233445566778899::;;;<<<===>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@@@@@@@@@ˏ`!!""##$$%%&&''((''&&&%%%%&&&'''(((())))))))******++,,,,--..//001122221100////////0000/////////00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%$$$$##$$$$$##""!!``!!""""""""!!```!!!!""""#""""!!``!!!"!!!!!!!!!!!!```!``!!!!!"""""""!!!"""""!!!!``ř@@@@nj`!!!!"""###$###########$$$$%%%&&''(((''&&%%$$##""!!````!!"""!!!!`!!""######$$$$%%%&&&&''(())**++++,,,,,---..//0///001122333445566778899::;;<<<<==>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@@͏@`!!""##$$%%&&''(((''&&&%&&&'''((())))))*******+++++,,,---..//0011222222110000000000110000/////00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%%%%$$$$$$$%$$##""!!!``!!"""##""""!!!``!!!!!"""##""!!```!!!!!!!`!!!!!`Ä```!!!!!!!!!!!!!!!!!!!!``ˏ@@@@`!!"""###$$$$$$####$$$$$$%%%&&&''(((''&&%%$$##""!!```````!!"""!!!!!""##$$$$$$$%%%&&&&&''(())**++++,,,,,--...//0000001122333445566778899::;;<<<===>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʊ`!!""##$$%%&&''(((('''&&&&'''((())))********++++++,,----..//00112233332211000000001111000000000112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!""##$$$%%&&%%%%$$%%$$##""!!`!!````!!!""######""!!!````!!!!"""""!!``!`````````````!!!!!!!```!!!!!``ĉ@@@@†`!!""###$$$%$$$$$$$$$$$%%%%&&&''(()((''&&%%$$##""!!````````!!"""""!""##$$$$$$%%%%&&&''''(())**++,,,,-----...//0010001122334445566778899::;;<<====>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ȑ`````!!""##$$%%&&''(()(('''&'''((()))******+++++++,,,,,---...//00112233333322111111111122111100000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!""#####$$%%&&%%%%%%$$##""!!``!````!!""######"""!!````!!!""""!!```````````````ƍ@@@@`!!""##$$%%%%%%$$$$%%%%%%&&&'''(()))((''&&%%$$##""!!!!!``````!!"""""""##$$%%%%%%%&&&'''''(())**++,,,,-----..///0011111122334445566778899::;;<<===>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ï`!!``!```!!""##$$%%&&''(()))(((''''((()))****++++++++,,,,,,--....//00112233444433221111111122221111111112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!"""#######$$%%&&&&%%%$$##""!!```ˏ`!!""##$$##"""!!!```````!!!""!!```NjϐɎ@@@@`!!""##$$%%&%%%%%%%%%%%&&&&'''(())*))((''&&%%$$##""!!!!!``!!""###"##$$%%%%%%&&&&'''(((())**++,,----.....///0011211122334455566778899::;;<<==>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!!!!!!""##$$%%&&''(())*))((('((()))***++++++,,,,,,,-----...///00112233444444332222222222332222111112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!"""""##""""##$$%%&&&&%%$$##""!!`ȋ`!!""##$$$###""!!!!!!``!!!!!````!`@@@@@@@@`!!""##$$%%&&&&%%%%&&&&&&'''((())***))((''&&%%$$##"""!!```!!""#####$$%%&&&&&&&'''((((())**++,,----.....//00011222222334455566778899::;;<<==>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````!!!""!!"!!!""##$$%%&&''(())***)))(((()))***++++,,,,,,,,------..////00112233445555443322222222333322222222233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!"""""""""""""##$$%%&&%%$$##""!!``!!""##$$$###"""!!!!```!!!``````!!```@@@@@``````!!""##$$%%&&&&&&&&&&&&&''''((())****))((''&&%%$$##""!!`̏`!!""##$#$$%%&&&&&&''''((())))**++,,--..../////00011223222334455666778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!!!""""""""""##$$%%&&''(())**+**)))()))***+++,,,,,,-------.....///000112233445555554433333333334433332222233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""""""""!""!!!!""##$$%%&%%$$##""!!``!!""##$$$$$##"""""!!```!!`@`!``````````ƍ@@ʈ`!!!!```!!!""##$$%%&&''''&&&&''''''((()))****))((''&&%%$$##""!!``!!""##$$%%&&'''''''((()))))**++,,--..../////00111223333334455666778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````!!!!!!!"""##""#"""##$$%%&&''(())**+++***))))***+++,,,,--------......//0000112233445566665544333333334444333333333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!"""""""!!!!!!!!!!!""##$$%%&%%$$##""!!``!!""##$$%$$$###""""!!!````‹`!````!!``!``````````@@`!!!!!``!!!""##$$%%&&'''''''''''''(((()))**++**))((''&&%%$$##""!!``!!""##$$%%&&''''(((()))****++,,--..////00000111223343334455667778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!"""""""##########$$%%&&''(())**++,++***)***+++,,,------......./////0001112233445566666655444444444455444433333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877666554433221100//..--,,++**))((''&&%%$$##""!!``!!!"""#""!!!!!`!!````!!""##$$%%&%%$$##""!!``!!""##$$%%%$$#####""!!!!!````!!``!!```!!!```Æ@@@@@`!!!!```!!"""##$$%%&&''((((''''(((((()))***++**))(((''&&%%$$##""!!``!!""##$$%%&&''(((()))*****++,,--..////00000112223344444455667778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!"""""""###$$##$###$$%%&&''(())**++,,,+++****+++,,,----........//////0011112233445566777766554444444455554444444445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776666554433221100//..--,,++**))((''&&%%$$##""!!``!!!""""""!!!``````!!""##$$%%%$$##""!!``!!""##$$%%%%%$$$####"""!!!!``!!````!!!````!``!``ы@@`!!!```!!!"""##$$%%&&''((((((((((((())))***++**))(('''&&%%$$##""!!``!!""##$$%%&&''(()))***++++,,--..//0000111112223344544455667788899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""#######$$$$$$$$$$%%&&''(())**++,,-,,+++*+++,,,---......///////0000011122233445566777777665555555555665555444445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766555554433221100//..--,,++**))((''&&%%$$##""!!``!!"""""""!!`````!!""##$$%%%$$##""!!``!!""##$$%%&%%%$$$####"""""!!``ɔ`!!!!``!!!!``!```!!```@@@@@```!!!```!!!""###$$%%&&''(())))(((())))))***+++**))((''''&&%%$$##""!!``!!""##$$%%&&''(())**+++++,,--..//0000111112233344555555667788899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""#######$$$%%$$%$$$%%&&''(())**++,,---,,,++++,,,---....////////00000011222233445566778888776655555555666655555555566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766555554433221100//..--,,++**))((''&&%%$$##""!!``!!"""""!!!!`````!!""##$$%%&%%$$##""!!``!!""##$$%%%%%%$$#######""""!!```Ɨ`!!!!````!!!!``!````!!!``!!`@@``!!!!!!``````!!!"""###$$%%&&''(()))))))))))))****+++**))((''&&&'&&%%$$##""!!``!!""##$$%%&&''(())**++,,,,--..//0011112222233344556555667788999::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$$$%%%%%%%%%%&&''(())**++,,--.--,,,+,,,---...//////000000011111222333445566778888887766666666667766665555566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554444433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!!!!``!!!!""##$$%%&%%$$##""!!``!!""##$$%%%$%$$##""#######""!!!``!!!!!!!!""!!``!!!``!!``!!`@@`!!!!!!!````!!````!!!!!"""##$$$%%&&&&''(())**)))))*****++++**))((''&&&&&&%%$$###""!!``!!""##$$%%&&''(())**++,,,--..//0011112222233444556666667788999::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$$%%%&&%%&%%%&&''(())**++,,--...---,,,,---...////00000000111111223333445566778899998877666666667777666666666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544444333221100//..--,,++**))((''&&%%$$##""!!``!!"""!!``!!!``!!!!""##$$%%&&%%$$##""!!``!!""##$$%%$$$$##""""##$####""!!!``!!!!!!""""!!`````!``!!`@@@`!!"""!!```!!!!!!````!!!"""###$$$%%&&%%&&''(())***))))**+++++**))((''&&%%%&%%$$###""!!``!!""##$$%%&&''(())**++,,--..//001122223333344455667666778899:::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%%%%&&&&&&&&&&''(())**++,,--../..---,---...///0000001111111222223334445566778899999988777777777788777766666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443333322221100//..--,,++**))((''&&%%$$##""!!``!!!"!!``!!!```!!""""##$$%%&&&%%$$##""!!``!!""##$$%$$#$##""!!""#####""!!!!``!!"""""##""!!```!`!!!`@@@@`!!"""""!!````!!""!!!``!``!!!""##$$%%%&&%%%%&&''(())*))(())**+++**))((''&&%%%%%%$$##"#""!!``!!""##$$%%&&''(())**++,,--..//00112223333344555667777778899:::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%%%&&&''&&'&&&''(())**++,,--..///...----...///0000111111112222223344445566778899::::99887777777788887777777778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433333222221100//..--,,++**))((''&&%%$$##""!!`ŋ```!!!``!!!!``!!""""##$$%%&&&&%%$$##""!!``!!""##$$$$####""!!!!""###""!!`!!`Ä`!!""""###""!!`@`!!!!`@@@`!!""#""!!```!!"""!!!```!!""##$$%%&%%$$%%&&''(()))(((())*****))((''&&%%$$$%$$##"""""!!``!!""##$$%%&&''(())**++,,--..//00112233344444555667787778899::;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&&&&''''''''''(())**++,,--..//0//...-...///00011111122222223333344455566778899::::::998888888888998888777778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433222221121100//..--,,++**))((''&&%%$$##""!!``!!``!!"!!``!!""####$$%%&&&&&%%%$$##""!!`````!!""##$$$$##"#""!!``!!"""""!!``!``‹`!!""###$##""!!```@@@`!!!``@@@```!!""#""!!`````!``!!"""!!```!!""##$$%%%$$$$%%&&''(()((''(())***))((''&&%%$$$$$$##""!"""!!``!!""##$$%%&&''(())**++,,--..//00112233344444556667788888899::;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&&&'''((''('''(())**++,,--..//000///....///00011112222222233333344555566778899::;;;;::9988888888999988888888899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332222211111100//..--,,++**))((''&&%%$$##""!!`€`!!``!!""!!!!""####$$%%&&&&%%%%%%$$##""!!````!!!!!""##$$$$##""""!!``!!"""!!```````!!""###$$$##""!!!`Ā`!!`@@@`!```!!!""##""!!```!!!!!!`!!"""!!``!!""##$$%$$##$$%%&&''(((''''(()))))((''&&%%$$###$##""!!!"!!``!!""##$$%%&&''(())**++,,--..//00112233444555556667788988899::;;<<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''''''(((((((((())**++,,--..//00100///.///000111222222333333344444555666778899::;;;;;;::9999999999::99998888899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221111100111100//..--,,++**))((''&&%%$$##""!!```!!!``!!"""!!""##$$$$%%%%&%%%%$$$%%$$##""!!!!!!!!!""##$$$$##""!""!!!``!!!!!!!``````!!!!""##$$$$$##""!!`````!!`@@``!!`!!!""###""!!`````!!!!!!"!!!""""!!``!!""##$$$$####$$%%&&''(''&&''(()))((''&&%%$$######""!!`!!!``!!""##$$%%&&''(())**++,,--..//0011223344555556677788999999::;;<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''''((())(()((())**++,,--..//00111000////000111222233333333444444556666778899::;;<<<<;;::99999999::::999999999::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111110000111100//..--,,++**))((''&&%%$$##""!!```!!"!!```!!""#""""##$$$$$$$%%%%%$$$$$$$$$$##""!!!!"""""##$$$$##""!!!!!`````!!!!!!````!!!""##$$$$$##""!!`ŀ``!!!!``@@`````!!""#""!!``!!!!!""""""!""#""!!``!!""##$$##""##$$%%&&'''&&&&''(((((''&&%%$$##"""#""!!``!!``!!""##$$%%&&''(())**++,,--..//00112233445566667778899:999::;;<<===>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((((())))))))))**++,,--..//0011211000/0001112223333334444444555556667778899::;;<<<<<<;;::::::::::;;::::99999::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100000//00111100//..--,,++**))((''&&%%$$##""!!```!!!"""!!!!!""###""##$$$$$$$$$$%$$$$###$$###$##""""""""""###$$##""!!`!!````````````!!""##$$%%$$##""!!`@``!!!`@@`!!"""!!``!!!""""""""""#""!!``!!""##$##""""##$$%%&&'&&%%&&''(((''&&%%$$##""""""!!``!```!!""##$$%%&&''(())**++,,--..//0011223344556667788899::::::;;<<===>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((()))**))*)))**++,,--..//001122211100001112223333444444445555556677778899::;;<<====<<;;::::::::;;;;:::::::::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100000////0011100//..--,,++**))((''&&%%$$##""!!``!!!""#""!!!""##$####$$#######$$$$$##############"""""""""""####""!!```͓Ă`!!""##$$%%%$$##""!!`@`!!``@@``!!"!!``!!!!!!!!!!"""##""!!``!!""###""!!""##$$%%&&&%%%%&&'''''&&%%$$##""!!!""!!`ą````!!""##$$%%&&''(())**++,,--..//0011223344556677788899::;:::;;<<==>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()))**********++,,--..//001122322111011122233344444455555556666677788899::;;<<======<<;;;;;;;;;;<<;;;;:::::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////..//0011100//..--,,++**))((''&&%%$$##""!!``!!"""###"""""####$##############$####"""##"""######"""!!!!"""##"""!!```!!""##$$%%&%%$$##""!!```!!!`````@@@`!!!!````!!!!!!!!""##""!!``!!""#""!!!!""##$$%%&%%$$%%&&'''&&%%$$##""!!!!!!!`@`!!!""##$$%%&&''(())**++,,--..//0011223344556677788999::;;;;;;<<==>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())***++**+***++,,--..//001122333222111122233344445555555566666677888899::;;<<==>>>>==<<;;;;;;;;<<<<;;;;;;;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////....//001100//..--,,++**))((''&&%%$$##""!!``!!""##$##"""###########"""""""#####"""""""""""""""""!!!!!!!!"""""""!!``````!!""##$$%%&&&%%$$##""!!```!``@@`!!`````````!!""#""!!``!!"""!!``!!""##$$%%%$$$$%%&&&&&%%$$##""!!```!!!```!!""##$$%%&&''(())**++,,--..//0011223344556677888999::;;<;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())***++++++++++,,--..//001122334332221222333444555555666666677777888999::;;<<==>>>>>>==<<<<<<<<<<==<<<<;;;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.....--..//00100//..--,,++**))((''&&%%$$##""!!``!!""#########""""#""""""""""""""#""""!!!""!!!""""""!!!````!!!""!!"""!!``!`!!!""##$$%%&&&&%%$$##""!!```@@@@@@@`!``!!""#""!!```````!!""!!``!!""##$$%$$##$$%%&&&%%$$##""!!``!!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899:::;;<<<<<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,++,+++,,--..//001122334443332222333444555566666666777777889999::;;<<==>>????>>==<<<<<<<<====<<<<<<<<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.....----..//000//..--,,++**))((''&&%%$$##""!!````!!""####""""""""""""""""!!!!!!!"""""!!!!!!!!!!!!!!!!!````!!!!!!"""!!````!!!!""##$$%%&&''&&%%$$##""!!```````@`!`@@@@`!``!!""##""!!!!!```!``!!"!!``!!""##$$$$####$$%%%%%$$##""!!`Ā`!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,,,,,,,,,--..//00112233445443332333444555666666777777788888999:::;;<<==>>??????>>==========>>====<<<<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-----,,--..//00//..--,,++**))((''&&%%$$##""!!``!`!!!""####"""""""!!!!"!!!!!!!!!!!!!!"!!!!```!!```!!!!!!``!!``!!"!!!!!!```!!"""##$$%%&&''''&&%%$$##""!!!!!``!!`@`!`@@``!!""###""!!!!!!!`@`!!""!!``!!""##$$$$##""##$$%%%$$##""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=====>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--,,-,,,--..//0011223344555444333344455566667777777788888899::::;;<<==>>????????>>========>>>>=========>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-----,,,,--..//0//..--,,++**))((''&&%%$$##""!!``!!!!!""###"""!!!!!!!!!!!!!!!!```````!!!!!``````````````!!!!!!!!!!```!!""##$$%%&&''((''&&%%$$##""!!!!```!!!``!``@@`!!""####"""""!!!``!!""!!!!""##$$$$##""""##$$$$$$##""!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<====>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,---------..//0011223344556554443444555666777777888888899999:::;;;<<==>>??????????>>>>>>>>>>??>>>>=====>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,++,,--..////..--,,++**))((''&&%%$$##""!!``````!!!"""##""""!!!!!!!````!```````!``nj`!!``!!""!!!!``!!""##$$%%&&''(((''&&%%$$##"""!!`@`!!``!!`@@@@@@@@@@`!!""##$##"""""!!``!!"""!!""##$$$$##""!!""##$$$$####""!!``֖`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,----.---..//0011223344556665554444555666777788888888999999::;;;;<<==>>????????????>>>>>>>>????>>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,++++,,--..////..--,,++**))((''&&%%$$##""!!````````!!!!```!!"""""""""!!!```````Ŋ`͎`!``!!"""!!!````!!""##$$%%&&''((((''&&%%$$##"""!!```!!!```!`@@@@@@@@ō`!!""##$$$####""!!``!!""""""##$$$$##""!!!!""########""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--.......//0011223344556676655545556667778888889999999:::::;;;<<<==>>????????????????????????????>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++++**++,,--..////..--,,++**))((''&&%%$$##""!!!!!!!!!!!!!!```````````!!""""""""!!!!`ϗ`!!!``!!""""""!!!!````!!""##$$%%&&''(()((''&&%%$$###""!!````!!!`````````````ƒ``````!!""##$$%$$###""!!``!!""#""##$$$$##""!!``!!""####""""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--.....//001122334455667776665555666777888899999999::::::;;<<<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++++****++,,--..////..--,,++**))((''&&%%$$##""!!!!!!!!""""!!``!!!!`!!!``!!!!""""""!!!!!```!!!!!!""!!""""!!!!!!```!!""##$$%%&&''(()))((''&&%%$$###""!!!```!!!!````````!``@`````!!!````!!``````!!!!!!!""##$$%%%$$$##""!!``!!""####$$$$##""!!``!!""""""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ž`!!""##$$%%&&''(())**++,,--..////00112233445566778776665666777888999999:::::::;;;;;<<<===>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*****))**++,,--..////..--,,++**))((''&&%%$$##"""""""""""""!!````!!!!!!!!!!!!!!"""""!!!!!``ʉ``!!""!!""!!!!"""!!``!!!!!!""##$$%%&&''(())*))((''&&%%$$$##""!!!```!!"!!!!!!````!!!``!!``!!!!!!``!!!!!```!!!!!!!!""##$$%%&%%$$##""!!``!!""###$$$$##""!!```!!"""""!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..///001122334455667788877766667778889999::::::::;;;;;;<<====>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*****))))**++,,--..////..--,,++**))((''&&%%$$##""""""""###""!!``!!!!""""!"""!!""""""!!!!````!!""""""!!``!!"!!``!!!!""##$$%%&&''(())***))((''&&%%$$$##"""!!```!!!!!!!!!!````!!!!"!!``!!!``!!""!!!``!!!"!!!``!!!"""""""##$$%%&&&%%$$##""!!``!!""##$$$##""!!``!!!!!!!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667788887776777888999::::::;;;;;;;<<<<<===>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))(())**++,,--..////..--,,++**))((''&&%%$$#############""!!``````!!!!"""""""!!"""""""!!!````!!""""!!``!!!!``!!""##$$%%&&''(())**+**))((''&&%%%$$##"""!!!```!!!!!!!!!!!!!!!!!"!!`!``!!"!!```````!!"""""!!`````!!!!!""!!`Ŏ`!!""""""""##$$%%&&&&%%$$##""!!``!!""##$$$##""!!```!!!!!!!!``!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778898887777888999::::;;;;;;;;<<<<<<==>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))(((())**++,,--..////..--,,++**))((''&&%%$$########$$$##""!!`````!!!!!!!!!!!!!!""""!!!```!!"""!!``!!"!!``!!""##$$%%&&''(())**++**))((''&&%%%$$###""!!!!`!`````!!!!!!!!!!!!!!``!``!!"""!!!!`!!!!!""##"""!!````!!`!`````!!!!```!!"""#######$$%%&&&&%%$$##""!!```!!""##$$$###""!!```````````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667788998887888999:::;;;;;;<<<<<<<=====>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((((''(())**++,,--..////..--,,++**))((''&&%%$$$$$$$$$$$##""!!```!!!!!!!!!``!!!!!!!``!!"!!```!!"""!!``!!""##$$%%&&''(())**++++**))((''&&&%%$$###"""!!!``````````!!`!``!`!!""#""!!!!!!!!""#####""!!!!``````!!!``!!!""########$$%%&&&&%%$$##""!!``!!""#######""!!`‰`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..//00112233445566778899998888999:::;;;;<<<<<<<<======>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((((''''(())**++,,--..////..--,,++**))((''&&%%$$$$$$$$$##""!!```````````!!!!```!!"!!``!!""#""!!!!""##$$%%&&''(())**++,,++**))((''&&&%%$$$##"""!!`Ê````!!!""###""""!"""""##$##""!!```ƀ`!!!!```!!!""###$$$$$$$%%&&''&&%%$$##""!!``!!""#####"""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667788999998999:::;;;<<<<<<=======>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''''&&''(())**++,,--..////..--,,++**))((''&&%%%%%%%%$$##""!!`‡`````!!"!!`!!""###""!!""##$$%%&&''(())**++,,,,++**))(('''&&%%$$$##""!!`…``!!!""##$##""""""""##$##""!!```!!""!!``!!"""##$$$$$$$$%%&&''&&%%$$##"""!!``!!""##""""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::9999:::;;;<<<<========>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''''&&&&''(())**++,,--..////..--,,++**))((''&&%%%%%%$$##""!!`‡`!!""!!!""##$##""""##$$%%&&''(())**++,,-,,++**))((''''&&%%$$##""!!`````!!"""##$$$####"#####$##""!!``!!"""!!`Ǘ`!!"""##$$$%%%%%%%&&''&&%%$$##""!!!``!!""#"""""!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::::9:::;;;<<<======>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&%%&&''(())**++,,--..////..--,,++**))((''&&%%%$$$$##""!!``!!""""!""##$$$##""##$$%%&&''(())**++,,-,,++**))((''''&&&&%%$$##""!!````````!!!!!"""##$$%$$########$##""!!``!!"""!!`ʏ`!!!!""##$$%%%%%%%&&''&&%%$$##""!!!!``!!""#""!!!!!!`ˆ@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;::::;;;<<<====>>>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&%%%%&&''(())**++,,--..//..--,,++**))((''&&%%$$$$###""!!``!!"""""##$$%$$####$$%%&&''(())**+++,,,,++**))((''&&&&&&%%%%$$##""!!!``````!!!!!""###$$%%%$$$$#$$$$$$##""!!``!!"""!!```!!!""##$$%%&&&&&''&&%%$$##""!!```````!!"""!!!!!``@``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʼn`!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;:;;;<<<===>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%$$%%&&''(())**++,,--....--,,++**))((''&&%%$$$#####""!!``!!""#"##$$%%%$$##$$%%&&''(())***+++++,++**))((''&&&&%%%%%%%%$$##""!!!``!!``````!!!!"""""###$$%%&%%$$$$$$$$$$##""!!`````!!""""!!```!!""##$$%%&&&''&&%%$$##""!!```!``!!"!!````Š`@``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȃ`````!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<;;;;<<<===>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%$$$$%%&&''(())**++,,--..--,,++**))((''&&%%$$####""""!!`````!!""####$$$%%%%$$$$%%&&''(())))*****++++**))((''&&%%%%%%$$$$$%$$##"""!!!!!!!!!!!!!!"""""##$$$%%&&&%%%%$%%%%%$$##""!!`````!!!!!""""!!``!!""##$$%%&&''&&%%$$##""!!!``!`````!``!!!!`È@``````!````!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!!!!!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<;<<<===>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$##$$%%&&''(())**++,,----,,++**))((''&&%%$$###"""""!!!``!!!!!""##$#$$$$$$$$%$$%%%%&&''(()))))*****+**))((''&&%%%%$$$$$$$$$$$$##"""!!""!!!!!!""""#####$$$%%&&'&&%%%%%%%%%%$$##""!!!!``!!!!!!""""!!``!!""##$$%%&&&&%%$$##""!!``!!!```!!!!!``!!!!```!!!!!!!!!``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!"""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==<<<<===>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$####$$%%&&''(())**++,,--,,++**))((''&&%%$$##""""!!!!!```!`!!!""###$$$$##$$$$$$$$%%%%&&''(((()))))****))((''&&%%$$$$$$#####$$$$$###""""""""""""""#####$$%%%&&'''&&&&%&&&&&%%$$##""!!!!!!!"""""#""!!`ʗ`!!""##$$%%&&&%%$$##""!!``!!````!!!!!!!``!!!!!``!!!!!!!"!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""""""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<====<===>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####""##$$%%&&''(())**++,,,,++**))((''&&%%$$##"""!!!!!```!```!!""############$$$$$$$%%&&''((((()))))*))((''&&%%$$$$###########$$$###""##""""""####$$$$$%%%&&''(''&&&&&&&&&&%%$$##""""!!""""""##""!!``!!""##$$%%&&%%$$##""!!``!!!!`````!!"""!!````!!`````!!""""""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!````!!"""""###$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>====>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####""""##$$%%&&''(())**++,,++**))((''&&%%$$##""!!!!``````!!"""####""########$$$$%%&&''''((((())))((''&&%%$$######"""""#####$$$##############$$$$$%%&&&''(((''''&''''&&&%%$$##"""""""#####""!!`ƒ`!!""##$$%%&&&%%$$##""!!`!!""!!!``````!!""""!!```````!!!"""""""#""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!!!``````!!""#####$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>>=>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""!!""##$$%%&&''(())**++++**))((''&&%%$$##""!!!````!!!""""""""""""#######$$%%&&'''''((((()((''&&%%$$####"""""""""""###$$$##$$######$$$$%%%%%&&&''''(((''''''&&&&&&%%$$####""#######""!!``!!""##$$%%&&&&%%$$##""!!!"""!!``!`!!""#""!!!!`@`!```!!!""########""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!``!!!````!!!!!!""#####$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""!!!!""##$$%%&&''(())**++**))((''&&%%$$##""!!``À``````!!!!""""!!""""""""####$$%%&&&&'''''((((''&&%%$$##""""""!!!!!"""""##$$$$$$$$$$$$$$$%%%%%&&'''''''(((''&&&&&%%%%%%%$$#######$$##""!!``!!""##$$%%&&&&%%$$##""!"""!!``!!""#""!!````!!``!!"""#######$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!````!!!!!!""##$$$$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!``!!""##$$%%&&''(())****))((''&&%%$$##""!!```!!!!!!!!!!!!"""""""##$$%%&&&&&'''''(''&&%%$$##""""!!!!!!!!!!!"""####$$$$$$$$$%%%%%%%%%&&&&&&&'''''&&&&%%%%%%%%%%$$$$##$$$$##""!!``!!""##$$%%&&'&&%%$$##""""!!``!!""""!!```!!!````!!"""##$$$$$$$$##""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!``!!``!!"""""##$$$$$%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!``!!""##$$%%&&''(())**))((''&&%%$$##""!!!```!!!!``!!!!!!!!""""##$$%%%%&&&&&''''&&%%$$##""!!!!!!`````!!!!!""########$$$$$$$$%%%%%%&&&&&&&'''&&%%%%%$$$$$%%$%$$$$$$$$##""!!``!!""##$$%%&&'&&%%$$##"#""!!```!!""#""!!!``````!!"!!!!`!!""###$$$$$$$%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!``!!!``!!"""""##$$%%%%%&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````!!""##$$%%&&''(())*))((''&&%%$$##""!!``````````!!!!!!!""##$$%%%%%&&&&&'&&%%$$##""!!!!``````!!!""""######$$$$$$$$$$$$%%%%%%%&&&&&%%%%$$$$$$$$$$$%%%$$%$$##""!!``!!""##$$%%&&''&&%%$$####""!!``!`!!""#""!!````!!``!!"""!!!!!""###$$%%%%%%%%$$##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!``!!``!!""#####$$%%%%%&&&'''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())*))((''&&%%$$##""!!`````!!!!""##$$$$%%%%%&&&&%%$$##""!!`````!!""""""""########$$$$$$%%%%%%%&&&%%$$$$$#####$$#$$%%%%$$##""!!``!!!""##$$%%&&''&&%%$$#$##""!!!!!!""#""!!`````!!!!!!""#""""!""##$$$%%%%%%%&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""!!```!!!```!!""#####$$%%&&&&&''''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**))((''&&%%$$##""!!````!!""##$$$$$%%%%%&%%$$##""!!``!!!!""""""############$$$$$$$%%%%%$$$$###########$$$$$$$##""!!`…``!!""##$$%%&&''&&%%$$$$##""!!"!""##""!!``!``!``!!"!!""###"""""##$$$%%&&&&&&&&%%$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""""!!!!!"!!``!!!""##$$$$$%%&&&&&'''((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!""##$$%%&&''(())*))((''&&%%$$##""!!``!!""####$$$$$%%%%$$##""!!```!!!!!!!!""""""""######$$$$$$$%%%$$#####"""""##"##$$$$#$##""!!``!!""##$$%%&&''&&%%$%$$##""""""###""!!``!!``!!````!!"""""##$####"##$$%%%&&&&&&&'&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""##""!!!""!!```!!!""##$$$$$%%&&'''''(((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!`!!""##$$%%&&''(()))*))((''&&%%$$##""!!``!!""######$$$$$%$$##""!!````!!!!!!""""""""""""#######$$$$$####"""""""""""#########""!!``!!!""##$$%%&&''&&%%%%$$##""#"##$##""!!``!!!!``À`!!!!!!!!""#""##$$$#####$$%%%&&''''''''&&%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$######""""""!!``!!!"""##$$%%%%%&&'''''((()))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!""##$$%%&&''((((())))((''&&%%$$##""!!``!!""#""#####$$$$$##""!!``````!!!!!!!!""""""#######$$$##"""""!!!!!""!""####"###""!!```!!""##$$%%&&''&&%&%%$$######$$$##""!!!!""!!``!!"!!!!""#####$$%$$$$#$$%%&&&'''''''(''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>=>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##$$##"""#""!!``!!!"""##$$%%%%%&&''((((())))**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""!""##$$%%&&''((((((())((''&&%%$$##""!!``!!"""""""#####$$##""!!``!!!!!!!!!!!!"""""""#####""""!!!!!!!!!!!""""""""""!!``!!""##$$%%&&''&&&&%%$$##$#$$%$$##""!!"""!!``!!""""""##$##$$%%%$$$$$%%&&&''((((((((''&&%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=====>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$#####""!!``!!"""###$$%%&&&&&''((((()))***++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""""##$$%%&&''(((('''((((''&&%%$$##""!!``!!!!"!!"""""######""!!````````!!!!!!"""""""###""!!!!!`````!!`!!""""!""""!!``!!""##$$%%&&'''&'&&%%$$$$$$%%%$$##"""""!!``!!""""""##$$$$$%%&%%%%$%%&&'''((((((()((''&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===<===>>?>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$%%$$#####""!!``!!"""###$$%%&&&&&''(()))))****++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####"##$$%%&&''(((('''''(((''&&%%$$##""!!`Í`!!!!!!!!"""""####""!!```````!!!!!!!"""""!!!!`````!!!!!!!!!!!``!!""##$$%%&&''''''&&%%$$%$%%&%%$$##"""!!``!!""#####$$%$$%%&&&%%%%%&&'''(())))))))((''&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<==>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%$$$$$##""!!`@`!!""##$$$%%&&'''''(()))))***+++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$######$$$$%%&&''((''&&&''(''&&%%$$##""!!````!``!!!!!""""##""!!``!!!!!!!"""!!`````!!!!`!!!!``!!""##$$%%&&''('(''&&%%%%%%&&&%%$$##""!!`@`!!""####$$%%%%%&&'&&&&%&&''((()))))))*))(('''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<;<<<==>===>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%&&%%$$$$##""!!`@@@@`!!""##$$$%%&&'''''(())*****++++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$#$$$#$$%%&&''''&&&&&''''&&%%$$##""!!`Ɗ```!!!!!""""""!!```````!!!!!```````````!!""##$$%%&&''((((''&&%%&%&&'&&%%$$##""!!```!!""##$$$%%&%%&&'''&&&&&''((())********))(('(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;<<======>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&&%%%$$##""!!`@@@`!!""##$$%%&&''((((())*****+++,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$###$$%%&&''&&%%%&&'''&&%%$$##""!!`̎```!!!!"""""!!``!!!```Â`!!!""##$$%%&&''((((''&&&&&&'''&&%%$$##""!!```!!""##$$$%%&&&&&''(''''&''(()))*******+**))((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;:;;;<<=<<<==>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&''&&%%%$$##""!!`@@@@`!!""##$$%%&&''(((())**+++++,,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%%%%$$##"##$$%%&&&&%%%%%&&''&&%%$$##""!!`ϑ``!!!!"""!!``````!!!!""##$$%%&&''((((''&&'&''''&&%%$$##""!!`````!!!""##$$%%%&&'&&''((('''''(()))**++++++++**))())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::;;<<<<<<======>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''''&&&%%$$##""!!`@@`!!""##$$%%&&''(())))**+++++,,,---..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&%%%$$##"""##$$%%&&%%$$$%%&&'&&%%$$##""!!`ʏ``!!!!!!``Å````!!""##$$%%&&''((((''''''''&&%%$$##""!!``!``!!""##$$%%&&'''''(()(((('(())***+++++++,++**)))**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::9:::;;<;;;<<======>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''((''&&&%%$$##""!!`@@`!!""##$$%%&&''(()))**++,,,,,----..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%&&%%$$##""!""##$$%%%%$$$$$%%&&&&%%$$##""!!```!!!```Lj`````!!""##$$%%&&''((((''('((''&&%%$$##""!!```````!!""##$$%%&&''''(()))((((())***++,,,,,,,,++**)**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99999::;;;;;;<<<<<<====>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((((((''&&%%$$##""!!`@@`!!""##$$%%&&''(())**++,,,,,---...//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%$$##""!!!""##$$%%$$###$$%%&&&%%$$##""!!``````lj`!!!``!!""##$$%%&&''(())((((((((''&&%%$$##""!!``!!""##$$%%&&''((())*))))())**+++,,,,,,,-,,++***++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9998999::;:::;;<<<<<<====>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(()((''&&%%$$##""!!`@@`!!""##$$%%&&''(())**++,,---....//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$%%$$##""!!`!!""##$$$$#####$$%%&&&%%$$##""!!```ʏ`!``!!""##$$%%&&''(()))(()(((''&&%%$$##""!!``!!""##$$%%&&''(())***)))))**+++,,--------,,++*++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998888899::::::;;;;;;<<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))((''&&%%$$##""!!`@@@```!!""##$$%%&&''(())**++,,--...///00112233445566778899::;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$##""!!``!!""##$$##"""##$$%%&&%%$$##""!!``ʐ``!!""##$$%%&&''(())))))((''&&%%$$##""!!!`````!!""##$$%%&&''(())**+****)**++,,,-------.--,,+++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99888788899:999::;;;;;;<<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))((''&&%%$$##""!!`@@Lj@```````!!```!!""##$$%%&&''(())**++,,--..///00112233445566778899::;::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##$$$##""!!``!!""##$##"""""##$$%%%%$$##""!!``Ȑ`!!""##$$%%&&''(())**))((''&&%%$$##""!!```!``!`!!""##$$%%&&''(())**+++*****++,,,--........--,,+,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887777788999999::::::;;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***))((''&&%%$$##""!!`@@@@`!```!!!!!!!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;::::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####$$$##""!!`!!""##$##""!!!""##$$%%$$###""!!`Ä`Đ`````!!""##$$%%&&''(())))((''&&%%$$##""!!``!!!!!!""##$$%%&&''(())**++,++++*++,,---......./..--,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988777677788988899::::::;;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***))((''&&%%$$##""!!`@@@@@`!!!!!!!!!!""!!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::::99::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""##$$$##""!!!""##$##""!!!!!""##$$$$###""!!`````!!!``!``!!""##$$%%&&''(())**))((''&&%%$$##""!!``!!!!"!""##$$%%&&''(())**++,,,+++++,,---..////////..--,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776666677888888999999::::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++**))((''&&%%$$##""!!`@@@@``````@`!!!!!""""""""""!!````!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::9999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""##$###"""!""##$##""!!```!!""##$$##"""!!```ȏ`!!!!!!!``!!""##$$%%&&''(())**))((''&&%%$$##""!!``!!"""""##$$%%&&''(())**++,,-,,,,+,,--...///////0//..---..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877666566677877788999999::::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++**))((''&&%%$$##""!!`@@`!!!!!!``````!!""""""""""##"""!!!```!!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899:998899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""####""""""##$##""!!``!!""####"""!!!``ď͖`!!""!!!``!!""##$$%%&&''(())****))((''&&%%$$##""!!``!!"""#"##$$%%&&''(())**++,,---,,,,,--...//00000000//..-..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655555667777778888889999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,++**))((''&&%%$$##""!!``@@``!!!!!!!!!!!!`````!!"""##########""!!!!!!!"""!!``!!""##$$%%&&''(())**++,,--..//001122334455667788999888899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!""#"""!!""######""!!``!!""###""!!!!```Ǐ``ٚ`!!""""!!```!!""##$$%%&&''(())**+**))((''&&%%$$##""!!!!""#####$$%%&&''(())**++,,--.----,--..///0000000100//...//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665554555667666778888889999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,++**))((''&&%%$$##""!!!`@`!!!""""""!!!!!!!!````!!""#######$$###"""!!!""""""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677889988778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!!!""""##""!!``!!""#"""!!!````ɒ`ܙ`!!""""!!```!!""##$$%%&&''(())**++**))((''&&%%$$##""!!""###$#$$%%&&''(())**++,,--...-----..///001111111100//.//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554444455666666777777888899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!`@@``!!!""""""""""""!!!!````!``!!""##$$$$$$$$$$##"""""""###""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677888877778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"!!!``!!""""#""!!``!!""""""!!````Ƒ`ړ`!!""#""!!`!``!!""##$$%%&&''(())**+++**))((''&&%%$$##""""##$$$$$%%&&''(())**++,,--../....-..//000111111121100///00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444344455655566777777888899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!`@@`!!!"""######""""""""!!!!````!!!```!!""##$$$$$$$%%$$$###"""#####""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677887766778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!``!!!!"""!!```!!"""""!!!```͓``ϗ`!!""#""!!!``!!""##$$%%&&''(())**++,++**))((''&&%%$$##""##$$$%$%%&&''(())**++,,--..///.....//00011222222221100/00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544333334455555566666677778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!`!!!``````!!!"""############""""!!!!!!!!"!!!!!""##$$%%%%%%%%%%$$#######$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778776666778899::;;<<==>>???>>>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!```!!!!""!!``!!""!!!!!!```Ɖ``ɕ`!!""##""!!!`ɇ`!!""##$$%%&&''(())**++,,,++**))((''&&%%$$####$$%%%%%&&''(())**++,,--..//0////.//00111222222232211000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433323334454445566666677778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!``!!!```!!!"""###$$$$$$########""""!!!!"""!!!""##$$%%%%%%%&&%%%$$$###$$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667777665566778899::;;<<==>>?>>>>>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````ڊ`!```!!!!``!!!!!!!!````ď``ȏ`!!""##""!!``!!""##$$%%&&''(())**++,,,++**))((''&&%%$$##$$%%%&%&&''(())**++,,--..//000/////00111223333333322110112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322222334444445555556666778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!``!!!!``!!!!"""###$$$$$$$$$$$$####""""""""#"""""##$$%%&&&&&&&&&&%%$$$$$$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566777766555566778899::;;<<==>>>========>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!``!!``!!!!``````Ɏ``Č`!!"""#""!!``!!""##$$%%&&''(())**++,,-,,++**))((''&&%%$$$$%%&&&&&''(())**++,,--..//0010000/00112223333333433221112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332221222334333445555556666778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!``!!"!!``!!!"""###$$$%%%%%%$$$$$$$$####""""###"""##$$%%&&&&&&&''&&&%%%$$$%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566776655445566778899::;;<<==>============>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``````!``!!!````ˊ```!!"""#""!!``!!""##$$%%&&''(())***++,,--,,++**))((''&&%%$$%%&&&'&''(())**++,,--..//0011100000112223344444444332212233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221111122333333444444555566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!```!!""""###$$$%%%%%%%%%%%%$$$$########$#####$$%%&&''''''''''&&%%%%%$$##""!!``!!""##$$$%%&&''(())**++,,--..//00112233445566665544445566778899::;;<<===<<<<<<<<====>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````````!``!``!!!``!``ŀ``!!!!""#""!!``!!""##$$%%&&''(())**)**++,,--,,++**))((''&&%%%%&&'''''(())**++,,--..//0011211110112233344444445443322233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111011122322233444444555566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ł``!`!``!!!"""###$$$%%%&&&&&&%%%%%%%%$$$$####$$$###$$%%&&'''''''(('''&&&%%%$$##""!!``!!""###$$%%&&''(())**++,,--..//00112233445566554433445566778899::;;<<=<<<<<<<<<<<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!`!!`!!!``!!```!!!!``!```!```!!!!""#""!!``!!""##$$%%&&''(())*)))**++,,--,,++**))((''&&%%&&'''('(())**++,,--..//0011222111112233344555555554433233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000001122222233333344445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!`````!!""####$$$%%%&&&&&&&&&&&&%%%%$$$$$$$$%$$$$$%%&&''((((((((((''&&&&%%$$##""!!``!!""####$$%%&&''(())**++,,--..//00112233445555443333445566778899::;;<<<;;;;;;;;<<<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!!!!!!````!!!!!!!!!````!!!!````!!""#""!!`````!!""##$$%%&&''(())))())**++,,--,,++**))((''&&&&''((((())**++,,--..//0011223222212233444555555565544333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000/0001121112233333344445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!``!!""###$$$%%%&&&''''''&&&&&&&&%%%%$$$$%%%$$$%%&&''((((((())((('''&&%%$$##""!!``!!""""##$$%%&&''(())**++,,--..//00112233445544332233445566778899::;;<;;;;;;;;;;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`!!"!""!"""!!!!!!""!!!"!!```!!!"!!``!!""#""!!!!!``!!""##$$%%&&''(()))((())**++,,--,,++**))((''&&''((()())**++,,--..//0011223332222233444556666666655443445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////001111112222223333445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!``!!""##$$$%%%&&&''''''''''''&&&&%%%%%%%%&%%%%%&&''(())))))))))(('''&&%%$$##""!!``!!"""""##$$%%&&''(())**++,,--..//00112233444433222233445566778899::;;;::::::::;;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!""""""""""!!!!""""""!!``!!""!!``!!""##""!!!!````!!""##$$%%&&''(((()(('(())**++,,--,,++**))((''''(()))))**++,,--..//0011223343333233445556666666766554445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///.///001000112222223333445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!``!!""##$$%%%&&&'''((((((''''''''&&&&%%%%&&&%%%&&''(()))))))**)))((''&&%%$$##""!!``!!"!!""##$$%%&&''(())**++,,--..//00112233443322112233445566778899::;::::::::::::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!""#"##"###""""""##"""!!``!!"""!!``!!""###""""!!```!!!!""##$$%%&&''((('((('''(())**++,,--,,++**))((''(()))*)**++,,--..//0011223344433333445556677777777665545566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.....//000000111111222233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!```!!""##$$%%&&&'''((((((((((((''''&&&&&&&&'&&&&&''(())**********))((''&&%%$$##""!!``!!!!!!""##$$%%&&''(())**++,,--..//00112233332211112233445566778899:::99999999::::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""##########""""###""!!!`†`!!"""!!``!!"""""""""!!!``!!!!""##$$%%&&''('''''(''&''(())**++,,--,,++**))(((())*****++,,--..//0011223344544443445566677777778776655566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...-...//0///00111111222233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!```!!"!!!``!!""##$$%%&&''((())))))((((((((''''&&&&'''&&&''(())*******++***))((''&&%%$$##""!!``!!!``!!""##$$%%&&''(())**++,,--..//00112233221100112233445566778899:999999999999::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###"##$#$$#$$$#######""!!```!!""""!!``!!"""""##""!!!````!!""""##$$%%&&&''''''&'''&&&''(())**++,,--,,++**))(())***+*++,,--..//0011223344555444445566677888888887766566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-----..//////00000011112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!``!!"!!!``!!""##$$%%&&''(()))))))))))((((''''''''('''''(())**+++++++++**))((''&&%%$$##""!!``!!``!!""##$$%%&&''(())**++,,--..//001122221100001122334455667788999888888889999::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####$$$$$$$$$$#####""!!``!!""""!!``!!!!!!""##"""!!```````!!"""##$$%%&&&&&''&&&&&'&&%&&''(())**++,,--,,++**))))**+++++,,--..//0011223344556555545566777888888898877666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,---../...//00000011112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!!````!!"""!!```!!""##$$%%&&''(())****))))))))((((''''((('''(())**+++++++,++**))((''&&%%$$##""!!``!!!``!!""##$$%%&&''(())**++,,--..//00112221100//001122334455667788988888888888899::;;<<==>>????????????>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$#$$%$%%$%%%$$$##""!!``!!""""!!```!!!!!""##"""!!!````````````!!""#####$$%%&&%&&&&&&%&&&%%%&&''(())**++,,--,,++**))**+++,+,,--..//0011223344556665555566777889999999988776778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,--......//////0000112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""!!!!``!!"""!!``!!""##$$%%&&''(())*********))))(((((((()((((())**++,,,,,,,,++**))((''&&%%$$##""!!``!!!!`!!""##$$%%&&''(())**++,,--..//00112221100////001122334455667788877777777888899::;;<<==>>??????????>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$%%%%%%%%%$$##""!!``!!""""!!`````!!""###""!!!!`````!`!!!```!!""######$$%%%%%&&%%%%%&%%$%%&&''(())**++,,--,,++****++,,,,,--..//0011223344556676666566778889999999:99887778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,+,,,--.---..//////0000112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####"""!!!!```!!""!!``!!""##$$%%&&''(())**+********))))(((()))((())**++,,,,,,,-,,++**))((''&&%%$$##""!!```!!!!!!""##$$%%&&''(())**++,,--..//00112221100//..//001122334455667787777777777778899::;;<<==>>????????>>=>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$%%&%&&%%%$$##""!!``!!""""!!```!!""###"""!!!!``!!!!!````!!""###"""##$$%%$%%%%%%$%%%$$$%%&&''(())**++,,--,,++**++,,,-,--..//00112233445566777666667788899::::::::998878899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++++,,------......////00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####""""!!!``!!"!!``!!""##$$%%&&''(())**++++++****))))))))*)))))**++,,--------,,++**))((''&&%%$$##""!!``!!`!!""##$$%%&&''(())**++,,--..///0011221100//....//001122334455667776666666677778899::;;<<==>>??????>>===>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%&&&&&&%%$$##""!!``!!""""!!```!!""###""""!!``!!!!!`’```!!"""""""""##$$$$$%%$$$$$%$$#$$%%&&''(())**++,,--,,++++,,-----..//00112233445566778777767788999:::::::;::9988899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++*+++,,-,,,--......////00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$###""""!!!```!!!!``!!""##$$%%&&''(())**+++++++++****))))*)))))**++,,,,-,,,---,,++**))((''&&%%$$##""!!``!``!!""##$$%%&&''(())**++,,--..///00111100//..--..//001122334455667666666666666778899::;;<<==>>????>>==<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%&&'&&&%%$$##""!!``!!"""!!``!!""#####"""!!``!!!!```!!``!!"""""!!!""##$$#$$$$$$#$$$###$$%%&&''(())**++,,--,,++,,---.-..//00112233445566778887777788999::;;;;;;;;::99899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*****++,,,,,,------....//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$####""!!``!!!``!!""##$$%%&&''(())**++,,,,++++*******))))***++,,,,,,,,,,---,,++**))((''&&%%$$##""!!```!!``!!""##$$%%&&''(())**++,,--.././/001100//..----..//001122334455666555555556666778899::;;<<==>>??>>==<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&'''&&%%$$##""!!``!!"""!!``!!""##$####""!!!!!!``!!!```!!"!!!!!!!""#####$$#####$##"##$$%%&&''(())**++,,--,,,,--.....//0011223344556677889888878899:::;;;;;;;<;;::999::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***)***++,+++,,------....//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%$$$###""!!```!!"!!```!!""##$$%%&&''(())**++,,,,,,,,++++***))(())**+++++++,+++,,---,,++**))((''&&%%$$##""!!!``!!!!`!!""##$$%%&&''(())**++,,--../...//0000//..--,,--..//001122334455655555555555566778899::;;<<==>>>>==<<;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''&'''&&%%$$##""!!``!!"""!!``!!""##$#####""!!!!``!!!!!```!!!!!!```!!""##"######"###"""##$$%%&&''(())**++,,--,,--..././/0011223344556677889998888899:::;;<<<<<<<<;;::9::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))**++++++,,,,,,----..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%$$##""!!``!!"!!!```!!""##$$%%&&''(())**++,,---,,,,+++**))(((())**+++++++++++,,--,,++**))((''&&%%$$##"""!!``!!!!!""##$$%%&&''(())*)**++,,--...-..//00//..--,,,,--..//001122334455544444444555566778899::;;<<==>>==<<;;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''''&&%%$$##""!!``!!""""!!``!!""###""###""!!```!!"!!!!``````!!!!````!!"""""##"""""#""!""##$$%%&&''(())**++,,----../////00112233445566778899:9999899::;;;<<<<<<<=<<;;:::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))()))**+***++,,,,,,----..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&%%$$##""!!``!!"!!!!```!!""##$$%%&&''(())**++,,------,,++**))((''(())*******+***++,,,,++**))((''&&%%$$##""!"!!``!!"!""##$$%%&&''(())*)))**++,,--.---..////..--,,++,,--..//001122334454444444444445566778899::;;<<====<<;;:;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((('(''&&%%$$##""!!``!!""""!!```!!!""#"""""""!!``!!"""!!!!!!!````````````````````!!!!``!!""!""""""!"""!!!""##$$%%&&''(())**++,,--..///0/00112233445566778899:::99999::;;;<<========<<;;:;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((((())******++++++,,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!!!``!!""##$$%%&&''(())**++,,--.--,,++**))((''''(())***********++,,++**))((''&&%%$$##""!!!!!!``!!""""##$$%%&&''(())*))())**++,,---,--..//..--,,++++,,--..//001122334443333333344445566778899::;;<<==<<;;:::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((((''&&%%$$##""!!``!!""#""!!``!!!!"""!!"""!!```!!"""""!!!!!!!!!!!!!!!`````````!!```````!!!!!!````!!"!!``!!"!!!""!!!!!"!!`!!""##$$%%&&''(())**++,,--..//000112233445566778899::;::::9::;;<<<=======>==<<;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>==<<;;::99887766554433221100//..--,,++**))((('((())*)))**++++++,,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""""!!!``!!""##$$%%&&''(())**++,,----,,++**))((''&&''(()))))))*)))**++++**))((''&&%%$$##""!!`!`````!!""#"##$$%%&&''(())*))((())**++,,-,,,--....--,,++**++,,--..//001122334333333333333445566778899::;;<<<<;;::9::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))((''&&%%$$##""!!`Ć`!!""""!!``!!``!!"!!!!!!!``!!"""""""""!!!!!!!!!!!!```````!!!!!!!!!!!!!!!!!!!!!!``!!!!""!!``!!!!`!!!!!!`!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;:::::;;<<<==>>>>>>>>==<<;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????==<<;;::99887766554433221100//..--,,++**))(('''''(())))))******++++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""""!!``!!""##$$%%&&''(())**++,,---,,++**))((''&&&&''(()))))))))))**++**))((''&&%%$$##""!!````!!""####$$%%&&''(()))))(('(())**++,,,+,,--..--,,++****++,,--..//001122333222222223333445566778899::;;<<;;::999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!``!``!!!``!!!``!!"""""""""""""""""""!!!!!!`!!!!!!!!!!""!!!!!!!"""""!!````!!!""!!``!!!``!!````!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;;:;;<<===>>>>>>>?>>==<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????=<<;;::99887766554433221100//..--,,++**))(('''&'''(()((())******++++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!``!!""##$$%%&&''(())**++,,---,,++**))((''&&%%&&''((((((()((())**+**))((''&&%%$$##""!!`````!!!""####$$%%%&&&''(()))(('''(())**++,+++,,----,,++**))**++,,--..//001122322222222222233445566778899::;;;;::99899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!`````!`````!!""""""""""""""""""""!!!!!!!!""""""""""""""""""""""!!!``!!"""!!``!!``!``!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<;;;;;<<===>>????????>>==<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????<<;;::99887766554433221100//..--,,++**))((''&&&&&''(((((())))))****++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!```!!""##$$%%&&''(())**++,,--,,++**))((''&&%%%%&&''((((((((((())***))((''&&%%%$$$##""!!````!!!!!!""##""##$$%%%&&&''(((((''&''(())**+++*++,,--,,++**))))**++,,--..//001122211111111222233445566778899::;;::9988899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!"""!!`````!!!!""""""#########""""""!""""""""""##"""""""#####""!!``!!""""!!``!!````!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<<;<<==>>>??????????>>===>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????<;;::99887766554433221100//..--,,++**))((''&&&%&&&''('''(())))))****++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""#""!!!``!!""##$$%%&&''(())**++,,-,,++**))((''&&%%$$%%&&'''''''('''(())*))((''&&%%$$$$####""!!!!!!!!!"""##""""##$$$%%%&&''(((''&&&''(())**+***++,,,,++**))(())**++,,--..//001121111111111112233445566778899::::998878899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!````!!!!!!!!""##########""""""""#####################""!!````!!""!!!!``!!!!``!```!!""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<<<<==>>>????????????>>=>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????;;::99887766554433221100//..--,,++**))((''&&%%%%%&&''''''(((((())))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!``!!""##""!!``!!""##$$%%&&''(())**++,,,,++**))((''&&%%$$$$%%&&'''''''''''(()))((''&&%%$$$#######""!!!!""""""""""!!""##$$$%%%&&'''''&&%&&''(())***)**++,,++**))(((())**++,,--..//001110000000011112233445566778899::99887778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!`````!!!!!!""##$$$$$######"##########$$#######$$$$##""!!``!!!""!!!!!``!!"!!!!!```!!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=====<==>>???????????????>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????;::99887766554433221100//..--,,++**))((''&&%%%$%%%&&'&&&''(((((())))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!``!!""##""!!```!!""##$$%%&&''(())**++,,,++**))((''&&%%$$##$$%%&&&&&&&'&&&''(()((''&&%%$$####"""""""""""""!!!""""!!!!""###$$$%%&&'''&&%%%&&''(())*)))**++++**))((''(())**++,,--..//0010000000000001122334455667788999988776778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""#""!!!```````!!""##$$$$$$########$$$$$$$$$$$$$$$$$$$$$##""!!``!!!""!!``!``!!"""!!"!!!!!!""##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>=====>>?????????????????>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????::99887766554433221100//..--,,++**))((''&&%%$$$$$%%&&&&&&''''''(((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!```!!""##""!!!``!!""##$$%%&&''(())**++,,,++**))((''&&%%$$####$$%%&&&&&&&&&&&''(((''&&%%$$###"""""""!!!!!!!!!!!!!!!!``!!""###$$$%%&&&&&%%$%%&&''(()))())**++**))((''''(())**++,,--..//000////////00001122334455667788998877666778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""###""!!!!``!!""##$$%$$$$$$#$$$$$$$$$$%%$$$$$$$%%%%$$##""!!```!!"""!!````!!"""""""!!!"""#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>>>=>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????:99887766554433221100//..--,,++**))((''&&%%$$$#$$$%%&%%%&&''''''(((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!!``!!""###""!!!``!!""##$$%%&&''(())**++,,++**))((''&&%%$$##""##$$%%%%%%%&%%%&&''(''&&%%$$##""""!!!!!!!!!!!!!```!!!!``!!"""###$$%%&&&%%$$$%%&&''(()((())****))((''&&''(())**++,,--..//0////////////001122334455667788887766566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""####"""!!``!!""##$$%%$$$$$$$$%%%%%%%%%%%%%%%%%%%%%$$##""!!!``!!""""!!```!!""#""#""""""##$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????99887766554433221100//..--,,++**))((''&&%%$$#####$$%%%%%%&&&&&&''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####""!!!``!!""####""!!``!!""##$$%%&&''(())**++,++**))((''&&%%$$##""""##$$%%%%%%%%%%%&&'''&&%%$$##"""!!!!!!!```````````!!``!!"""""###$$%%%%%$$#$$%%&&''((('(())**))((''&&&&''(())**++,,--..///........////001122334455667788776655566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$##"""!!``!!""##$$%%%%%$%%%%%%%%%%&&%%%%%%%&&&&%%$$##""!!!````!!""##""!!````!!""######"""###$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????9887766554433221100//..--,,++**))((''&&%%$$###"###$$%$$$%%&&&&&&''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####"""!!``!!""##$##""!!``!!""##$$%%&&''(())**++++**))((''&&%%$$##""!!""##$$$$$$$%$$$%%&&'&&%%$$##""!!!!```````!!!!!!!!"""##$$%%%$$###$$%%&&''('''(())))((''&&%%&&''(())**++,,--../............//001122334455667777665545566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$###""!!``!!!""##$$%%%%%%%%&&&&&&&&&&&&&&&&&&&&&%%$$##"""!!!```!!!""####""!!!``!!""####$######$$%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????887766554433221100//..--,,++**))((''&&%%$$##"""""##$$$$$$%%%%%%&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$##""!!``!!""##$$##""!!``!!""##$$%%&&''(())**+++**))((''&&%%$$##""!!!!""##$$$$$$$$$$$%%&&&%%$$##""!!!``ń``!!!!!!!"""##$$$$$##"##$$%%&&'''&''(())((''&&%%%%&&''(())**++,,--...--------....//001122334455667766554445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$##""!!``!!!""##$$%%&%&&&&&&&&&&''&&&&&&&''''&&%%$$##"""!!!``!!!!""##$$##""!!``!!""##$$$$###$$$%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????87766554433221100//..--,,++**))((''&&%%$$##"""!"""##$###$$%%%%%%&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$##""!!``!!""##$$$$##""!!``!!""##$$%%&&''(())**++**))((''&&%%$$##""!!``!!""#######$###$$%%&%%$$##""!!````````!!!""##$$$##"""##$$%%&&'&&&''((((''&&%%$$%%&&''(())**++,,--.------------..//001122334455666655443445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""####""!!````!!""##$$%%&&&&'''''''''''''''''''''&&%%$$###"""!!``!!!"""##$$$##""!!```!!""##$$%$$$$$$%%&&%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????7766554433221100//..--,,++**))((''&&%%$$##""!!!!!""######$$$$$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$##""!!````!!""##$$%%$$##""!!``!!""##$$%%&&''(())**+**))((''&&%%$$##""!!``!!""###########$$%%%$$##""!!``!!!""#####""!""##$$%%&&&%&&''((''&&%%$$$$%%&&''(())**++,,---,,,,,,,,----..//001122334455665544333445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""####""!!``!!""##$$%%&&''''''''(('''''''((((''&&%%$$###"""!!``````!!""""##$$%$$##""!!``!!""##$$%$$$%%%&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????766554433221100//..--,,++**))((''&&%%$$##""!!!`!!!""#"""##$$$$$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,++**))((''&&%%%$$##""!!!!!!""##$$%%%%$$##""!!``!!""##$$%%&&''(())**+**))((''&&%%$$##""!!``!!""""""""#"""##$$%$$##""!!`@``!!""###""!!!""##$$%%&%%%&&''''&&%%$$##$$%%&&''(())**++,,-,,,,,,,,,,,,--..//001122334455554433233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""###""!!``!!""##$$%%&&''(((((((((((((((((((''&&%%$$##""!!``````!!!!"""###$$%%%$$##""!!````!!""##$$%%%%%%%&&''&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????66554433221100//..--,,++**))((''&&%%$$##""!!````!!""""""######$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,,++**))((''&&&%%$$##""!!!!""##$$%%%%$$##""""!!``!!""##$$%%&&''(())**++**))((''&&%%$$##""!!``!!"""""""""""""##$$$##""!!`````!!"""""!!`!!""##$$%%%$%%&&''&&%%$$####$$%%&&''(())**++,,,++++++++,,,,--..//001122334455443322233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##""!!``!!""##$$%%&&''((((())((((((()))((''&&%%$$##""!!```!!!!!!!!""####$$%%%%$$##""!!``!!`!!""##$$%%%%%&&&'''''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????6554433221100//..--,,++**))((''&&%%$$##""!!`Ć`!!"!!!""######$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++,,,,++**))((''&&&%%$$##""""""##$$%%%%$$##""!!"!!``!!""##$$%%&&''(())**+++**))((''&&%%$$##""!!`!!"""!!!!!!"!!!""##$##""!!````````!!"""!!``!!""##$$%$$$%%&&&&%%$$##""##$$%%&&''(())**++,++++++++++++,,--..//001122334444332212233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""#""!!``!!""##$$%%&&''(()))))))))))))))((''&&%%$$##""!!````!!!!!!!""""###$$$%%&&%%$$##""!!``!``!!""##$$%%&&&&''(('(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!""""""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++,,,,++**))(('''&&%%$$##""""##$$%%%%$$##""!!!!!!``!!""##$$%%&&''(())*******))((''&&%%$$##""!!!"!!!!!!!!!!!!!!""###""!!```````!!!""!!``!!""##$$$#$$%%&&%%$$##""""##$$%%&&''(())**+++********++++,,--..//001122334433221112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!``!!""##$$%%&&''(())))**)))))))*))((''&&%%$$##""!!````!!!""""""""##$$$$%%&&&&%%$$##""!!````!!""##$$%%&&'''((((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????54433221100//..--,,++**))((''&&%%$$##""!!```!!!!```!!""""""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**++,,,,++**))(('''&&%%$$######$$%%%%$$##""!!``!!!``!!""##$$%%&&''(())*****))((''&&%%$$##""!!!!!!!!``````!```!!""#""!!`````!```!!!!!!!`!!""##$$$###$$%%%%$$##""!!""##$$%%&&''(())**+************++,,--..//001122333322110112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!``!!""##$$%%&&''(())*************))((''&&%%$$##""!!````!```!!""""""####$$$%%%&&'&&%%$$##""!!````!!""##$$%%&&''(())())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????54433221100//..--,,++**))((''&&%%$$##""!!`````!!!!``!!!!!!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****++,,,,++**))(((''&&%%$$####$$%%%%$$##""!!``!!``!!""##$$%%&&''(())*)))))((''&&%%$$##""!!!!!!`````!!""#""!!``````!````````````!!!!!!!""###$$##"##$$%%$$##""!!!!""##$$%%&&''(())***))))))))****++,,--..//001122332211000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!``!!""##$$%%&&''(())***++*******+**))((''&&%%$$##""!!``````!!!!``````!`!!""########$$%%%%&&'''&&%%$$##""!!``!!``!!""##$$%%&&''(()))))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!"!!``!!!!!!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))**++,,,,++**))(((''&&%%$$$$$$%%&%%$$##""!!``!!``!!""##$$%%&&''(()))))))((''&&%%$$##""!!``````!!""#""!!!!`!!!!!````!!!!!`````!!!!""""####"""##$$$$##""!!``!!""##$$%%&&''(())*))))))))))))**++,,--..//001122221100/00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!``!!""##$$%%&&''(())**+++++++++++++**))((''&&%%$$##""!!`````!!!!!!!!!```!!!!!!!""######$$$$%%%&&&''(''&&%%$$##""!!!!!!!!""##$$%%&&''(())**)**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????6554433221100//..--,,++**))((''&&%%$$##""!!!!!!!""!!``````!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))**++,,,,++**)))((''&&%%$$$$%%&&&%%$$##""!!``!!``!!""##$$%%&&''(()))(((((''&&%%$$##""!!``!!""#""!!!!!!!"!!```!``!``!!!!!!!!``````````!!""""##""!""##$$##""!!``!!""##$$%%&&''(()))(((((((())))**++,,--..//0011221100///00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!``!!""##$$%%&&''(())**++,,+++++++,++**))((''&&%%$$##""!!`````!````````!!!!!!!!""!!````````!````!!!!!"!""##$$$$$$$$%%&&&&''(((''&&%%$$##""!!""!!!!""##$$%%&&''(())***++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????66554433221100//..--,,++**))((''&&%%$$##""!!"""""""!!```!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(())**++,,,,++**)))((''&&%%%%%%&&'&&%%$$##""!!```!!``!!""##$$%%&&''(())(((((''&&%%$$##""!!``!!""##""""!"""""!!``!!!!!!!!!"""""!!!```!``!!!!""""!!!""####""!!``!!""##$$%%%&&''(())(((((((((((())**++,,--..//00111100//.//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""!!```!!""##$$%%&&''(())**++,,,,,,,,,,,,++**))((''&&%%$$##""!!```!!!!!!!!!!!!!!!""""""""!!``!!!!```````!!!!!!!!!"""""""##$$$$$$%%%%&&&'''(()((''&&%%$$##""""""!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????766554433221100//..--,,++**))((''&&%%$$##"""""""##""!!```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((())**++,,,,++***))((''&&%%%%&&'''&&%%$$##""!!!`!!``!!""##$$%%&&''(((('''''&&%%$$##""!!``!!""###"""""""#""!!!!!"!!"!!"""""""!!````!!!!""!!`!!""####""!!``!!""##$$%%%%%&&''((((''''''''(((())**++,,--..//001100//...//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!``!!""##$$%%&&''(())**++,,--,,,,,,,-,,++**))((''&&%%$$##""!!````!!!"!!!!!!!!""""""""#""!!``!!!!````!!!!!!!"!!!!"""""#"##$$%%%%%%%%&&''''(()))((''&&%%$$##""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????7766554433221100//..--,,++**))((''&&%%$$##""#######""!!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''(())**++,,,,++***))((''&&&&&&''(''&&%%$$##""!!!!``!!""##$$%%&&''(((''''''&&%%$$##""!!``!!""##$####"#####""!!"""""""""####""!!``````!!!!``!!"""###""!!!!""###$$$$$$%%&&''((''''''''''''(())**++,,--..//0000//..-..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!``!!""##$$%%&&''(())**++,,------------,,++**))((''&&%%$$##""!!``!!``!!""""""""""""#######""!!``!!!!```!!!!"""""""""#######$$%%%%%%&&&&'''((())*))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????87766554433221100//..--,,++**))((''&&%%$$#######$$##""!!!!!``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''(())**++,,,,+++**))((''&&&&''(((''&&%%$$##"""!!``!!""##$$%%&&&'''''&&&&&&%%$$##""!!``!!""##$$#######$##"""""#""#""######""!!```!!!!`!!"""""###""!!""#####$$$$$$%%&&''''&&&&&&&&''''(())**++,,--..//00//..---..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""""!!``!!""##$$%%&&''(())**++,,--.-------.--,,++**))((''&&%%$$##""!!````!!!!``!!"""""""""########$##""!!```!!""!!``!``!!""""""#""""#####$#$$%%&&&&&&&&''(((())**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????887766554433221100//..--,,++**))((''&&%%$$##$$$$$$$##"""""!!``!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&''(())**++,,,,+++**))((''''''(()((''&&%%$$##""!!``!!""##$$%%&&&'''&&&&&&%%%$$##""!!``!!""##$$$$#$$$$$##""#########$$$$##""!!!`````````!!!!""!!!""""""""""""""######$$%%&&''&&&&&&&&&&&&''(())**++,,--..////..--,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##""!!``!!""##$$%%&&''(())**++,,--.........--,,++**))((''&&%%$$##""!!``````!!!!!!``!!""##########$$$$$$$##""!!`````!!!""""!!!!``!!"""#########$$$$$$$%%&&&&&&''''((()))****))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????9887766554433221100//..--,,++**))((''&&%%$$$$$$$%%$$##"""""!!``````!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&''(())**++,,,,,++**))((''''(())((''&&%%$$##""!!``!!""##$$%%%&&&&&%%%%%%%%$$##""!!``!!""##$$$$$$$$$%$$#####$##$##$$$$$$##""!!!!```!!```!!"!!!!!!"""!!!!!!"""""######$$%%&&&&%%%%%%%%&&&&''(())**++,,--..//..--,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!```!!""##""!!``!!""##$$%%&&''(())**++,,--......../..--,,++**))((''&&%%$$##""!!!!!!!!!!"!!```!!""########$$$$$$$$$$##""!!``!!!!!""##""!!!!``!!""####$####$$$$$%$%%&&''''''''(())))****))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????99887766554433221100//..--,,++**))((''&&%%$$%%%%%%%$$#####""!!`!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%&&''(())**++,,,,,++**))(((((()))((''&&%%$$##""!!``!!""##$$%%%&&&%%%%%%$$$$$##""!!``!!""##$$%%%$%%%%%$$##$$$$$$$$$%%%%$$##"""!!!!`!!``!!!!```!!!!!!!!!!!!!!""""""##$$%%&&%%%%%%%%%%%%&&''(())**++,,--....--,,+,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!""###""!!``!!""##$$%%&&''(())**++,,--..////////..--,,++**))((''&&%%$$##""!!!!!!""""!!``!!""##$$$$$$$$$$%%%%%%$$##""!!``!!!!"""###""!!!```!!!""##$$$$$$$%%%%%%%&&''''''(((()))***+**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????:99887766554433221100//..--,,++**))((''&&%%%%%%%&&%%$$#####""!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%&&''(())**++,,-,,++**))(((())))((''&&%%$$##""!!``!!""##$$$%%%%%$$$$$$$$$$##""!!````!!""##$$%%%%%%%%&%%$$$$$%$$%$$%%%%%%$$##""""!!!!!``!!!```!!!``````!!!!!""""""##$$%%%%$$$$$$$$%%%%&&''(())**++,,--..--,,+++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""####""!!``````!!""##$$%%&&''(())**++,,--..///////0//..--,,++**))((''&&%%$$##""""""""""!!``!!""##$$$$$$$%%%%%%%%%$$##""!!``!!""""###""!!``@@``!!""##$$$$$%%%%%&%&&''(((((((())****+++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????::99887766554433221100//..--,,++**))((''&&%%&&&&&&&%%$$$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$%%&&''(())**++,,-,,++**))))))**))((''&&%%$$##""!!``!!""###$$$%%%$$$$$$######""!!``!!!""##$$%%&&&%&&&&&%%$$%%%%%%%%%&&&&%%$$###""""!!``!!!`Ã```````!!!!!!""##$$%%$$$$$$$$$$$$%%&&''(())**++,,----,,++*++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$##""!!!!``!!``!!""##$$%%&&''(())**++,,--..//00000000//..--,,++**))((''&&%%$$##""""""#""!!```!!""##$$%%%%%%%%%&&&&&%%$$##""!!```!!"""####""!!`Ă`!!""##$$%%%&&&&&&&''(((((())))***++++**))((''&&%%$$##"""!!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????;::99887766554433221100//..--,,++**))((''&&&&&&&''&&%%$$$$##""!!`Ɠ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$%%&&''(())**++,,-,,++**))))***))((''&&%%$$##""!!``!!""####$$$$$###########""!!``!!!""##$$%%&&&&&&&&'&&%%%%%&%%&%%&&&&&&%%$$####""!!```````````````````!!!``!!!!!!""##$$$$########$$$$%%&&''(())**++,,--,,++***++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$##""!!!!``!!!!!""##$$%%&&''(())**++,,--..//0000000100//..--,,++**))((''&&%%$$########""!!```!!!""##$$%%%%%%%&&&&&&&&&%%$$##""!!````!!!""#####""!!``!!""##$$%%&&&&&'&''(())))))))**+++++**))((''&&%%$$##""!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????;;::99887766554433221100//..--,,++**))((''&&'''''''&&%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##$$%%&&''(())**++,,-,,++******+**))((''&&%%$$##""!!``!!""""###$$$######""""""""!!``!!""##$$%%&&''&'''''&&%%&&&&&&&&&''''&&%%$$$###""!!``!!!!!!!!!!!!!!!!!!!!!``````!!""##$$############$$%%&&''(())**++,,,,++**)**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$##"""!!``!!!!""##$$%%&&''(())**++,,--..//001111111100//..--,,++**))((''&&%%$$########""!!```!!!!""##$$%%&&&&&&&&&'''''&&%%$$##""!!!``!!!""#####""!!``!!""##$$%%&&''''''(())))))****+++++**))((''&&%%$$##""!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????<;;::99887766554433221100//..--,,++**))(('''''''((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####$$%%&&''(())**++,,-,,++****+++**))((''&&%%$$##""!!``!!"""""#####""""""""""""!!!``!!""##$$%%&&''''''(''&&&&&'&&'&&''''''&&%%$$$$##""!!!!!!!!!!!!!!!!!!!!!""!!`````!!""####""""""""####$$%%&&''(())**++,,++**)))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$##"""!!```!!"""##$$%%&&''(())**++,,--..//00111111121100//..--,,++**))((''&&%%$$$$$$$##""!!```!!!!"""##$$%%&&&&&&&'''''''''&&%%$$##""!!``!!""##$##""!!``!!""##$$%%&&'''('(())********++,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????<<;;::99887766554433221100//..--,,++**))((''(((((((''&&%%$$##""!!`͔`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""##$$%%&&''(())**++,,-,,++++++,++**))((''&&%%$$##""!!``!!!!!"""###""""""!!!!!!!!```!!""##$$%%&&''('(((((''&&'''''''''((((''&&%%%$$##"""!!"""""""""""""""""!!!!!!!!``!!!""##""""""""""""##$$%%&&''(())**++++**))())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$$###""!!``!!""##$$%%&&''(())**++,,--..//0011222222221100//..--,,++**))((''&&%%$$$$$$##""!!``!!!!""""##$$%%&&'''''''''((((''&&%%$$##""!!``!!""##$##""!!``!!""##$$%%&&''((((())******++++,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????=<<;;::99887766554433221100//..--,,++**))((((((()((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""##$$%%&&''(())**++,,-,,++++,,,++**))((''&&%%$$##""!!``!!!!!!"""""!!!!!!!!!!!!``!!""##$$%%&&''((((()(('''''(''(''(((((''&&%%$$##""!!!!!!!"""""""""""""!!!!!!!`````!!""""!!!!!!!!""""##$$%%&&''(())**++**))((())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!"""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//0011222223221100//..--,,++**))((''&&%%%%%$$##""!!``!!!""""###$$%%&&'''''''((((((((''&&%%$$##""!!``!!""##$##""!!``!!""##$$%%&&''((()())**++++++++,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????==<<;;::99887766554433221100//..--,,++**))(())))))((''&&%%$$##""!!```!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""##$$%%&&''(())**++,,-,,,,,,-,,++**))((''&&%%$$##""!!``````!!!"""!!!!!!`````````!!""##$$%%&&''(())))((''((((((((()((''&&%%$$##""!!!!!!!!!"""""##""!!!!```````!!""!!!!!!!!!!!!""##$$%%&&''(())****))(('(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//001122333333221100//..--,,++**))((''&&%%%%$$##""!!``!!""""####$$%%&&''((((((((())((''&&%%$$##""!!``!!""##$##""!!``!!""##$$%%&&''(())))**++++++,,,,++**))((''&&%%$$##""!!!``@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>==<<;;::99887766554433221100//..--,,++**)))))))*))((''&&%%$$##""!!``!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!""##$$%%&&''(())**++,,-,,,,---,,++**))((''&&%%$$##""!!!````!!!!!`````@`!!""##$$%%&&''(())))((((()(()(()((''&&%%$$##""!!```````!!!!!""""!!!!```!!!!````````!!!!""##$$%%&&''(())**))(('''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$##""!!`````!!""##$$%%&&''(())**++,,--..//00112233333433221100//..--,,++**))((''&&&&%%$$##""!!``!!"""####$$$%%&&''((((((())))))((''&&%%$$##""!!```!!""##$##""!!``!!""##$$%%&&''(())*)**++,,,,,,,,++**))((''&&%%$$##""!!``@``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))******))((''&&%%$$##""!!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,-----.--,,++**))((''&&%%$$##""!!!!``Ì`!!!`@`!!""##$$%%&&''(()))))(())))))))((''&&%%$$##""!!``!!!!!""!!````!!!````!!""##$$%%&&''(())))((''&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$##""!!```!!!!!""##$$%%&&''(())**++,,--..//0011223344444433221100//..--,,++**))((''&&&%%$$##""!!``!!""####$$$$%%&&''(()))))))))*))((''&&%%$$##""!!```!!""####""!!``!!""##$$%%&&''(())***++,,,,,,,,++**))((''&&%%$$##""!!`@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*******+**))((''&&%%$$##""!!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,---...--,,++**))((''&&%%$$##"""!!!``````!!""##$$%%&&''((())))))))*))))((''&&%%$$##""!!`````!!!!```!!``!!""##$$%%&&''(())((''&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$##""!!``!!!!!!""##$$%%&&''(())**++,,--..//001122334444454433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$%%%&&''(()))))))*****))((''&&%%$$##""!!``!``!!""###""!!```!!""##$$%%&&''(())***++,,-----,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**++++++**))((''&&%%$$##"""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##"""!!````!!""##$$%%&&''''(((())))****))((''&&%%$$##""!!``!!!``````````!!""##$$%%&&''(()((''&&%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$##""!!``!!""""##$$%%&&''(())**++,,--..//0011223344555554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$%%%%&&''(())*********+**))((''&&%%$$##""!!!!``!!""###""!!`€`!!""##$$%%&&''(())**+++,,-----,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++++++,++**))((''&&%%$$##""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$###""!!``!!!""##$$%%&&&&&''''(((())**+**))((''&&%%$$##""!!``!!!!``!`````!!`````ˆ`!!""##$$%%&&''((((''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$##""!!``!!"""##$$%%&&''(())**++,,--..//00112233445555554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%&&&''(())*******+++++**))((''&&%%$$##""!!!``!!""###""!!`````!!""##$$%%&&''(())**+++,,--..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++,,,,,,++**))((''&&%%$$#####$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$###""!!`````!!!""##$$$$%%&&&&&&''''((())**+**))((''&&%%$$##""!!```!!!!!!!!`````````````!````!!!!!!``!``!``!!""##$$%%&&''(((''&&%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$##""!!``!!""###$$%%&&''(())**++,,--..//001122334455666554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%%&&&&''(())**+++++++++,++**))((''&&%%$$##""!!``!!""####""!!!!```!!!""##$$%%&&''(())**++,,,--...--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,,,-,,++**))((''&&%%$$##$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$$##""!!!!!```!!"""##$$$#$$%%%%%&&&&''''(())**+**))((''&&%%$$##""!!!```!!""!!"!!!!``!!!!!!!!!``!!!!!!!""!!!`!!!`!!!````!!""##$$%%&&''(((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$##""!!````!!""###$$%%&&''(())**++,,--..//0011223344556666554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&&&'''(())**+++++++,,,,++**))((''&&%%$$##""!!``!!""##$##""!!!!!!!!""##$$%%&&''(())**++,,,--....--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,------,,++**))((''&&%%$$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""##$$%%&&''(())**++,,--..//00100//..--,,++**))((''&&%%$$$##""!!!!!!`````!!""#######$$%%%%%%&&&&'''(())**+**))((''&&%%$$##""!!!````!```!!""""""""!!!!!!!!!!!!!!``!!!!!!""""""!!!"!!!"!!```````!!!!""##$$%%&&''(((''&&%%$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$##""!!````!!!""##$$$%%&&''(())**++,,--..//001122334455667766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&&''''(())**++,,,,,,,,,,,++**))((''&&%%$$##""!!``!!""##$##""""!!!"""##$$%%&&''(())**++,,---../..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-------.--,,++**))((''&&%%$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%%$$##"""""!!!!!!``!!""####"##$$$$$%%%%&&&&''(())**+**))((''&&%%$$##"""!!!!``!!!!!!""##""#""""!!""""""""!!``!!"""""""##"""!"""!"""!!!!!!!!!!!""##$$%%&&''(((''&&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$##""!!````!!""##$$$%%&&''(())**++,,--..//0011223344556677766554433221100//..--,,++**))((''&&%%$$##""!!`†`!!"""##$$%%&&''''((())**++,,,,,,,---,,++**))((''&&%%$$##""!!``!!""##$##""""""""##$$%%&&''(())**++,,---..//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--......--,,++**))((''&&%%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%%$$##""""""!!!!!```!!""#""""""##$$$$$$%%%%&&&''(())**+**))((''&&%%$$##"""!!!!!!"!!!""########"""""""""""""!!`!!""""""######"""#"""#""!!!!!!!""""##$$%%&&''(((''&&%%$$##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$##""!!``!``!!""##$$%%%&&''(())**++,,--..//00112233445566777766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$%%&&'''(((())**++,,---------,,++**))((''&&%%$$##""!!``!!""#######"""###$$%%&&''(())**++,,--...///..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//......./..--,,++**))((''&&%%&&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##$$%%&&''(())**++,,--..//00112221100//..--,,++**))((''&&&%%$$#####""""""!!!```!!""#"""""!""#####$$$$%%%%&&''(())**+**))((''&&%%$$###""""!!""""""##$$##$####""########""!!!""#######$$###"###"###"""""""""""##$$%%&&''(((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$##""!!```!!!!""##$$%%%&&''(())**++,,--..//001122334455667787766554433221100//..--,,++**))((''&&%%$$##""!!```!!""###$$%%&&''(((()))**++,,---------,,++**))((''&&%%$$##""!!``!!!""###########$$%%&&''(())**++,,--...////..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..//////..--,,++**))((''&&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&&%%$$######"""""!!!``!!""#""!!!!!!""######$$$$%%%&&''(())**+**))((''&&%%$$###""""""#"""##$$$$$$$$#############""!""######$$$$$$###$###$##"""""""####$$%%&&''(((''&&%%$$##""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""###""!!`@`!!!!""##$$%%&&&''(())**++,,--..//0011223344556677887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""###$$%%&&''((())))**++,,--......--,,++**))((''&&%%$$##""!!``!!!"""##$$###$$$%%&&''(())**++,,--..///0//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///////0//..--,,++**))((''&&''''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$%%&&''(())**++,,--..//001122333221100//..--,,++**))(('''&&%%$$$$$######"""!!````!!""""!!!!!`!!"""""####$$$$%%&&''(())**+**))((''&&%%$$$####""######$$%%$$%$$$$##$$$$$$$$##"""##$$$$$$$%%$$$#$$$#$$$###########$$%%&&''(((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""##""!!````````!!""""##$$%%&&&''(())**++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##""!!`È`!!""##$$$%%&&''(())))***++,,--.......--,,++**))((''&&%%$$##""!!```!!"""##$$$$$$%%&&''(())**++,,--..///0//..--,,++**))((''&&%%$$##""!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//000000//..--,,++**))(('''''((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%&&''(())**++,,--..//00112233333221100//..--,,++**))(('''&&%%$$$$$$#####"""!!!!```!!"""!!`````!!""""""####$$$%%&&''(())**+**))((''&&%%$$$######$###$$%%%%%%%%$$$$$$$$$$$$$##"##$$$$$$%%%%%%$$$%$$$%$$#######$$$$%%&&''(((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"!!""#""!!````!`!!!`!!!""""##$$%%&&'''(())**++,,--..//0011223344556677889887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()))****++,,--..////..--,,++**))((''&&%%$$##""!!```!!!""##$$$%%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!```Ö`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110000000100//..--,,++**))((''(((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%&&''(())**++,,--..//0011223332333221100//..--,,++**))(((''&&%%%%%$$$$$$###""!!!!!`````!!!""!!``!!!!!""""####$$%%&&''(())**+**))((''&&%%%$$$$##$$$$$$%%&&%%&%%%%$$%%%%%%%%$$###$$%%%%%%%&&%%%$%%%$%%%$$$$$$$$$$$%%&&''(((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!""#""!!`````!!!!!!!!!!""####$$%%&&'''(())**++,,--..//00112233445566778899887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())***+++,,--../////..--,,++**))((''&&%%$$##""!!````!!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110011111100//..--,,++**))((((()))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&''(())**++,,--..//001122333222333221100//..--,,++**))(((''&&%%%%%%$$$$$###""""!!!!!!````!!!!!!```!!!!!!!!""""###$$%%&&''(())**+**))((''&&%%%$$$$$$%$$$%%&&&&&&&&%%%%%%%%%%%%%$$#$$%%%%%%&&&&&&%%%&%%%&%%$$$$$$$%%%%&&''((((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!``!!""#""!!!`!```!!!!"!"""!"""####$$%%&&''((())**++,,--..//001122334455667788999887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++++,,--..//00//..--,,++**))((''&&%%$$##""!!`ƀ```!!```!!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111111121100//..--,,++**))(())))**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&''(())**++,,--..//00112233322122333221100//..--,,++**)))((''&&&&&%%%%%%$$$##"""""!!!!!!!``!!``!!`@@@```````!!!!""""##$$%%&&''(())**+**))((''&&&%%%%$$%%%%%%&&''&&'&&&&%%&&&&&&&&%%$$$%%&&&&&&&''&&&%&&&%&&&%%%%%%%%%%%&&''(())((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!``!!""#""!!!!``!!!!""""""""""##$$$$%%&&''((())**++,,--..//0011223344556677889999887766554433221100//..--,,++**))((''&&%%$$##""!!``````!!!""##$$%%&&''(())**+++,,,--..//00//..--,,++**))((''&&%%$$##""!!``!!!!!``!!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322112222221100//..--,,++**)))))***++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''(())**++,,--..//0011223332211122333221100//..--,,++**)))((''&&&&&&%%%%%$$$####""""""!!!!``````````@@``!!!!"""##$$%%&&''(())**+**))((''&&&%%%%%%&%%%&&''''''''&&&&&&&&&&&&&%%$%%&&&&&&''''''&&&'&&&'&&%%%%%%%&&&&''(())))((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!``!!""##"""!!``!!!""""#"###"###$$$$%%&&''(()))**++,,--..//00112233445566778899::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!""##$$%%&&''(())**++,,,,--..//000//..--,,++**))((''&&%%$$##""!!``!!!!!!``!!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!``!!""##$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322222223221100//..--,,++**))****++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''(())**++,,--..//001122333221101122333221100//..--,,++***))(('''''&&&&&&%%%$$#####"""""""!!!````!!!````!!!!""##$$%%&&''(())**+**))(('''&&&&%%&&&&&&''((''(''''&&''''''''&&%%%&&'''''''(('''&'''&'''&&&&&&&&&&&''(())**))((''&&%%$$##""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##""!!``!!"""##########$$%%%%&&''(()))**++,,--..//00112233445566778899:::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!"""##$$%%&&''(())**++,,,---..//00100//..--,,++**))((''&&%%$$##""!!```!!"""!!``!!!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!````!!""##$$%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322333333221100//..--,,++*****+++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((())**++,,--..//00112233322110001122333221100//..--,,++***))((''''''&&&&&%%%$$$$######""""!!!!`````````!!!!!!!````!!!""##$$%%&&''(())**+**))(('''&&&&&&'&&&''(((((((('''''''''''''&&%&&''''''(((((('''('''(''&&&&&&&''''(())****))((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""#""!!``!!""###$#$$$#$$$%%%%&&''(())***++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!"""""##$$%%&&''(())**++,,----..//0011100//..--,,++**))((''&&%%$$##""!!``````!!""""!!```!!""##$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%%$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443333333433221100//..--,,++**++++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(())**++,,--..//001122333221100/001122333221100//..--,,+++**))(((((''''''&&&%%$$$$$#######"""!!!!!!!`````!!!!!!"""!!!!````!!""##$$%%&&''(())**+**))(((''''&&''''''(())(()((((''((((((((''&&&''((((((())((('((('((('''''''''''(())**++**))((''&&%%$$##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""#""!!``!!""##$$$$$$$$$$%%&&&&''(())***++,,--..//00112233445566778899::;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!``!!""""###$$%%&&''(())**++,,---...//00111100//..--,,++**))((''&&%%$$##"""!!!!!!```!!""##""!!``!!""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!``!!""##$$$$%$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443344444433221100//..--,,+++++,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))**++,,--..//001122333221100///001122333221100//..--,,+++**))(((((('''''&&&%%%%$$$$$$####""""!!!!!!!!!!!!!!"""""""!!!``!!""##$$%%&&''(())**+**))(((''''''('''(())))))))(((((((((((((''&''(((((())))))((()((()(('''''''(((())**++++**))((''&&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""""""!!``!!""##$$$%$%%%$%%%&&&&''(())**+++,,--..//00112233445566778899::;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!""#####$$%%&&''(())**++,,--....//00111100//..--,,++**))((''&&%%$$##""!""!!!!!!!!!""###""!!``!!""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!``!!!!""##$#$$$##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444444454433221100//..--,,++,,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))**++,,--..//001122333221100//.//001122333221100//..--,,,++**)))))(((((('''&&%%%%%$$$$$$$###"""""""!!!!!""""""###""""!!``!!""##$$%%&&''(())**++**)))((((''(((((())**))*))))(()))))))((('''(()))))))**)))()))()))((((((((((())**++,,++**))((''&&%%$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!"""!!```!!""##$$%%%%%%%%%%&&''''(())**+++,,--..//00112233445566778899::;;<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!""####$$$%%&&''(())**++,,--...///00111100//..--,,++**))((''&&%%$$##""!!!""""""!!!""####""!!``!!""##$$%%&&''(())**++,,--.../..--,,++**))((''&&%%$$##""!!````!!""####$####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655445555554433221100//..--,,,,,---..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****++,,--..//001122333221100//...//001122333221100//..--,,,++**))))))((((('''&&&&%%%%%%$$$$####""""""""""""""#######"""!!``!!""##$$$%%&&''(())**++**)))(((((()((())********))))))))))(((''''(()))((())***)))))))*))((((((())))**++,,,,++**))((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!"""!!```!!!""##$$%%%&%&&&%&&&''''(())**++,,,--..//00112233445566778899::;;<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$$$$%%&&''(())**++,,--..////00111100//..--,,++**))((''&&%%$$##""!!`!!"""""""""##$##""!!`…`!!""##$$%%&&''(())**++,,--......--,,++**))((''&&%%$$##""!!``!!""#"###""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655555556554433221100//..--,,----..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**++,,--..//001122333221100//..-..//001122333221100//..---,,++*****))))))(((''&&&&&%%%%%%%$$$#######"""""######$$$####""!!``!!!""##$$$%%&&''(())**++***))))(())))))**++**+****))***))(('''''''(()((((())***)))))***)))))))))))**++,,,,,,++**))((''&&%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""!!`````!!!!""##$$%%&&&&&&&&&&''(((())**++,,,--..//00112233445566778899::;;<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$%%%&&''(())**++,,--..///000111100//..--,,++**))((''&&%%$$##""!!``!!""##"""##$$##""!!``!!""##$$%%&&''(())**++,,--..-...--,,++**))((''&&%%$$##""!!``!!""""#""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655666666554433221100//..-----...//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++,,--..//001122333221100//..---..//001122333221100//..---,,++******)))))(((''''&&&&&&%%%%$$$$##############$$$$$$$###""!!````!!""###$$%%&&''(())**++***))))))*)))**+++++++*******))(('''&&&&''((('''(())))))())****)))))))****++,,,,,,,,++**))((''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""!!`````!!!!!!"""##$$%%&&&&&&&&&'''(((())**++,,---..//00112233445566778899::;;<<==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%&&''(())**++,,--..//000011221100//..--,,++**))((''&&%%$$##""!!`!!""#######$$$##""!!``!!""##$$%%&&''(())**++,,--.---..--,,,++**))((''&&%%$$##""!!``!!"!"""!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776666666766554433221100//..--....//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++,,--..//001122333221100//..--,--..//001122333221100//...--,,+++++******)))(('''''&&&&&&&%%%$$$$$$$#####$$$$$$%%%$$$$##""!!```!!""###$$%%&&''(())**+++****))******++++*****)))))))((''&&&&&&&''('''''(())))((())*************++,,,,++++++++**))((''&&%&&''(())**++,,--..//00112233445566778899::;;;<<===>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!"!!```!!!!!!!!""""##$$%%&%%%%%%%&&''(())))**++,,---..//00112233445566778899::;;<<====<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//000111221100//..--,,++**))((''&&%%$$##""!!!!!""##$$###$$%$$##""!!``!!""##$$%%&&''(())**++,,---,----,,++,++**))((''&&%%$$##""!!`@@@`!!!!"!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776677777766554433221100//.....///00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,--..//001122333221100//..--,,,--..//001122333221100//...--,,++++++*****)))((((''''''&&&&%%%%$$$$$$$$$$$$$$%%%%%%%$$$##""!!```!!""#"##$$%%&&''(())**+++******+***++++*****)))))))((''&&&%%%%&&'''&&&''(((((('(())*********++++,,,,++++++++++**))((''&&&''(())**++,,--..//00112233445566778899::::;;;<<<==>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!```!!!!!!""""""###$$%%&%%%%%%%%%&&''(())**++,,--...//00112233445566778899::;;<<==>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00111221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$$%%$$##""!!``!!""##$$%%&&''(())**++,,--,,,--,,++++++**))((''&&%%$$##""!!`@`!`!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988777777787766554433221100//..////00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,--..//001122333221100//..--,,+,,--..//001122333221100///..--,,,,,++++++***))((((('''''''&&&%%%%%%%$$$$$%%%%%%&&&%%%%$$##""!!````!!""#"""##$$%%&&''(())**+++++**++++++++**)))))(((((((''&&%%%%%%%&&'&&&&&''(((('''(())*******++++,,,,++************))((''&''(())**++,,--..//001122334455667788999::::::;;<<<===>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!```!!!""""""""####$$%%&%%$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$%%%$$##""!!``!!""##$$%%&&''(())**++,,-,,+,,,,++**+++**))((''&&%%$$##""!!!```!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988778888887766554433221100/////000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..----..//001122333221100//..--,,+++,,--..//001122333221100///..--,,,,,,+++++***))))((((((''''&&&&%%%%%%%%%%%%%%&&&&&&&%%%$$##""!!``!!!""#""!""##$$%%&&''(())**+++++++,+++++**)))))(((((((''&&%%%$$$$%%&&&%%%&&''''''&''(())*******++++,+++**************))(('''(())**++,,--..//00112233445566778888999999:::;;;<<===>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!``!!""""""######$$$%%&%%$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<====<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!!``!!"!""##$$%%&%%$$##""!!``!!""##$$%%&&''(())**++,,,,+++,,++****+**))((''&&%%$$##""!!``````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988888889887766554433221100//0000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--..//001122333221100//..--,,++*++,,--..//0011223332211000//..-----,,,,,,+++**)))))((((((('''&&&&&&&%%%%%&&&&&&'''&&&&%%$$##""!!```!!!""#""!!!""##$$%%&&''(())**++,++,,,,++**))((((('''''''&&%%$$$$$$$%%&%%%%%&&''''&&&''(()))))))**++++++**))))))))))))))))(('(())**++,,--..//00112233445566778888888999999::;;;<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!"""########$$$$$%%%%$$#######$$%%&&''(())**++,,--..//00112233445566778899::;;<<====<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!``!`!!"!!!""##$$%%%$$##""!!``!!""##$$%%&&''(())**++,,++*++++**))***))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99889999998877665544332211000001112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//....//001122333221100//..--,,++***++,,--..//0011223332211000//..------,,,,,+++****))))))((((''''&&&&&&&&&&&&&&'''''''&&&%%$$##""!!!````````!!""#""!!`!!""##$$%%&&''(())**++,,,,,++**))((((('''''''&&%%$$$####$$%%%$$$%%&&&&&&%&&''(()))))))****+***))))))))))))))))))((())**++,,--..//0011223344556677777777888888999:::;;<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```````````!!""######$$$$$$%$$$$%$$#########$$%%&&''(())**++,,--..//00112233445566778899::;;<<===<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!``!!"!!`!!""##$$%%%$$##""!!``!!""##$$%%&&''(())**++,++***++**))))***))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9999999:9988776655443322110011112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..//001122333221100//..--,,++**)**++,,--..//0011223332211100//.....------,,,++*****)))))))((('''''''&&&&&''''''(((''''&&%%$$##""!!!!!!!!!```!!""""!!``!!""##$$%%&&''(())**++,,,++**))(('''''&&&&&&&%%$$#######$$%$$$$$%%&&&&%%%&&''((((((())******))(((((((((((((((((((())**++,,--..//00112233445566777777777788888899:::;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!``!!!!!!!""###$$$$$$$$%%$$#$$$$##"""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!!!``!!""##$$%%$$##""!!``!!""##$$%%&&''(())**++++**)****))(())***))((''&&%%$$##""!!`@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99::::::99887766554433221111122233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100////001122333221100//..--,,++**)))**++,,--..//0011223332211100//......-----,,,++++******))))((((''''''''''''''((((((('''&&%%$$##"""!!!!!!!!!````!!""#""!!``!!""##$$%%&&''(())**++,++**))(('''''&&&&&&&%%$$###""""##$$$###$$%%%%%%$%%&&''((((((())))*)))((((((((((((((((((''(())**++,,--..//001122334455666666666777777888999::;;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!````!!!!!!!""##$$$$$$$$$$$$$####$##"""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!!!``!!""##$$%%%$$##""!!```!!""##$$%%&&''(())**+++**)))**))(((())**))((''&&%%$$##""!!`@‰@``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::::::::;::998877665544332211222233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//001122333221100//..--,,++**))())**++,,--..//0011223332221100/////......---,,+++++*******)))((((((('''''(((((()))((((''&&%%$$##"""""""""!!!!!```!!""#""!!``!!""##$$%%&&''(())**++,++**))((''&&&&&%%%%%%%$$##"""""""##$#####$$%%%%$$$%%&&'''''''(())))))((''''''''''''''''''''(())**++,,--..//001122334455666666666677777788999:::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!`ɒ```````!!!!"""""""##$$$%$$$##$$$$##"####""!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!"!!`!!""##$$%%%$$##""!!!``````!!""##$$%%&&''(())**++**))())))((''(())*))((''&&%%$$##""!!`@`!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99::;;;;;::9988776655443322222333445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100001122333221100//..--,,++**))((())**++,,--..//0011223332221100//////.....---,,,,++++++****))))(((((((((((((()))))))(((''&&%%$$###"""""""""!!!!!````!!""#""!!!`!!""##$$%%&&''(())**++,++**))((''&&&&&%%%%%%%$$##"""!!!!""###"""##$$$$$$#$$%%&&'''''''(((()(((''''''''''''''''''&&''(())**++,,--..//001122334455555555566666677788899:::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!`΍`!!!!!!!!!!"""""""##$$$$$$$########""""#""!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<;;::99887766554433221100//..--,,++**))((''&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!""!!!""##$$%%%$$##""!!````!``!!""##$$%%&&''(())****))((())((''''(())*))((''&&%%$$##""!!`@@`!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9999::;;;;;::99887766554433223333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211001122333221100//..--,,++**))(('(())**++,,--..//0011223333221100000//////...--,,,,,+++++++***)))))))((((())))))***))))((''&&%%$$#########"""""!!!!``````!!"""!!``!!""##$$%%&&''(())**++,++**))((''&&%%%%%$$$$$$$##""!!!!!!!""#"""""##$$$$###$$%%&&&&&&&''((((((''&&&&&&&&&&&&&&&&&&&&''(())**++,,--..//0011223344555555555566666677888999::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!`dž`!!!!!!!!""""#######$$$$$$###""####""!""""!!```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<;;::99887766554433221100//..--,,++**))((''&&&%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!!!"!""##$$%%%$$##""!!``@`!``!!""##$$%%&&''(())***))(('((((''&&''(()))((''&&%%$$##""!!!!`@@@@@@``````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998899::;;;;;::998877665544333334445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111122333221100//..--,,++**))(('''(())**++,,--..//00112233332211000000/////...----,,,,,,++++****))))))))))))))*******)))((''&&%%$$$#########"""""!!!!!!!``!!""!!``!!""##$$%%&&''(())**+++**))((''&&%%%%%$$$$$$$##""!!!````!!"""!!!""######"##$$%%&&&&&&&''''('''&&&&&&&&&&&&&&&&&&%%&&''(())**++,,--..//0011223344444444455555566677788999::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!`Â`!!""""""""""#######$$$$#####""""""""!!!!"!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;::99887766554433221100//..--,,++**))((''&&%%%$%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!!!!""##$$%%%%$$##""!!```!``!!""##$$%%&&''(())**))(('''((''&&&&''(()((''&&%%$$##""!!!!!`@@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99888899:::;;;;::9988776655443344445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221122333221100//..--,,++**))((''&''(())**++,,--..//00112233332211111000000///..-----,,,,,,,+++*******)))))******+++****))((''&&%%$$$$$$$$$#####""""!!!!!``!!""!!``!!""##$$%%&&''(())**++**))((''&&%%$$$$$#######""!!```!!"!!!!!""####"""##$$%%%%%%%&&''''''&&%%%%%%%%%%%%%%%%%%%%&&''(())**++,,--..//0011223344444444445555556677788899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!`````!!""""""""####$$$$#########"""!!""""!!`!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%%$$$%$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!``!!""##$$%%%$$##""!!``!!``!!""##$$%%&&''(())*))((''&''''&&%%&&''(((''&&%%$$##""!!``!!!`@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988778899:::;;;;::99887766554444455566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332222333221100//..--,,++**))((''&&&''(())**++,,--..//00112233332211111100000///....------,,,,++++**************+++++++***))((''&&%%%$$$$$$$$$#####""""""!!```!!""!!``!!""##$$%%&&''((()))****))((''&&%%$$$$$#######""!!``!!!```!!""""""!""##$$%%%%%%%&&&&'&&&%%%%%%%%%%%%%%%%%%$$%%&&''(())**++,,--..//0011223333333334444445556667788899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!```!!!!!""#####################"""""!!!!!!!!```!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$$#$$$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!``!!""##$$%%%$$##""!!``!!!```````!!""##$$%%&&''(())*))((''&&&''&&%%%%&&''(''&&%%$$##""!!```!`@@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988777788999::;;;;::998877665544555566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322333221100//..--,,++**))((''&&%&&''(())**++,,--..//001122333322222111111000//.....-------,,,+++++++*****++++++,,,++++**))((''&&%%%%%%%%%$$$$$####"""""!!`````!!""!!!!""##$$%%&&'''((((())**))((''&&%%$$#####""""""""!!``!!``!!""""!!!""##$$$$$$$%%&&&&&&%%$$$$$$$$$$$$$$$$$$$$%%&&''(())**++,,--..//0011223333333333444444556667778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!""################"""""""""!!!``!!!!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$$###$$$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%%$$##""!!``!!!!!!!!!``!!""##$$%%&&''(())))((''&&%&&&&%%$$%%&&''''&&%%$$##""!!```@@@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877667788999::;;;;::9988776655555666778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433333221100//..--,,++**))((''&&%%%&&''(())**++,,--..//001122333322222211111000////......----,,,,++++++++++++++,,,,,,,+++**))((''&&&%%%%%%%%%$$$$$######""!!!``!``!!"""!!""##$$%%&&'''''''((())))((''&&%%$$#####"""""""!!!!``!``!!!!!!`!!""##$$$$$$$%%%%&%%%$$$$$$$$$$$$$$$$$$##$$%%&&''(())**++,,--..//0011222222222333333444555667778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!"""""####$$$###"""""""""""""!!!!!````!!`````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$###"##$$$##""!!``!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!``!``!!""##$$%%%$$##""!!````!!"!!!!!!``!!""##$$%%&&''(()))((''&&%%%&&%%$$$$%%&&'''&&%%$$##""!!``!`@@@@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766667788899::;;;;::99887766556666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544333221100//..--,,++**))((''&&%%$%%&&''(())**++,,--..//001122333333322222211100/////.......---,,,,,,,+++++,,,,,,---,,,,++**))((''&&&&&&&&&%%%%%$$$$#####""!!!``!!`!!""#""""##$$%%&&'&&'&'''''(())((''&&%%$$##"""""!!!!!!!!```!!``!!!!!``!!""#######$$%%%%%%$$####################$$%%&&''(())**++,,--..//0011222222222233333344555666778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""""""##########""""""""!!!!!!!!!```!!```!!``!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$###"""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!```!!!!!""##$$%%%$$##""!!``!!"""""""!!``!!""##$$%%&&''(())((''&&%%$%%%%$$##$$%%&&''&&%%$$##""!!``!!``@@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655667788899::;;;;::998877666667778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%&&''(())**++,,--..//00112233333333222221110000//////....----,,,,,,,,,,,,,,-------,,,++**))(('''&&&&&&&&&%%%%%$$$$$$##""!!``!!!""###""##$$%%&&'&&&&&&&&'''((((''&&%%$$##"""""!!!!!!!```!!!``````!!`!!""#########$$$$%$$$##################""##$$%%&&''(())**++,,--..//0011111111122222233344455666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!"""#######""###"""!!!!!!!!!!!!!````!!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$##"""!""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//00100//..--,,++**))((''&&%%$$##""!!``!!"!!""##$$%%%%$$##""!!````!!""""""""!!``!!""##$$%%&&''(())((''&&%%$$$%%$$####$$%%&&&&%%$$##""!!```!!!!!``@@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665555667778899::;;;;::9988776677778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#$$%%&&''(())**++,,--..//001122334443333332221100000///////...-------,,,,,------...----,,++**))(('''''''''&&&&&%%%%$$$$$##""!!``!!""##$####$$%%&&'&&%%&%&&&&&''((''&&%%$$##""!!!!!````````!!!````!!""#""""""""##$$$$$$##""""""""""""""""""""##$$%%&&''(())**++,,--..//0011111111112222223344455566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""####""""""""""!!!!!!!!``````ǀ`!!!!!""!!"""""""##$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//00100//..--,,++**))((''&&%%$$##""!!``!!""""##$$%%&&%%$$##""!!`!``!!""#####""!!``!!""##$$%%&&''(()((''&&%%$$#$$$$##""##$$%%&&%%$$##""!!```!!""!!!!``΂@@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554455667778899::;;;;::99887777788899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###$$%%&&''(())**++,,--..//001122334444333332221111000000////....--------------.......---,,++**))((('''''''''&&&&&%%%%%%$$##""!!``!!""##$$$##$$%%&&&&&%%%%%%%%&&&''''&&%%$$##""!!!!!``!!!```!!"""""""""""####$###""""""""""""""""""!!""##$$%%&&''(())**++,,--..//0000000001111112223334455566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""""""!!"""!!!```````ȍ`!!""""""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`!!""##$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!```!!"""##$$%%&&&&%%$$##""!!!!`@†`!!""######""!!```!!""##$$%%&&''(()((''&&%%$$###$$##""""##$$%%&%%$$##""!!``!!"!!!!!`@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444455666778899::;;;;::998877888899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"##$$%%&&''(())**++,,--..//00112233444444433322111110000000///.......-----......///....--,,++**))((((((((('''''&&&&%%%%%$$##""!!``!!""##$$%$$$$%%&&&&&%%$$%$%%%%%&&''&&%%$$##""!!`````ɔ````!!""!!!!!!!!""######""!!!!!!!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//0000000000111111223334445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""""!!!!!!!!!!`…`!!""""##""#######$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!""##$##""!!``!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''&&%%$$##""!!!`@`!!""##$$$##""!!``!!""##$$%%&&''((((''&&%%$$##"####""!!""##$$%%%%$$##""!!```!!"!!!!!!`@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544334455666778899::;;;;::9988888999::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233444444433322221111110000////..............///////...--,,++**)))((((((((('''''&&&&&&%%$$##""!!``!!""##$$%$$%%&&&&%%%$$$$$$$$%%%&&&&%%$$##""!!``!!!!!!!!!!!!""""#"""!!!!!!!!!!!!!!!!!!``!!""##$$%%&&''(())**++,,--../////////000000111222334445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!"!!!!!!``!!!```!!""############$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!``!!""##$$##""!!``!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&'''&&%%$$##""!!``!!""##$$$##""!!``!!""##$$%%&&''((((''&&%%$$##"""##""!!!!""##$$%%$$##""!!``!!"!!```!!`@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433334455566778899::;;;;::99889999::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!""##$$%%&&''(())**++,,--..//001122334455544433222221111111000///////.....//////000////..--,,++**)))))))))(((((''''&&&%%$$##""!!``!!""##$$%%%&&&%%%%$$##$#$$$$$%%&&%%$$##""!!``!!!````````!!""""""!!``````````````````!!""##$$%%&&''(())**++,,--..//////////00000011222333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!!!```````!!""##$$##$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!`!!"""##$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''&&%%$$##""!!``!!""##$$%$$##""!!```!!""##$$%%&&''((((''&&%%$$##""!""""!!``!!""##$$$$##""!!```!!!``!`@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322334455566778899::;;;;::99999:::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//0011223344555444333322222211110000//////////////0000000///..--,,++***)))))))))(((((''''&&%%$$##""!!```!!""##$$%%%%%%%%$$$########$$$%%%%$$##""!!``````!!!!"!!!`ʇ`!!""##$$%%&&''(())**++,,--..........//////00011122333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!```!````!!""##$$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!!!"""""##$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'''&&%%$$##""!!```!!""##$$%$$##""!!```!`!!""##$$%%&&''(((''&&%%$$##""!!!""!!``!!""##$$$$##""!!``!!``!!`ď@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332222334445566778899::;;;;::99::::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445555443333322222221110000000/////0000001110000//..--,,++*********)))))((((''&&%%$$##""!!``!!""##$$$$%%%$$$$##""#"#####$$%%$$##""!!`π`!!!!!!`@`!!""##$$%%&&''(())**++,,--............//////0011122233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!````!!""##$$$%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!"!""""!""##$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''&&%%$$##""!!```!!""##$$%%%$$##""!!```!!``!!""##$$%%&&''(''&&%%$$##""!!`!!""!!``!!""##$$$$##""!!``!!``!!!`ŀ@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221122334445566778899::;;;;:::::;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445555444433333322221111000000000000001111111000//..--,,+++*********)))))((''&&%%$$##""!!``!!"""##$$$$$$$$###""""""""###$$%$$##""!!````!``@@@@`!!""##$$%%&&''(())**++,,------------......///0001122233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""!!`€`!!""##$$%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!""""""!!!""####""!!``!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'''&&%%$$##""!!``!!""##$$%%%%$$##""!!``!!!!``!!""##$$%%&&'''&&%%$$##""!!``!!""!!!!""##$$$$##""!!``!!!!!!!!``@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111122333445566778899::;;;;::;;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455655444443333333222111111100000111111222111100//..--,,+++++++++*****))((''&&%%$$##""!!``!!"""####$$$####""!!"!"""""##$$$##""!!``@@@`!!""##$$%%&&''(())**++,,--------------......//0001112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""""!!``!!""##$$%%&&&&&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""#"""!!`!!""####""!!``!!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''(''&&%%$$##""!!```!!!""##$$%%%%$$##""!!````!!!"!!``!!""##$$%%&&''''&&%%$$##""!!``!!"""!!""##$$$$##""!!```!!""!!""!!``!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211001122333445566778899::;;;;;;;<<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566655554444443333222211111111111111222222211100//..--,,,+++++++++***))((''&&%%$$##""!!``!!!""########"""!!!!!!!!"""##$$$##""!!`@@Ã`!!""##$$%%&&''(())**++,,--,,,,,,,,,,------...///001112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##""!!```!!""##$$%%&&&&&&''(())**++,,--..//00112233445566778899::;;<<===<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"##""!!``!!""###""!!```!!!!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(((''&&%%$$##""!!``!!!!""##$$%%%%$$##""!!!````!!!""""!!!!""##$$%%&&''((''&&%%$$##""!!`!!""#""""##$$$$##""!!```!!!"""""!!"!!!``@``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100001122233445566778899::;;;;<<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//0011223344556676655555444444433322222221111122222233322221100//..--,,,,,,,,,+++**))((''&&%%$$##""!!``!!!""""###""""!!``!`!!!!!""###$##""!!`@@`!!""##$$%%&&''(())**++,,,,,,,,,,,,,,,,,------..///000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#######""!!``!!!""##$$%%&&''''''(())**++,,--..//00112233445566778899::;;<<==>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####""!!``!!""###""!!``!````!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!"""##$$%%&&''((''&&%%$$##""!!``!``!!""##$$%%%%$$##""!!``!```!!!!"""#""!!""##$$%%&&''((((''&&%%$$##""!!!""###""##$$%$$##""!!``!!!!""#""!!!!!!`ƊÌ@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//001122233445566778899::;;<<<===>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!""##$$%%&&''(())**++,,--..//001122334455667776666555555444433332222222222222233333332221100//..---,,,,,,,,,++**))((''&&%%$$##""!!`````!!""""""""!!!`````!!!""####""!!!`@@``!!""##$$%%&&''(())**++++,,++++++++++,,,,,,---...//000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###$$##""!!```!!""##$$%%&&''''''(())**++,,--..//00112233445566778899::;;<<==>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#$##""!!`!!""##$##""!!``!``!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!""##$$%%&&''''&&%%$$##""!!````!!""##$$%%%%$$##""!!`!!``!!"""####""""##$$%%&&''(())((''&&%%$$##""!""##$####$$%$$##""!!``!!!"""#""!!``!!!`@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100////001112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778776666655555554443333333222223333334443333221100//..---------,,,++**))((''&&%%$$##""!!!!``!!!!"""!!!!`À``!!"""#""!!``@@`!!""##$$%%&&''(())**+++++++++++++++++,,,,,,--...///00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$##""!!!``!!""##$$%%&&''((((())**++,,--..//00112233445566778899::;;<<==>>?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$##""!!!""##$$##""!!``!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!!!""##$$%%&&'''&&%%$$##""!!`@@```!!""##$$%%&%%$$##""!!!!``!!"""###$##""##$$%%&&''(())))((''&&%%$$##"""##$$$##$$%$$##""!!``!!""""#""!!``!!`@@``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..//001112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"##$$%%&&''(())**++,,--..//0011223344556677888777766666655554444333333333333334444444333221100//...---------,,++**))((''&&%%$$##""!!!!````!!!!!!!!```Ύ`!!""""!!`@@`!!""###$$%%&&''(())****++**********++++++,,,---..///00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%$$##""!!``!!""##$$%%&&''(((())**++,,--..//00112233445566778899::;;<<==>>???>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$%$$##""!""##$$##""!!``!```!!""##$$%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'&&%%$$##""!!``!!""##$$%%&&%%$$##""!!!``!!""##$$$$####$$%%&&''(())**))((''&&%%$$##"##$$%$$$$%$$##""!!``!!""####""!!``!!!!`@@@@@@@``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//....//000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###$$%%&&''(())**++,,--..//001122334455667788988777776666666555444444433333444444555444433221100//.........---,,++**))((''&&%%$$##""""!!!!``````!!!`````Ά`!!!""!!`@`!!""""##$$%%&&''(())*****************++++++,,---...//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%%$$##""!!``!!""##$$%%&&''(()))**++,,--..//00112233445566778899::;;<<==>>?????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$###"""##$$$$##""!!```````!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&%%$$##""!!```!!""##$$%%&&&%%$$##""!!```!!""##$$$%$$##$$%%&&''(())****))((''&&%%$$###$$%%%$$%$$##""!!``!!""###$##""!!!!""!!`@@@@@Ő`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--..//000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#$$%%&&''(())**++,,--..//00112233445566778899988887777776666555544444444444444555555544433221100///.........--,,++**))((''&&%%$$##""""!!!!!!````ł`!``!!!!!``!!!""""##$$%%&&''(())))**))))))))))******+++,,,--...//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"##"##$$%$$##""!!```!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&&&%%$$##""!!````!!""##$$%%&&&%%$$##""!!```!!!!""##$$%%%$$$$%%&&''(())**++**))((''&&%%$$#$$%%&%%%$$##""!!``!!""##$$$$##""!!""""!!`@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..----..///00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899:9988888777777766655555554444455555566655554433221100/////////...--,,++**))((''&&%%$$####""""!!!!``````!!```!!!!""##$$%%&&''(()))))))))))))))))******++,,,---..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""###$$%%%$$##""!!````!```!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!``!!!!!""##$$%%&&&&%%$$##""!!!``!!""##$$%%&&&%%$$##""!!```!!!``!!""##$$%%%$$%%&&''(())**++++**))((''&&%%$$$%%&&%%$$##""!!``!!""##$$$%$$##""""##""!!`@@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,--..///00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$%%&&''(())**++,,--..//00112233445566778899:::99998888887777666655555555555555666666655544332211000/////////..--,,++**))((''&&%%$$####"""""!!`ŋ`!`````!!!!""##$$%%&&''(((())(((((((((())))))***+++,,---..//00112233445566778899::;;<<==>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!""##$$%%%$$##""!!``!!!!!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!`!!!!`!!""##$$%%&&&&%%$$##""!!``!!""##$$%%&&&%%$$##""!!``!!!``!!""##$$%%%%%&&''(())**++,,++**))((''&&%%$%%&&%%$$##""!!``!!""##$$%%%%$$##""###"""!!``@@@̊`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,--...//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%&&''(())**++,,--..//00112233445566778899::;::99999888888877766666665555566666677766665544332211000000000///..--,,++**))((''&&%%$$$$###""!!``!````!!""##$$%%&&''((((((((((((((((())))))**+++,,,--..//00112233445566778899::;;<<==>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%%$$##""!!``!!!!!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!!````!!""##$$%%&&&%%$$##""!!``!!""##$$%%&&%%$$##""!!``!!!!``!!""##$$%%%%&&''(())**++,,,,++**))((''&&%%%&&%%$$##""!!``!!""##$$%%%&%%$$#####""!!!`Á@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++,,--...//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%&&''(())**++,,--..//00112233445566778899::;;;::::9999998888777766666666666666777777766655443322111000000000//..--,,++**))((''&&%%$$$$###""!!``!``!!""##$$%%&&''''((''''''''''(((((()))***++,,,--..//00112233445566778899::;;<<===>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!""##$$%%%$$##""!!``!!""!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&&%%$$##""!!``!!""##$$%%&%%$$##""!!```!!""!!``!!""##$$%%&&&&''(())**++,,--,,++**))((''&&%&&&%%$$##""!!```!!""##$$%%&&&&%%$$###""!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++,,---..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&''(())**++,,--..//00112233445566778899::;;<;;:::::99999998887777777666667777778887777665544332211111111100//..--,,++**))(((''&&%%%%$$$##""!!``!!```!!""##$$%%&&'''''''''''''''''(((((())***+++,,--..//00112233445566778899::;;<<===>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%$$##""!!``!!"!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&%%$$##""!!``!!""##$$%%&&%%$$##""!!``!!!""""!!!!""##$$%%&&&&''(())**++,,----,,++**))((''&&&&&%%$$##""!!``!!""##$$%%&&&&&%%$$##""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>==>>>>??????????????????????>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**++,,---..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&''(())**++,,--..//00112233445566778899::;;<<<;;;;::::::999988887777777777777788888887776655443322211111100//..--,,++**))(('((''&&%%%%$$$##""!!```@`!!!````!!""##$$%%&&&&''&&&&&&&&&&''''''((()))**+++,,--..//00112233445566778899::;;<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%$$##""!!```!!""!!``!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&%%$$##""!!``!!""##$$%%&&&%%$$##""!!!!!""##""!!""##$$%%&&''''(())**++,,--..--,,++**))((''&&&%%$$##""!!``!!""###$$%%&&&&%%$$##""!!`ď`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<========>>>>???????????????????>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****++,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''(())**++,,--..//00112233445566778899::;;<<=<<;;;;;:::::::99988888887777788888899988887766554433222221100//..--,,++**))(('''((''&&&&%%%$$##""!!!!```````!!!!````!!""##$$%%&&&&&&&&&&&&&&&&&''''''(()))***++,,--..//00112233445566778899::;;<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&%%$$##""!!``!!"""!!``!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&%%$$##""!!``!!""##$$%%%&&&%%$$##""!!"""####""""##$$%%&&''''(())**++,,--....--,,++**))((''&&%%$$##""!!``!!""#""##$$%%&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<====<<====>>>>????????????????>>=>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>==<<;;::99887766554433221100//..--,,++**))**++,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('(())**++,,--..//00112233445566778899::;;<<===<<<<;;;;;;::::999988888888888888999999988877665544333221100//..--,,++**))((''&''((''&&&&%%%$$##""!!!!`!!`!``!!!!!``!!""##$$%%%%&&%%%%%%%%%%&&&&&&'''((())***++,,--..//00112233445566778899::;;;<<==>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&&%%$$##""!!````!!""#""!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&%%$$##""!!```!!"""##$$$%%&&&%%$$##"""""##$$##""##$$%%&&''(((())**++,,--../..--,,++**))((''&&%%$$##""!!``!!""""""##$$%%%%$$$##""!!`Ì`!!""##$$%%&&''(())**++,,--..//001122334455667788999::;;<<=<<<<<<====>>>>>>???????????>>===>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????==<<;;::99887766554433221100//..--,,++**))))**+++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((())**++,,--..//00112233445566778899::;;<<==>==<<<<<;;;;;;;:::999999988888999999:::999887766554433221100//..--,,++**))((''&&&''((''''&&&%%$$##""""!!!!!``!!"!!!``!!""##$$%%%%%%%%%%%%%%%%%&&&&&&''((()))**++,,--..//00112233445566778899::;;;<<==>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!""##$$%%&&'&&%%$$##""!!!!!!""##""!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&&&%%$$##""!!``!``!!"""##$$$%%&&&%%$$##""###$$$$####$$%%&&''(((())**++,,--../....--,,++**))((''&&%%$$##""!!```!!"""!!""##$$%%$$#$##""!!`ň``!!""##$$%%&&''(())**++,,--...//001122334455667788999::;;<<<<;;<<<<====>>>>>>>???????>>==<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????=<<;;::99887766554433221100//..--,,++**))(())**+++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))())**++,,--..//00112233445566778899::;;<<==>>>====<<<<<<;;;;::::99999999999999:::::99887766554433221100//..--,,++**))((''&&%&&''((''''&&&%%$$##""""!"!!```!!""!!``!!""##$$$$%%$$$$$$$$$$%%%%%%&&&'''(()))**++,,--..//00112233445566778899:::;;<<=====>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$%%&&'''&&%%$$##""!!!!""###""!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%&&&%%$$##""!!!!``!!!!""###$$%%&&&%%$$#####$$%%$$##$$%%&&''(())))**++,,--.......--,,++**))((''&&%%$$##""!!``!!"!!!!""##$$$$####""!!``````!!""##$$%%&&''(())**++,,--.-..//001122334455667788899::;;<;;;;;;<<<<======>>>>>>>??>>==<<<==>>?????????????????????????????????????????????>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????<<;;::99887766554433221100//..--,,++**))(((())***++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))**++,,--..//00112233445566778899::;;<<==>>?>>=====<<<<<<<;;;:::::::99999::::::::99887766554433221100//..--,,++**))((''&&%%%&&''(((('''&&%%$$####""""!!````!!""""!!``!!"""##$$$$$$$$$$$$$$$$$%%%%%%&&'''((())**++,,--..//00112233445566778899:::;;<<======>>>>>>>?????>>????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"##$$%%&&''(''&&%%$$##""""""####""!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%&&&%%$$##""!!!!```!!!!!""###$$%%&&&%%$$##$$$%%%%$$$$%%&&''(())))**++,,--.....-----,,++**))((''&&%%$$##""!!``!!!``!!""##$$##"#""!!```!``!!""##$$%%&&''(())**++,,-----..//001122334455667788899::;;;;::;;;;<<<<=======>>>>>>>==<<;<<==>>???????????????????????????????????????????>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????<;;::99887766554433221100//..--,,++**))((''(())***++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)**++,,--..//00112233445566778899::;;<<==>>???>>>>======<<<<;;;;::::::::::::::;::99887766554433221100//..--,,++**))((''&&%%$%%&&''(((('''&&%%$$####"""!!``!!``!!""##""!!``!!!!""####$$##########$$$$$$%%%&&&''((())**++,,--..//001122334455667788999::;;<<<<<====>>>>>>>>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###$$%%&&''(((''&&%%$$##""""##$##""!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!""###$$$%%%%%%%$$##""""!!``!``!!"""##$$%%&&&%%$$$$$%%&&%%$$%%&&''''(())**++,,--....------,,++**))((''&&%%$$##""!!```!!!``!!""####"""""!!``````!``!!""##$$%%&&''(())**++,,---,--..//001122334455667778899::;::::::;;;;<<<<<<=======>>==<<;;;<<==>>?????????????????????????????????????>>>>>>==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????;;::99887766554433221100//..--,,++**))((''''(()))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***++,,--..//00112233445566778899::;;<<==>>?????>>>>>=======<<<;;;;;;;:::::;;;;::99887766554433221100//..--,,++**))((''&&%%$$$%%&&''(((((''&&%%$$$$###""!!`!!!!````!!""####""!!```!!!""#################$$$$$$%%&&&'''(())**++,,--..//001122334455667788999::;;<<<<<<=======>>>>>==>>>>>?????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#$$%%&&''(()((''&&%%$$######$$##""!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!""####$$$%%%%%%%$$##""""!!```!!"""##$$%%&&&%%$$%%%&&&&%%%%&&''''''(())**++,,--..---,,,,,++**))((''&&%%$$##""!!``!!!``!!""###""!"""!!``!`!!!!``!!""##$$%%&&''(())**++,,,-,,,--..//001122334455667778899::::99::::;;;;<<<<<<<=======<<;;:;;<<==>>???????????????????????????????????>>>>>>====>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????;::99887766554433221100//..--,,++**))((''&&''(()))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*++,,--..//00112233445566778899::;;<<==>>?????????>>>>>>====<<<<;;;;;;;;;;;;;::99887766554433221100//..--,,++**))((''&&%%$$#$$%%&&''(((((''&&%%$$$$###""!!!""!!!!!!""##$##""!!```!!""""##""""""""""######$$$%%%&&'''(())**++,,--..//001122334455667788899::;;;;;<<<<===============>>>>????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%&&''(()))((''&&%%$$####$$$##""!!``!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$##""!!``!!""#""###$$$$$$$$$$$##""!!```!!!""##$$%%&&&%%%%%&&''&&%%&&''''&&''(())**++,,----,,,,,,++**))((''&&&%%$$##""!!``!!!``!!""###""!!!""!!```!!!!!!!`@`!!""##$$%%&&''(())**++,,+,,,+,,--..//001122334455666778899:999999::::;;;;;;<<<<<<<==<<;;:::;;<<==>>?????????????????????????????????>>======<<==>>?????????>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????::99887766554433221100//..--,,++**))((''&&&&''((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++,,--..//00112233445566778899::;;<<==>>????????????>>>>>>>===<<<<<<<;;;;;;;::99887766554433221100//..--,,++**))((''&&%%$$###$$%%&&''(()((''&&%%%%$$$##""!""""!!!!""##$$$##""!!``!!"""""""""""""""""######$$%%%&&&''(())**++,,--..//001122334455667788899::;;;;;;<<<<<<<=====<<=====>>>>???????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$%%&&''(())*))((''&&%%$$$$$$%$$##""!!``!!""##$$%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%$$##""!!``!!""#""""###$$$$$$$$$##""!!```!!!""##$$%%&&&%%&&&''''&&&&''''&&&&''(())**++,,--,,,+++++**))((''&&&&%%$$##""!!`ǁ`!!!!!""###""!!`!!!!``!!"""!!`Ϙ``!!""##$$%%&&''(())**++,,+++,+++,,--..//00112233445566677889999889999::::;;;;;;;<<<<<<<;;::9::;;<<==>>???????????????????????????????>>======<<<<==>>>>?????>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????:99887766554433221100//..--,,++**))((''&&%%&&''((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+,,--..//00112233445566778899::;;<<==>>?????????????????>>>>====<<<<<<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"##$$%%&&''(()((''&&%%%%$$$##"""##""""""##$$%$$##""!!``!!!!!""!!!!!!!!!!""""""###$$$%%&&&''(())**++,,--..//001122334455667778899:::::;;;;<<<<<<<<<<<<<<<====>>>???????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""""!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%&&''(())***))((''&&%%$$$$%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00100//..--,,++**))((''&&%%$$##""!!!!""#""!!"""#########$##""!!```!!""##$$%%&&&&&&''((''&&''''&&%%&&''(())**++,,,,++++++**))((''&&%%%%$$##""!!``!!!""###""!!``!!!``!!"""!!`Җ``!!""##$$%%&&''(())**++,++*+++*++,,--..//001122334455566778898888889999::::::;;;;;;;<<;;::999::;;<<==>>?????????????????????????????>>==<<<<<<;;<<==>>>>???>>=>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????99887766554433221100//..--,,++**))((''&&%%%%&&'''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,--..//00112233445566778899::;;<<==>>?????????????????????>>>=======<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$%%&&''(()((''&&&&%%%$$##"####""""##$$%$$##""!!``!!!!!!!!!!!!!!!!!!""""""##$$$%%%&&''(())**++,,--..//001122334455667778899::::::;;;;;;;<<<<<;;<<<<<====>>???????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%&&''(())**+**))((''&&%%%%%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!""#""!!!!"""#########$##""!!````!!""##$$%%&&&'''((((''''''&&%%%%&&''(())**++,,+++*****))((''&&%%%%$$##""!!``!!!""""""!!````!```!!""""!!```!!""##$$%%&&''(())**++++***+***++,,--..//0011223344555667788887788889999:::::::;;;;;;;::99899::;;<<==>>???????????????????????????>>==<<<<<<;;;;<<====>>?>>===>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????9887766554433221100//..--,,++**))((''&&%%$$%%&&'''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,--..//00112233445566778899::;;<<==>>???????????????????????>>>>=====<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!""##$$%%&&''(()((''&&&&%%%$$###$$######$$%%$$##""!!`````!!``````````!!!!!!"""###$$%%%&&''(())**++,,--..//001122334455666778899999::::;;;;;;;;;;;;;;;<<<<===>>???????????????????????????????>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$####"""!!``````````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&''(())**+++**))((''&&%%%%&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""""#""!!``!!!"""""""""##$##""!!!```!!""##$$%%&&''(())((''''&&%%$$%%&&''(())**++++******))((''&&%%$$$$##""!!```!!!!""""!!``````!!""#""!!````!!""##$$%%&&''(())**+++**)***)**++,,--..//0011223344455667787777778888999999:::::::;;::9988899::;;<<==>>?????????????????????????>>==<<;;;;;;::;;<<====>>>==<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????887766554433221100//..--,,++**))((''&&%%$$$$%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---..//00112233445566778899::;;<<==>>??????????????????????????>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(()((''''&&&%%$$#$$$$####$$%%%%$$##""!!`````!!!!!!""###$$$%%&&''(())**++,,--..//0011223344556667788999999:::::::;;;;;::;;;;;<<<<==>>?????????????????????????????>>>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$####""!!``````!!!!!!!!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&''(())**++,++**))((''&&&&&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112221100//..--,,++**))((''&&%%$$##""#""!!``!!!"""""""""##$##""!!!````!!""##$$%%&&''(()((((''&&%%$$$$%%&&''(())**++***)))))((''&&%%$$$$##""!!!```!!!!"""!!`````!!""##""!!``!`!!""##$$%%&&''(())**+++**)))*)))**++,,--..//001122334445566777766777788889999999:::::::998878899::;;<<==>>???????????????????????>>==<<;;;;;;::::;;<<<<==>==<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????87766554433221100//..--,,++**))((''&&%%$$##$$%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-..//00112233445566778899::;;<<==>>????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''(()((''''&&&%%$$$%%$$$$$$%%&%%$$##""!!`````!!!"""##$$$%%&&''(())**++,,--..//00112233445556677888889999:::::::::::::::;;;;<<<==>>???????????????????????????>>==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$$$###""!!!````!!!!!!!!!!!!!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''(())**++,,,++**))((''&&&&&&%%$$##""!!````!!!""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%$$####""!!```!!!!!!!!!""##$##"""!!!``!!""##$$%%&&''(((''''&&%%$$##$$%%&&''(())****))))))((''&&%%$$####""!!````!!!""!!!!````!!""###""!!```Ñ`!!!!""##$$%%&&''(())**+++**))()))())**++,,--..//001122333445566766666677778888889999999::99887778899::;;<<==>>?????????????????????>>==<<;;::::::99::;;<<<<===<<;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????7766554433221100//..--,,++**))((''&&%%$$####$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...//00112233445566778899::;;<<==>>????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()(((('''&&%%$%%%%$$$$%%&&%%$$##""!!```!!"""###$$%%&&''(())**++,,--..//001122334455566778888889999999:::::99:::::;;;;<<==>>?????????????????????????>>====>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%$$$$##""!!!!``!!!!!!""""""""""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('(())**++,,-,,++**))((''''''&&%%$$##""!!```!!!!!""##$$%%&&''(())**++,,--..//001122333221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!!""##$##"""!!``!!""##$$%%&&''(''''&&%%$$####$$%%&&''(())**)))(((((''&&%%$$####""!!```!!!!`!!````!!`!!""##$##""!!!````!!!""####$$%%&&''(())**+**))((()((())**++,,--..//0011223334455666655666677778888888999999988776778899::;;<<==>>???????????????????>>==<<;;::::::9999::;;;;<<=<<;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????766554433221100//..--,,++**))((''&&%%$$##""##$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.//00112233445566778899::;;<<==>>?????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())((((''&&%%$$%%%%%%%%&&%%$$##""!!``!!!""###$$%%&&''(())**++,,--..//001122334445566777778888999999999999999::::;;;<<==>>>??????????????????????>>==<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%%%$$$##"""!!!``````!!!""""""""""""""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((())**++,,---,,++**))((''''''&&%%$$##""!!!!!!!"""##$$%%&&''(())**++,,--..//0011223333221100//..--,,++**))((''&&%%$$##""!!``````````!!""##$##""!!``!!""##$$%%&&'''&&&&%%$$##""##$$%%&&''(())))((((((''&&%%$$##""""!!``!!``!``!!!!!!""##$$$##""!!!!!``!!"""#"""##$$%%&&''(())***))(('((('(())**++,,--..//0011222334455655555566667777778888888998877666778899::;;<<==>>>????????????????>>==<<;;::9999998899::;;;;<<<;;:;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????66554433221100//..--,,++**))((''&&%%$$##""""##$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///00112233445566778899::;;<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''(())))((''&&%%$$$$%%%%%%&&&&%%$$##""!!``!!!"""##$$%%&&''(())**++,,--..//0011223344455667777778888888999998899999::::;;<<==>>>????????????????????>>==<<<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&%%%%$$##"""!!```!!!!!!""""""###########""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))())**++,,--.--,,++**))((((((''&&%%$$##""!!!"""""##$$%%&&''(())**++,,--..//001122334433221100//..--,,++**))((''&&%%$$##""!!`Έ`!!""####""!!``!!""##$$%%&&'&&&&%%$$##""""##$$%%&&''(())((('''''&&%%$$##""""!!````!`!!!""!""##$$%$$##"""!!!``!!""#"""""##$$%%&&''(())*))(('''('''(())**++,,--..//0011222334455554455556666777777788888887766566778899::;;<<==>>>??????????????>>==<<;;::999999888899::::;;<;;:::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????6554433221100//..--,,++**))((''&&%%$$##""!!""##$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/00112233445566778899::;;<<==>>?????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(())))((''&&%%$$##$$%%&&&&'&&%%$$##""!!```!!"""##$$%%&&''(())**++,,--..//00112233344556666677778888888888888889999:::;;<<===>>??????????????????>>==<<;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''&&&&%%%$$###""!!```!!!!!!!"""################""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))**++,,--...--,,++**))((((((''&&%%$$##"""""""###$$%%&&''(())**++,,--..//0011223344433221100//..--,,++**))((''&&%%$$##""!!``!!""###""!!``!!""##$$%%&&&&%%%%$$##""!!""##$$%%&&''((((''''''&&%%$$##""!!!!````!!!""""""##$$%%%$$##""""!!`!!""#""!!!""##$$%%&&''(()))((''&'''&''(())**++,,--..//0011122334454444445555666666777777788776655566778899::;;<<===>>????????????>>==<<;;::99888888778899::::;;;::9::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????554433221100//..--,,++**))((''&&%%$$##""!!!!""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!""##$$%%&&''(())))((''&&%%$$####$$%%&&''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//001122333445566666677777778888877888889999::;;<<===>>>??>>???????????>>==<<;;;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''&&&&%%$$###""!!``````!!!!""""""######$$$$$$$$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)**++,,--../..--,,++**))))))((''&&%%$$##"""#####$$%%&&''(())**++,,--..//001122334454433221100//..--,,++**))((''&&%%$$##""!!`ɍ`!!""##""!!``!!""##$$%%&&%%%%$$##""!!!!""##$$%%&&''(('''&&&&&%%$$##""!!!!````!!"""##"##$$%%&%%$$###"""!!!""#""!!!!!""##$$%%&&''(()((''&&&'&&&''(())**++,,--..//0011122334444334444555566666667777777665545566778899::;;<<===>>??????????>>==<<;;::998888887777889999::;::999::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????54433221100//..--,,++**))((''&&%%$$##""!!``!!""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110112233445566778899::;;<<==>>?????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$%%&&''(())))((''&&%%$$##""##$$%%&&'&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//001122233445555566667777777777777778888999::;;<<<==>>>>>>>>>???????>>==<<;;::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((''''&&&%%$$$##""!!`````````!!!```````!!!!"""""""###$$$$$$$$$$$$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***++,,--..///..--,,++**))))))((''&&%%$$#######$$$%%&&''(())**++,,--..//0011223344554433221100//..--,,++**))((''&&%%$$##""!!``!!""##""!!``!!""##$$%%%%%$$$$##""!!``!!""##$$%%&&''''&&&&&&%%$$##""!!```````!!""######$$%%&&&%%$$####""!""#""!!```!!""##$$%%&&''(((''&&%&&&%&&''(())**++,,--..//0001122334333333444455555566666667766554445566778899::;;<<<==>>?>>?????>>==<<;;::99887777776677889999:::99899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????4433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"##$$%%&&''(())))((''&&%%$$##""""##$$%%&&'&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//001122233445555556666666777776677777888899::;;<<<===>>==>>>>?????>>==<<;;::::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((((''''&&%%$$$##""!!!``````!!!!!!!!!!!!!!!``````!!!!""""######$$$$$$%%%%%%%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*++,,--..//0//..--,,++******))((''&&%%$$###$$$$$%%&&''(())**++,,--..//001122334455554433221100//..--,,++**))((''&&%%$$##""!!``!!""##""!!``!!""##$$%%%%$$$$##""!!``!!""##$$%%&&''&&&%%%%%$$##""!!``!````!!!""###$$#$$%%&&'&&%%$$$###"""#""!!``!!""##$$%%&&''(''&&%%%&%%%&&''(())**++,,--..//0001122333322333344445555555666666655443445566778899::;;<<<==>>>>>>>>>>==<<;;::9988777777666677888899:9988899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????54433221100//..--,,++**))((''&&%%$$##""!!``!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332212233445566778899::;;<<==>>?????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###$$%%&&''(())))((''&&%%$$##""!!""##$$%%&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001112233444445555666666666666666777788899::;;;<<=========>>???>>==<<;;::99::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))(((('''&&%%%$$##""!!!!```!!!!!!!!!!!"""!!!!!!!!!```!!!!""""#######$$$%%%%%%%%%%%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++,,--..//000//..--,,++******))((''&&%%$$$$$$$%%%&&''(())**++,,--..//0011223344556554433221100//..--,,++**))((''&&%%$$##""!!``!!""##""!!``!!""##$$%%$$$##$$##""!!``!!""##$$%%&&''&&%%%%%%$$##""!!``!!`!!!!!""##$$$$$$%%&&'''&&%%$$$$##""""!!``!!""##$$%%&&''(''&&%%$%%%$%%&&''(())**++,,--..///001122322222233334444445555555665544333445566778899::;;;<<==>==>>>>>==<<;;::99887766666655667788889998878899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????554433221100//..--,,++**))((''&&%%$$##""!!!!"""!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322233445566778899::;;<<==>>???????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#$$%%&&''(())))((''&&%%$$##""!!!!""##$$%%&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001112233444444555555566666556666677778899::;;;<<<==<<====>>?>>==<<;;::9999::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))((((''&&%%%$$##"""!!!`````!!!!!!"""""""""""""""!!!!!!!!!""""####$$$$$$%%%%%%&&&&&&&&%%$$##""!!```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+,,--..//00100//..--,,++++++**))((''&&%%$$$%%%%%&&''(())**++,,--..//001122334455666554433221100//..--,,++**))((''&&%%$$##""!!``!!!""#""!!``!!""##$$%$$$####$##""!!``!!""##$$%%&&&&%%%$$$$$$##""!!``!!!!!!"""##$$$%%$%%&&''(''&&%%$$##"""""!!``!!""##$$%%&&''''&&%%$$$%$$$%%&&''(())**++,,--..///001122221122223333444444455555554433233445566778899::;;;<<==========<<;;::9988776666665555667777889887778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????6554433221100//..--,,++**))((''&&%%$$##""!!"""!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433233445566778899::;;<<==>>?????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%&&''(())))((''&&%%$$##""!!``!!""##$$%%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0010112233333444455555555555555566667778899:::;;<<<<<<<<<==>>>==<<;;::998899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***))))(((''&&&%%$$##""""!!!!````!!!!"""""""""""###"""""""""!!!""""####$$$$$$$%%%&&&&&&&&&&&&&%%$$##""!!``````!!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,--..//0011100//..--,,++++++**))((''&&%%%%%%%&&&''(())**++,,--..//0011223344556666554433221100//..--,,++**))((''&&%%$$##""!!```!!""""!!``!!""##$$$$###""####""!!``!!""##$$%%&&%%$$$$$$####""!!``!!"!"""""##$$%%%%%%&&''(''&&%%$$##""!!""!!``!!""##$$%%&&'''&&%%$$#$$$#$$%%&&''(())**++,,--...//001121111112222333333444444455443322233445566778899:::;;<<=<<=====<<;;::998877665555554455667777888776778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????66554433221100//..--,,++**))((''&&%%$$##"""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544333445566778899::;;<<==>>???????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$%%&&''(())))((''&&%%$$##""!!``!!""##$$%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0000112233333344444445555544555556666778899:::;;;<<;;<<<<==>==<<;;::99888899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****))))((''&&&%%$$###"""!!!!`!!!!!""""""###############"""""""""####$$$$%%%%%%&&&&&&''''''''&&%%$$##""!!``````!!!!!!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????>>==<<;;::99887766554433221100//..--,--..//001121100//..--,,,,,,++**))((''&&%%%&&&&&''(())**++,,--..//001122334455667766554433221100//..--,,++**))((''&&%%$$##""!!```!!"""!!``!!""##$$$###""""##""!!``!!""##$$%%%%$$$#######""!!````!!""""""###$$%%%&&%&&''(''&&%%$$##""!!!!"!!``!!""##$$$%%&&'&&%%$$###$###$$%%&&''(())**++,,--...//001111001111222233333334444444332212233445566778899:::;;<<<<<<<<<<;;::99887766555555444455666677877666778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????766554433221100//..--,,++**))((''&&%%$$##"""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443445566778899::;;<<==>>?????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%&&''(())**))((''&&%%$$##""!!``!!""##$$%%&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00/001122222333344444444444444455556667788999::;;;;;;;;;<<===<<;;::9988778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++****)))(('''&&%%$$####""""!!!!!""""###########$$$#########"""####$$$$%%%%%%%&&&'''''''''''''&&%%$$##""!!!!!!!!!!!!""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????>>==<<;;::99887766554433221100//..---..//00112221100//..--,,,,,,++**))((''&&&&&&&'''(())**++,,--..//00112233445566777766554433221100//..--,,++**))((''&&%%$$##""!!!```!!"""!!``!!""##$$##"""!!""#""!!``!!""##$$%%%$$######""""!!``!!!!""#"#####$$%%&&&&&&''(''&&%%$$##""!!``!!!!``!!""##$##$$%%&&&%%$$##"###"##$$%%&&''(())**++,,---..//0010000001111222222333333344332211122334455667788999::;;<;;<<<<<;;::9988776655444444334455666677766566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????7766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554445566778899::;;<<==>>???????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%&&''(())****))((''&&%%$$##""!!!!""##$$%%&%%$$##""""!!``!!""##$$%%&&''(())**++,,--..//////001122222233333334444433444445555667788999:::;;::;;;;<<=<<;;::998877778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++****))(('''&&%%$$$###""""!"""""######$$$$$$$$$$$$$$$#########$$$$%%%%&&&&&&''''''((((((((''&&%%$$##""!!!!!!""""""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????>>==<<;;::99887766554433221100//..-..//0011223221100//..------,,++**))((''&&&'''''(())**++,,--..//0011223344556677887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!!"!!``!!""##$##"""!!!!""""!!``!!""##$$%%$$###"""""""!!``!!!""######$$$%%&&&''&''(''&&%%$$##""!!``!!!``!!""######$$%%&%%$$##"""#"""##$$%%&&''(())**++,,---..//0000//0000111122222223333333221101122334455667788999::;;;;;;;;;;::998877665544444433334455556676655566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????87766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665545566778899::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&''(())**++**))((''&&%%$$##""!!""##$$%%&%%$$##""!!!!``!!""##$$%%&&''(())**++,,--....//.//001111122223333333333333334444555667788899:::::::::;;<<<;;::99887766778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,++++***))(((''&&%%$$$$####"""""####$$$$$$$$$$$%%%$$$$$$$$$###$$$$%%%%&&&&&&&'''(((((((((((((''&&%%$$##""""""""""""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????>>==<<;;::99887766554433221100//...//001122333221100//..------,,++**))(('''''''((())**++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##"""!!```Œ`!!!"!!``!!""####""!!!``!!""""!!````!!!""##$$%$$##""""""!!!!``!!""###$$$$$%%&&&&''''''''&&%%$$##""!!``!!!``!!""####""##$$%%%$$##""!"""!""##$$%%&&''(())**++,,,--..//0//////000011111122222223322110001122334455667788899::;::;;;;;::99887766554433333322334455556665545566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????887766554433221100//..--,,++**))((''&&%%$$##""!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,++**))((''&''(())**++++**))((''&&%%$$##""""##$$%%&%%$$##""!!!!``!!""##$$%%&&''(())**++,,----......//0011111122222223333322333334444556677888999::99::::;;<;;::9988776666778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,++++**))(((''&&%%%$$$####"#####$$$$$$%%%%%%%%%%%%%%%$$$$$$$$$%%%%&&&&''''''(((((())))))))((''&&%%$$##""""""##""!!``!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????>>==<<;;::99887766554433221100//.//00112233433221100//......--,,++**))(('''((((())**++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!`…``!!!!``!!!""##""!!!``!!"""!!!!!!!!!!""##$$$##"""!!!!!!!```!!""##$$$$%%%&&&&&&''''''''&&%%$$##""!!``!!!!!!""####""""##$$%$$##""!!!"!!!""##$$%%&&''(())**++,,,--..////..////0000111111122222221100/001122334455667788899::::::::::9988776655443333332222334444556554445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????9887766554433221100//..--,,++**))((''&&%%$$##""!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++,++**))(('''(())**++,,++**))((''&&%%$$##""##$$%%&%%$$##""!!`````!!""##$$%%&&''(())**++,,,----..-..//0000011112222222222222223333444556677788999999999::;;;::998877665566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,,,,+++**)))((''&&%%%%$$$$#####$$$$%%%%%%%%%%%&&&%%%%%%%%%$$$%%%%&&&&'''''''((()))))))))))))((''&&%%$$##########""!!``!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::99887766554433221100///0011223344433221100//......--,,++**))((((((()))**++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!!``!!!!```!!!!""""!!````!!""!!`!!!!!``!!""##$##""!!!!!!`````!!""##$$%%%%%&&%%%%&&&&&&''''&&%%$$##""!!``!!""!!""##"#""!!""##$$$##""!!`!!!`!!""##$$%%&&''(())**+++,,--../......////0000001111111221100///001122334455667778899:99:::::998877665544332222221122334444555443445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????99887766554433221100//..--,,++**))((''&&%%$$##""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877666778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++,++**))(('(())**++,,,,++**))((''&&%%$$####$$%%&%%$$##""!!``!!""##$$%%&&''(())**+++,,,,------..//0000001111111222221122222333344556677788899889999::;::99887766555566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..----,,,,++**)))((''&&&%%%$$$$#$$$$$%%%%%%&&&&&&&&&&&&&&&%%%%%%%%%&&&&''''(((((())))))********))((''&&%%$$######$$##""!!``!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????>>==<<;;::99887766554433221100/001122334454433221100//////..--,,++**))((()))))**++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!``!!!!``!!`!!""!!```!!"!!``!!!``!!""###""!!!`````!!""""##$$%%&&&%%%%%%&&&&&&&&&&%%$$##""!!`!!!""""""##""""!!!!""##$##""!!``!``!!""##$$%%&&''(())**+++,,--....--....////0000000111111100//.//00112233445566777889999999999887766554433222222111122333344544333445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????:99887766554433221100//..--,,++**))((''&&%%$$##""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**++,++**))((())**++,,--,,++**))((''&&%%$$##$$%%&&%%$$##""!!`@`!!""##$$%%&&''(())**+++++,,,,--,--../////0000111111111111111222233344556667788888888899:::9988776655445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...----,,,++***))((''&&&&%%%%$$$$$%%%%&&&&&&&&&&&'''&&&&&&&&&%%%&&&&''''((((((()))*************))((''&&%%$$$$$$$$$###""!!`!!"!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????>>==<<;;::998877665544332211000112233445554433221100//////..--,,++**)))))))***++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!``!!!!`````!!"!!```!!"!!``!!``!!""##""!!```!!!!""##$$%%%%%$$$$%%%%%%&&&&%%$$##""!!``!!""#""##""!"!!``!!""####""!!``!``!!""##$$%%&&&''(())***++,,--.------....//////00000001100//...//00112233445566677889889999988776655443322111111001122333344433233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????::99887766554433221100//..--,,++**))((''&&%%$$####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****++,++**))())**++,,----,,++**))((''&&%%$$$$%%&&&%%$$##""!!``!!""##$$%%&&''(())*****++++,,,,,,--..//////000000011111001111122223344556667778877888899:998877665544445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//....----,,++***))(('''&&&%%%%$%%%%%&&&&&&'''''''''''''''&&&&&&&&&''''(((())))))******++++++++**))((''&&%%$$$$$$$#####""!!!""!!`Å`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????>>==<<;;::9988776655443322110112233445565544332211000000//..--,,++**)))*****++,,--..//0011223344556677889887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!``!!!!``!!""!!````!!""!!`!!!!``!!""#""!!``!!!!!""##$$%%%$$$$$$%%%%%%%%%%%$$##""!!``!!""####""!!!!``!!""####""!!`!!!`!!""##$$%%&&&&&''(())***++,,----,,----....///////0000000//..-..//00112233445566677888888888877665544332211111100001122223343322233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????;::99887766554433221100//..--,,++**))((''&&%%$$##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998878899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))**++,++**)))**++,,--..--,,++**))((''&&%%$$%%&&&%%$$##""!!``!!""##$$%%&&''(()))*****++++,,+,,--.....////000000000000000111122233445556677777777788999887766554433445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100///....---,,+++**))((''''&&&&%%%%%&&&&'''''''''''((('''''''''&&&''''(((()))))))***+++++++++++++**))((''&&%%%%%$$##""###""!""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111223344556665544332211000000//..--,,++*******+++,,--..//00112233445566778899887766554433221100//..--,,++**))((''&&%%$$##""!!``!!``!`````!!""""!!!!``!!""""!!!"!!``!!!""""!!``!``!!""##$$$$$####$$$$$$%%%%%%$$##""!!``!!""###""!!`!``!!""####""!!!"!!!""##$$%%&&&&%&&''(()))**++,,-,,,,,,----......///////00//..---..//001122334455566778778888877665544332211000000//001122223332212233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????;;::99887766554433221100//..--,,++**))((''&&%%$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))**++,++**)**++,,--....--,,++**))((''&&%%%%&&&%%$$##""!!```!!""##$$%%&&''(()))))****++++++,,--......///////00000//0000011112233445556667766777788988776655443333445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100////....--,,+++**))((('''&&&&%&&&&&''''''((((((((((((((('''''''''(((())))******++++++,,,,,,,,++**))((''&&%%%$$##""""###""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::9988776655443322122334455667665544332211111100//..--,,++***+++++,,--..//0011223344556677889999887766554433221100//..--,,++**))((''&&%%$$##""!!```````````!!""#""!!!!!!""##""!"""!!``!!!!"""!!```!!""##$$$######$$$$$$$$$$$$$##""!!``!!""#""!!```!!""##$##""!"""!""##$$%%&&&&%%%&&''(()))**++,,,,++,,,,----.......///////..--,--..//0011223344555667777777777665544332211000000////001111223221112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????<;;::99887766554433221100//..--,,++**))((''&&%%$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(())**++,++***++,,--..//..--,,++**))((''&&%%&&&&%%$$##""!!``!!""##$$%%&&''((()))))****++*++,,-----....///////////////00001112233444556666666667788877665544332233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::998877665544332211000////...--,,,++**))((((''''&&&&&''''((((((((((()))((((((((('''(((())))*******+++,,,,,,,,,,,,++**))((''&&%%$$##""!!""###"""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322233445566777665544332211111100//..--,,+++++++,,,--..//00112233445566778899::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`````!!""##""""!!""####"""#""!!`!```!!!!!!```!!""##$###""""######$$$$$$$$##""!!``!!""#""!!``!!""##$$$##"""#"""##$$%%&&&&%%$%%&&''((())**++,++++++,,,,------.......//..--,,,--..//0011223344455667667777766554433221100//////..//001111222110112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????<<;;::99887766554433221100//..--,,++**))((''&&%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::999::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((())**++,++*++,,--..////..--,,++**))((''&&&&'&&%%$$##""!!``!!""##$$%%&&''((((())))******++,,------......./////../////0000112233444555665566667787766554433222233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::9988776655443322110000////..--,,,++**)))(((''''&'''''(((((()))))))))))))))((((((((())))****++++++,,,,,,-----,,++**))((''&&%%$$##""!!!!""###""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????>>==<<;;::9988776655443323344556677877665544332222221100//..--,,+++,,,,,--..//00112233445566778899::::99887766554433221100//..--,,++**))((''&&%%$$##""!!!```@`!!""##""""""##$###"###""!!``!!!!!````!!""##$###""""""##############""!!!``!!""""""!!``!!""##$$$$##"###"##$$%%&&&&%%$$$%%&&''((())**++++**++++,,,,-------.......--,,+,,--..//00112233444556666666666554433221100//////....//000011211000112233445566778899::;;<<==>>???>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????=<<;;::99887766554433221100//..--,,++**))((''&&%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''(())**++,+++,,--..//00//..--,,++**))((''&&'&&%%$$##""!!``!!""##$$%%&&''''((((())))**)**++,,,,,----...............////000112233344555555555667776655443322112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221110000///..---,,++**))))(((('''''(((()))))))))))***)))))))))((())))****+++++++,,,--------,,++**))((''&&%%$$##""!!``!!""##""!!``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443334455667788877665544332222221100//..--,,,,,,,---..//00112233445566778899::;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!````!``@@@`!!""#####""##$##"""##""!!```````````!!""##$##"""!!!!""""""########""!!````!!"!!""!!`@``!!""##$$%$$##"####$$%%&&&&%%$$#$$%%&&'''(())**+******++++,,,,,,-------..--,,+++,,--..//001122333445565566666554433221100//......--..//000011100/00112233445566778899::;;<<==>>?>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????==<<;;::99887766554433221100//..--,,++**))((''&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''(())**++,+,,--..//0000//..--,,++**))(('''&&%%$$##""!!``!!""##$$%%&&''''''(((())))))**++,,,,,,-------.....--.....////00112233344455445555667665544332211112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::998877665544332211110000//..---,,++***)))(((('((((())))))***************)))))))))****++++,,,,,,------.--,,++**))((''&&%%$$##""!!``!!""""!!```!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443445566778898877665544333333221100//..--,,,-----..//00112233445566778899::;;;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!`!!```!!!`@@`!!""#######$##"""""""!!``!!""####"""!!!!!!""""""""""""""!!``!!"!!!!"!!`č@`!!""##$$$##"""##$$%%&&&&%%$$###$$%%&&'''(())****))****++++,,,,,,,-------,,++*++,,--..//0011223334455555555554433221100//......----..////00100///00112233445566778899::;;<<==>>>==>>????????>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>==<<;;::99887766554433221100//..--,,++**))((''&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&''(())**++,,--..//00100//..--,,++**))((''&&%%$$##""!!!``!!""##$$%%&&&&'''''(((())())**+++++,,,,---------------....///00112223344444444455666554433221100112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::998877665544332221111000//...--,,++****))))((((())))***********+++*********)))****++++,,,,,,,---.....--,,++**))((''&&%%$$##""!!``!!""""!!```!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444556677889998877665544333333221100//..-------...//00112233445566778899::;;<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""!!!``!`@@@`!!""##$$##$##""!!!"""!!``!!""##""!!!````!!!!!!""""""""!!``!!!``!!!``!!""##$$##""!""##$$%%&&%%$$##"##$$%%&&&''(())*))))))****++++++,,,,,,,--,,++***++,,--..//00112223344544555554433221100//..------,,--..////000//.//00112233445566778899::;;<<==>====>>??????>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&''(())**++,,--..//000//..--,,++**))((''&&%%$$##""!!!!!``!!""##$$%%&&&&&&&''''(((((())**++++++,,,,,,,-----,,-----....//00112223334433444455655443322110000112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::998877665544332222111100//...--,,+++***))))()))))******+++++++++++++++*********++++,,,,------........--,,++**))((''&&%%$$##""!!``!!""#""!!``!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????>>==<<;;::998877665545566778899:998877665544444433221100//..---.....//00112233445566778899::;;<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!```@@@@`!!!""##$$$##""!!!!!""!!``!!""""!!!``!!!!!!!!!!!!!!``!!``!!``!!""##$##""!!!""##$$%%%%$$##"""##$$%%&&&''(())))(())))****+++++++,,,,,,,++**)**++,,--..//001122233444444444433221100//..------,,,,--....//0//...//00112233445566778899::;;<<===<<==>>????>>=>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!`````!!""##$$%%%%%%&&&&&''''(('(())*****++++,,,,,,,,,,,,,,,----...//0011122333333333445554433221100//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::998877665544333222211100///..--,,++++****)))))****+++++++++++,,,+++++++++***++++,,,,-------.../////..--,,++**))((''&&%%$$##""!!!!""#""!!``!!!"""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655566778899:::998877665544444433221100//.......///00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!`@@``!!""##$##""!!```!!!!```!!""!!```ʉ``````!!!!!!!!```!!!``!!``!!""####""!!`!!""##$$%%$$##""!""##$$%%%&&''(()(((((())))******+++++++,,++**)))**++,,--..//0011122334334444433221100//..--,,,,,,++,,--....///..-..//00112233445566778899::;;<<=<<<<==>>??>>===>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!`‚`!!""##$$%%%%%%%%%&&&&''''''(())******+++++++,,,,,++,,,,,----..//00111222332233334454433221100////00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::998877665544333322221100///..--,,,+++****)*****++++++,,,,,,,,,,,,,,,+++++++++,,,,----......////////..--,,++**))((''&&%%$$##""!!""##""!!``!!""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766566778899::;::998877665555554433221100//.../////00112233445566778899::;;<<===<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!`@`!!""###""!!``!!!``!!!!``````````!!"!!``!!!``!!""###""!!``!!""##$$$$##""!!!""##$$%%%&&''((((''(((())))*******+++++++**))())**++,,--..//00111223333333333221100//..--,,,,,,++++,,----../..---..//00112233445566778899::;;<<<;;<<==>>>>==<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!``!!""####$$$$$$$%%%%%&&&&''&''(()))))****+++++++++++++++,,,,---..//000112222222223344433221100//..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::9988776655444333322211000//..--,,,,++++*****++++,,,,,,,,,,,---,,,,,,,,,+++,,,,----.......///00000//..--,,++**))((''&&%%$$##""""###""!!``!!"""###$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877666778899::;;;::998877665555554433221100///////000112233445566778899::;;<<==>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!````!!""###""!!``!!!!``!!!`€`!!""!!!!!!``!!""###""!!``!!""###$$##""!!`!!""##$$$%%&&''(''''''(((())))))*******++**))((())**++,,--..//000112232233333221100//..--,,++++++**++,,----...--,--..//00112233445566778899::;;<;;;;<<==>>==<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$%%&&''(())**++,,--...--,,++**))((''&&%%$$##""!!``!!""#####$$$$$$$$$%%%%&&&&&&''(())))))*******+++++**+++++,,,,--..//0001112211222233433221100//....//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::9988776655444433332211000//..---,,,++++*+++++,,,,,,---------------,,,,,,,,,----....//////00000000//..--,,++**))((''&&%%$$##""####""!!``!!""####$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776778899::;;<;;::998877666666554433221100///00000112233445566778899::;;<<==>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!```!!""##$##""!!``!!"!!``!!!```!!""""!!"!!``!!"""##""""!!`!!""#######""!!``!!""##$$$%%&&''''&&''''(((()))))))*******))(('(())**++,,--..//0001122222222221100//..--,,++++++****++,,,,--.--,,,--..//00112233445566778899::;;;::;;<<====<<;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##$$%%&&''(())**++,,--..--,,++**))((''&&%%$$##""!!```!!"""""#######$$$$$%%%%&&%&&''((((())))***************++++,,,--..///0011111111122333221100//..--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::9988776655544443332211100//..----,,,,+++++,,,,-----------...---------,,,----....///////0001111100//..--,,++**))((''&&%%$$####$##""!!``!!""###$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887778899::;;<<<;;::998877666666554433221100000001112233445566778899::;;<<==>>?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!``````!!""##$$$##""!!!!""!!```````!!!``!!""##""""!!``!!"""""""""!!!""##"""####""!!`!!""#####$$%%&&'&&&&&&''''(((((()))))))**))(('''(())**++,,--..///0011211222221100//..--,,++******))**++,,,,---,,+,,--..//00112233445566778899::;::::;;<<==<<;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####$$%%&&''(())**++,,--.--,,++**))((''&&%%$$##""!!``!!"""""#########$$$$%%%%%%&&''(((((()))))))*****))*****++++,,--..///00011001111223221100//..----..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::9988776655554444332211100//...---,,,,+,,,,,------...............---------....////0000001111111100//..--,,++**))((''&&%%$$##$$##""!!``!!""##$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998878899::;;<<=<<;;::9988777777665544332211000111112233445566778899::;;<<==>>???>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!````!``!!""##$$%$$##""!!"""!!``!!!!!!!!!``!!""###"""!!``!!!""!!!!!!!""#""""""""##""!!!""#######$$%%&&&&%%&&&&''''((((((()))))))((''&''(())**++,,--..///00111111111100//..--,,++******))))**++++,,-,,+++,,--..//00112233445566778899:::99::;;<<<<;;:;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""##$$%%&&''(())**++,,----,,++**))((''&&%%$$##""!!``!!!!!!"""""""#####$$$$%%$%%&&'''''(((()))))))))))))))****+++,,--...//000000000112221100//..--,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::9988776665555444332221100//....----,,,,,----...........///.........---....////0000000111222221100//..--,,++**))((''&&%%$$$$$##""!!``!!""##$$$%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988899::;;<<===<<;;::99887777776655443322111111122233445566778899::;;<<==>>?????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!``!`!!"!""##$$%$$##""""""!!``!!!!!!!!```````````````!!""##$##""!!```!!!!!!!!!!!!""""!!!""""##""!""##"""""##$$%%&%%%%%%&&&&''''''((((((())((''&&&''(())**++,,--...//001001111100//..--,,++**))))))(())**++++,,,++*++,,--..//00112233445566778899:9999::;;<<;;:::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""##$$%%&&''(())**++,,---,,++**))((''&&%%$$##""!!```!!!!!"""""""""####$$$$$$%%&&''''''((((((()))))(()))))****++,,--...///00//00001121100//..--,,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::9988776666555544332221100///...----,-----......///////////////.........////0000111111222222221100//..--,,++**))((''&&%%$$$$##""!!``!!""##$$%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99899::;;<<==>==<<;;::998888887766554433221112222233445566778899::;;<<==>>???????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!"!!!""##$$%$$##""##""!!``!!"""""!!``!!!``!`!!!!!!!````````!!!""##$$##""!!````````!!```````!!"!!!!!!!!"""""""##"""""""##$$%%%%$$%%%%&&&&'''''''(((((((''&&%&&''(())**++,,--...//0000000000//..--,,++**))))))(((())****++,++***++,,--..//0011223344556677889998899::;;;;::9::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""##$$%%&&''(())**++,,-,,++**))((''&&%%$$##""!!`````!!!!!!!"""""####$$#$$%%&&&&&''''((((((((((((((())))***++,,---../////////0011100//..--,,++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::9988777666655544333221100////....-----....///////////000/////////...////0000111111122233333221100//..--,,++**))((''&&%%$$##""!!!``!!""##$$%%%&&&'''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::999::;;<<==>>>==<<;;::9988888877665544332222222333445566778899::;;<<==>>????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````!!!`!!""##$$%$$######""!!``!!"""""!!``!!!!!``````!!!!!!!!!!!!""##$$$##""!!``!!!``````!!!!```!!!!"""""#"""!!!!!""##$$%$$$$$$%%%%&&&&&&'''''''((''&&%%%&&''(())**++,,---..//0//00000//..--,,++**))((((((''(())****+++**)**++,,--..//0011223344556677889888899::;;::999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!""##$$%%&&''(())**++,,,++**))((''&&%%$$##""!!``!!!!!!!!!""""######$$%%&&&&&&'''''''(((((''((((())))**++,,---...//..////00100//..--,,++++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887777666655443332211000///....-.....//////000000000000000/////////00001111222222333333221100//..--,,++**))((''&&%%$$##""!!!!`†`!!""##$$%%&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9::;;<<==>>?>>==<<;;::99999988776655443322233333445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!````!``!!""##$$%$$####""!!``!!""""!!``!!"!!``!`!!!!!!!"""##$$$##""!!``!!!!```!!`````!!!!!""""!!!!!!!""##$$$$##$$$$%%%%&&&&&&&'''''''&&%%$%%&&''(())**++,,---..//////////..--,,++**))((((((''''(())))**+**)))**++,,--..//0011223344556677888778899::::99899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,++**))((''&&%%$$##""!!```````!!!!!""""##"##$$%%%%%&&&&'''''''''''''''(((()))**++,,,--.........//000//..--,,++**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::998887777666554443322110000////.....////00000000000111000000000///000011112222222333433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&&'''((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::;;<<==>>???>>==<<;;::999999887766554433333334445566778899::;;<<==>>??????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!``!````!!""##$$%%$$$##""!!``!!""""!!``!!"!!`````!!"""""##$$$##""!!``!!!!``````!`†`!!!!!"!!!`````!!""##$######$$$$%%%%%%&&&&&&&''&&%%$$$%%&&''(())**++,,,--../../////..--,,++**))((''''''&&''(())))***))())**++,,--..//0011223344556677877778899::9988899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..----..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,++**))((''&&%%$$##""!!`@```!!!!""""""##$$%%%%%%&&&&&&&'''''&&'''''(((())**++,,,---..--....//0//..--,,++****++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::998888777766554443322111000////./////000000111111111111111000000000111122223333334433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'''((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:;;<<==>>?????>>==<<;;::::::998877665544333444445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!``!`````!!"""##$$%%%$$##""!!``!!""""!!``!!"!!`@@@`!!""#########""!!``!!"!!!```````````!!!!``!!""####""####$$$$%%%%%%%&&&&&&&%%$$#$$%%&&''(())**++,,,--..........--,,++**))((''''''&&&&''(((())*))((())**++,,--..//0011223344556677766778899998878899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++++**))((''&&%%$$##""!!````!!!!""!""##$$$$$%%%%&&&&&&&&&&&&&&&''''((())**+++,,---------..///..--,,++**))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99988887776655544332211110000/////00001111111111122211111111100011112222333333344433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((()))**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;<<==>>???????>>==<<;;::::::9988776655444444455566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!!!``````!!!"""""##$$%%%$$##""!!``!!""""!!```!!!!`@Ā`!!"""""#######""!!``!!"!!!`!``„`!````!!""##""""""####$$$$$$%%%%%%%&&%%$$###$$%%&&''(())**+++,,--.--.....--,,++**))((''&&&&&&%%&&''(((()))(('(())**++,,--..//0011223344556676666778899887778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//....//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**+++**))((''&&%%$$##""!!```!!!!!!""##$$$$$$%%%%%%%&&&&&%%&&&&&''''(())**+++,,,--,,----../..--,,++**))))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99998888776655544332221110000/000001111112222222222222221111111112222333344444454433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((()))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;<<==>>?????????>>==<<;;;;;;::99887766554445555566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!````!!!""!!!""##$$%%$$##""!!``!!"""!!``!!``!!""""""""""""""!!``!!""!!!!````!!"""""!!""""####$$$$$$$%%%%%%%$$##"##$$%%&&''(())**+++,,----------,,++**))((''&&&&&&%%%%&&''''(()(('''(())**++,,--..//0011223344556665566778888776778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**+++**))((''&&%%$$##""!!```!!`!!""#####$$$$%%%%%%%%%%%%%%%&&&&'''(())***++,,,,,,,,,--...--,,++**))(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;:::9999888776665544332222111100000111122222222222333222222222111222233334444444554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()))***++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<==>>???????????>>==<<;;;;;;::998877665555555666778899::;;<<==>>????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!``!!"!!!!!""##$$%$$##""!!```!!""""!!````!!"!!!!""""""""""!!``````!!"!!`````````!!""!!!!!!""""######$$$$$$$%%$$##"""##$$%%&&''(())***++,,-,,-----,,++**))((''&&%%%%%%$$%%&&''''(((''&''(())**++,,--..//0011223344556555566778877666778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100////00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++++**))((''&&%%$$##""!!````!!""######$$$$$$$%%%%%$$%%%%%&&&&''(())***+++,,++,,,,--.--,,++**))(((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::::999988776665544333222111101111122222233333333333333322222222233334444555555554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()))***++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<==>>?????????????>>==<<<<<<;;::9988776655566666778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`‡`!!!``!!!!```!!""##$$$##""!!```!!""""!!``!!!!!!!!!!!!!!!"!!````!!"!!``````````!!!!!!``!!!!""""#######$$$$$$$##""!""##$$%%&&''(())***++,,,,,,,,,,++**))((''&&%%%%%%$$$$%%&&&&''(''&&&''(())**++,,--..//0011223344555445566777766566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!""##$$%%&&''(())**++,,++**))((''&&%%$$##""!!``!!"""""####$$$$$$$$$$$$$$$%%%%&&&''(()))**+++++++++,,---,,++**))((''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;;::::9998877766554433332222111112222333333333334443333333332223333444455555556554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**+++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===>>???????????????>>==<<<<<<;;::99887766666667778899::;;<<==>>??????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!``!!!``!!""##$###""!!```!!!""#""!!``!!````!!!!!!!!!!!!``!!"""!!````!``!``````!!!!!````!!!!""""""#######$$##""!!!""##$$%%&&''(()))**++,++,,,,,++**))((''&&%%$$$$$$##$$%%&&&&'''&&%&&''(())**++,,--..//0011223344544445566776655566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""##$$%%&&''(())**++,,,++**))((''&&%%$$##""!!`Ǝ`!!"""""""#######$$$$$##$$$$$%%%%&&''(()))***++**++++,,-,,++**))((''''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;;;::::99887776655444333222212222233333344444444444444433333333344445555666666554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=>>?????????????????>>======<<;;::998877666777778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!``!!``!!""#####""!!``````!!!""##""!!`````````````!!!``!!"""!!```!``!````````!!!!"""""""#######""!!`!!""##$$%%&&''(()))**++++++++++**))((''&&%%$$$$$$####$$%%%%&&'&&%%%&&''(())**++,,--..//0011223344433445566665545566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""##$$%%&&''(())**++,,,,++**))((''&&%%$$##""!!`Î`!!"!!!""""###############$$$$%%%&&''((())*********++,,,++**))((''&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<<;;;;:::99888776655444433332222233334444444444455544444444433344445555666666666554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>???????????????????>>======<<;;::9988777777788899::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!``!```!!""##"""!!``!!``!!"""###""!!``````!!``!!""!!``!`````!!````!!!!!!"""""""##""!!``!!""##$$%%&&''((())**+**+++++**))((''&&%%$$######""##$$%%%%&&&%%$%%&&''(())**++,,--..//0011223343333445566554445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""##$$%%&&''(())**++,,-,,++**))((''&&%%$$##""!!``!!!!!!!"""""""#####""#####$$$$%%&&''((()))**))****++,++**))((''&&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<<<;;;;::9988877665554443333233333444444555555555555555444444444555566667777766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????>?????????????????????>>>>>>==<<;;::99887778888899::;;<<==>>???????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!```!!""""""!!``!!!``!!""####""!!````!!``ʊ`!!!```!!""!!``!!!!!```!!!!```!!!!!!!"""""#""!!``!!""##$$$%%&&''((())**********))((''&&%%$$######""""##$$$$%%&%%$$$%%&&''(())**++,,--..//0011223332233445555443445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!``!!```!!!!"""""""""""""""####$$$%%&&'''(()))))))))**+++**))((''&&%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>===<<<<;;;::9998877665555444433333444455555555555666555555555444555566667777777766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>==<<;;::998888888999::;;<<==>>?????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!``!!"""!!!!!!``!!!!``!!""###""!!``!!!!!````†`!!"!!``!`!!"""!!``!!!!!``!!!!!```@````!!!!!!!"""""!!`!!""###$$$$%%&&'''(())*))*****))((''&&%%$$##""""""!!""##$$$$%%%$$#$$%%&&''(())**++,,--..//0011223222233445544333445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433222233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!``````!!!!!!!"""""!!"""""####$$%%&&'''((())(())))**+**))((''&&%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>====<<<<;;::9998877666555444434444455555566666666666666655555555566667777888887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988899999::;;<<==>>???????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!```!!"!!!!!!!!!!"!!``!!""##""!!``!!""!!!!!`````````````!!"""!!!!!!"""!!!!`````!!""!!!``!!"!!!!````!!!!!"""""!!!""#####$#$$%%&&'''(())))))))))((''&&%%$$##""""""!!!!""####$$%$$###$$%%&&''(())**++,,--..//0011222112233444433233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$%%&&''(())**++,,---,,++**))((''&&%%$$##""!!```!!!!!!!!!!!!!!!""""###$$%%&&&''((((((((())***))((''&&%%$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>>====<<<;;:::99887766665555444445555666666666667776666666665556666777788888887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9999999:::;;<<==>>?????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!``!!!`````!!!"""!!``!!""##""!!```!!""!!!!!!!!!!!!!!!``!!""""!!!!!!!!!!!!!!!!!!""!!``!``!!"!!``````!!!""""!""####"####$$%%&&&''(()(()))))((''&&%%$$##""!!!!!!``!!""####$$$##"##$$%%&&''(())**++,,--..//0011211112233443322233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$%%&&''(())**++,,--.--,,++**))((''&&%%$$##""!!``````!!!!!``!!!!!""""##$$%%&&&'''((''(((())*))((''&&%%$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>>>====<<;;:::99887776665555455555666666777777777777777666666666777788889999887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::999:::::;;<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!``!``!!"""!!``!!""#""!!``!!""""""!!!!!!!!!!!``!!!!"""!!!!!!!``!``!!!!""!!```@@@`!!!!``!!!!"""""""""""#"##$$%%&&&''((((((((((''&&%%$$##""!!!!!!``!!""""##$##"""##$$%%&&''(())**++,,--..//0011100112233332212233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988777766554433445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%&&''(())**++,,--...--,,++**))((''&&%%$$##""!!``````````!!!!"""##$$%%%&&'''''''''(()))((''&&%%$$##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????>>>>===<<;;;::9988777766665555566667777777777788877777777766677778888999999887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::::;;;<<==>>?????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!`````!!"""!!``!!""##""!!``!!"""""""""""""""!!``!!!!!!"!!````````!!!!"!!``!!!!```!!!!!!!""""!""""##$$%%%&&''(''(((((''&&%%$$##""!!```````!!!!""""###""!""##$$%%&&''(())**++,,--..//0010000112233221112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776777665544445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!!```!!!!""##$$%%%&&&''&&''''(()((''&&%%$$####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????>>>>==<<;;;::99888777666656666677777788888888888888877777777788889999:::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::;;;;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!```!!""!!``!!""##""!!```!!"""#"""""""""""!!!`````!!!`ǃ```!!"!!```!!```!!!!!!!!!!!"!""##$$%%%&&''''''''''&&%%$$##""!!`````!!!!""#""!!!""##$$%%&&''(())**++,,--..//000//00112222110112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776667776655445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!```!!!""##$$$%%&&&&&&&&&''(((''&&%%$$##""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????>>>==<<<;;::99888877776666677778888888888899988888888877788889999::::::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;;;<<<==>>????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!```!!"""!!``!!""##""!!````!!!!""########""!!```!```!!"!!!```!``````!!!!`!!!!""##$$$%%&&'&&'''''&&%%$$##""!!```!!!!"""!!`!!""##$$%%&&''(())**++,,--..//0////00112211000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776656677766555566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&''(())**++,,--..////..--,,++**))((''&&%%$$##""!!```!!""##$$$%%%&&%%&&&&''(''&&%%$$##""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????>>==<<<;;::99988877776777778888889999999999999998888888889999::::;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;<<<<<==>>??????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!```!``!!""""!!```!!""###""!!```!!!!""######""!!`ˍ``!!"!!!````````!`!!""##$$$%%&&&&&&&&&&&&%%$$##""!!`````!``!!"!!``!!""##$$%%&&''(())**++,,--..///..//00111100/00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655566777665566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''(())**++,,--..////..--,,++**))((''&&%%$$##""!!``!!""###$$%%%%%%%%%&&'''&&%%$$##""!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????>>===<<;;::9999888877777888899999999999:::9999999998889999::::;;;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<<===>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!`````!!``!!""##""!!`!````````!!""###""!!`΀``!``!!""##$##""!!`Ȍ`!!""!!!`````!!""###$$%%&%%&&&&&&&%%$$$$##""!!`!!```!``!!!!``!!""##$$%%&&''(())**++,,--../....//001100///00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655455667776666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''(())**++,,--..////..--,,++**))((''&&%%$$##""!!``!!""###$$$%%$$%%%%&&'&&%%$$##""!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????>>===<<;;:::9998888788888999999:::::::::::::::999999999::::;;;;<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<=====>>?????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!```!!!!!!!````!!""####""!!!!!!!!!```````!!""###""!!`````!!""##$##""!!```````†`!!""!!``!``!!""####$$%%%%%%%%%%%%$$$##$##""!!!!!```!``!!!!``!!""##$$%%&&''(())**++,,--....--..//0000//.//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444556677766778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((())**++,,--..////..--,,++**))((''&&%%$$##""!!``!!"""##$$$$$$$$$%%&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????>>>==<<;;::::9999888889999:::::::::::;;;:::::::::999::::;;;;<<<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677889999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=======>>>???????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!""!!!``!!!!""!!!!!!""##$$##""!"!!!!!!`````!!!!!`````!!""###""!!```````!!""##$$##""!!``!``!`````!!!"!!`````!!!!""""##$$%$$%%%%%%%$$#####$##""!""!!!```!``!!!"!!``!!""##$$%%&&''(())**++,,---...----..//00//...//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443445566777778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(())**++,,--..////..--,,++**))((''&&%%$$##""!!``!!"""###$$##$$$$%%&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????>>>==<<;;;:::9999899999::::::;;;;;;;;;;;;;;;:::::::::;;;;<<<<===<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===>>>>>?????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""""!!!``!!"""""!!!!""##$$$$##""""""""!!`!!!!!!!!!!!!``!!""####""!!`!```````!!""##$$$##""!!``!```!!!!!`````!!"!!`Ĕ```!!""""##$$$$$$$$$$$$###""#####"""!!!!!``!!``!!"!!!!""##$$%%&&''(())**++++,,,--.--,,--..////..-..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443334455667778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))**++,,--..//0//..--,,++**))((''&&%%$$##""!!``!!!""#########$$%%&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????>>==<<;;;;::::99999::::;;;;;;;;;;;<<<;;;;;;;;;:::;;;;<<<<======<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667788988899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""##""!!``!!""##""""""##$$%%$$##"#""""""!!!!!!"""""!!!!````!!""##$##""!!!``!``!!""##$$$##""!!````!!````!`!!!!!!!!`````!!!!````!!!!""##$##$$$$$$$##"""""####""!!`````````!!"!!""##$$%%&&''(())******++,,,---,,,,--..//..---..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))**++,,--..//0//..--,,++**))((''&&%%$$##""!!``!!!"""##""####$$%%&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<<;;;::::9:::::;;;;;;<<<<<<<<<<<<<<<;;;;;;;;;<<<<====>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677888888899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""####""!!``!!""###""""##$$%%%%$$########""!""""""""""!!````!!``!!""##$$$##""!!!``!!``!!""##$$$$##""!!!`!`!!!!!!!!!!""!!!!!!!`!``!!"!!``````!!!!""############"""!!"""#""!!`````!!"""##$$%%&&''(()))**)****+++,,-,,++,,--....--,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****++,,--..//0//..--,,++**))((''&&%%$$##""!!```!!"""""""""##$$%%&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>==<<<<;;;;:::::;;;;<<<<<<<<<<<===<<<<<<<<<;;;<<<<====>>>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667788887778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####$$##""!!``!!""########$$%%&&%%$$#$######""""""#####""!!````!!!!!!`!!""##$$%$$##""!!``!!!!`Ɍ`!!""##$$%%$$##""!!!!!!""!!!!"!""!!```!!!!!!``!!"!!```!!`````!!""#""#######""!!!!!"""""!!``!````!!""##$$%%&&&''(())))))))**+++,,,++++,,--..--,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332212233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!!""!!""""##$$%%&%%$$##""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????>>===<<<;;;;:;;;;;<<<<<<===============<<<<<<<<<====>>>>??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677888777778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###$$$$##""!!```!!""##$####$$%%&&&&%%$$$$$$$$##"##########""!!!!!!!!!`!!!""##$$%%$$##""!!`č`!!``!!""##$$%%%$$##"""!"!""""""""""!!``!!!!!``!!"!!!```!!!!!```!!""""""""""""!!!``!!!"""!!``!!!``!!""##$$%%&&&''((())())))***++,++**++,,----,,+,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++,,--..//000//..--,,++**))((''&&%%$$##""!!```!!!!!!!!!""##$$%%&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????>>====<<<<;;;;;<<<<===========>>>=========<<<====>>>>?????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778877666778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$%%$$##""!!``!!""##$$$$$$%%&&&&&%%$$#$$$$$$########$$$##""!!!!"!!``!!""##$$%$$##""!!``!!``!!""##$$%%%$$##""""""##""""#""!!``!!""!!``!!""!!!!!!""!!!!```````!!"!!"""""""!!```!!!"!!````!!!``!!""##$$%%%%&&''(((((((())***+++****++,,--,,+++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++,,--..//0000//..--,,++**))((''&&%%$$##""!!```!!``!!!!""##$$%%&%%$$##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????>>>===<<<<;<<<<<======>>>>>>>>>>>>>>>=========>>>>???????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@`!!""##$$%%&&''(())**++,,--..//00112233445566777766666778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%$$##""!!!!``!!""###$$$$$$%%&&&%%$$###$$%%$$#$##""##$$$##"""""!!``!!""##$$%$$##""!!``!!``!!""##$$%%%%$$###"#"#########""!!```!!"""!!``!!""""!!!!""""!!!!!!!!``!!!!!!!!!!!!````!!!````!!!!``!`!!""##$$%%%%&&'''(('(((()))**+**))**++,,,,++*++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,--..//001100//..--,,++**))((''&&%%$$##""!!``````!!""##$$%%&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????>>>>====<<<<<====>>>>>>>>>>>???>>>>>>>>>===>>>>??????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@`!!""##$$%%&&''(())**++,,--..//001122334455667776655566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%$$##""!!!!!!``!!""#####$$$$$%%%%%$$##"##$$%%$$##""""##$$$##"""""!!``!!""##$$%$$##""!!``!!!```!!!""##$$%%&%%$$######$$####$##""!!!!!""#""!!`!!!!"!!!!!""""!!!!!!!!!!`````!!``!!!!!!!!``````!!`Ɗ```!!""!!!``!!""##$$$$%%&&''''''''(()))***))))**++,,++***++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,--..//0011100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&%%$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????>>>====<=====>>>>>>???????????????>>>>>>>>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@`!!""##$$%%&&''(())**++,,--..//0011223344556677665555566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$##""!!``!!!!```!!"""""######$$%%%$$##"""##$$$$##""!!""##$$$#####""!!`!!""##$$%%$$##""!!``!!"!!````!!""##$$%%&%%$$$#$#$$$$$$$$$##""!!!""###""!!``!!!!!``!!""!!``!!""""!!!!`````!!```````!`!`!!!```!``!!`!!"""!!``!!""##$$$$%%&&&''&''''((())*))(())**++++**)**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..----..//00111100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????>>>>=====>>>>???????????????????????>>>????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@`!!""##$$%%&&''(())**++,,--..//00112233445566766554445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!``!!""""""""#####$$$$$##""!""##$$##""!!!!""##$$$#####""!!!""##$$%%$$##""!!``!!"!!`LJ`!!""##$$%%&%%$$$$$$%%$$$$%$$##"""""###""!!```!```!!!!``!!""""!!!!!`````!`€`````````!!!!""""!!``!!""##$##$$%%&&&&&&&&''((()))(((())**++**)))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--..//0011221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>>>=>>>>>????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..//001122334455666655444445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!``!!!!!!!!""""""##$$$##""!!!""####""!!``!!""##$$$$$$##""!""##$$%%%$$##""!!``!!!!```!!""##$$%%&&%%%$%$%%%%%%%%%$$##"""##$##""!!```!!!!``!!""#""""!!!!!````ĀÃ`!!!""##""!!``!!""#####$$%%%&&%&&&&'''(()((''(())****))())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//....//00112221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????>>>>>??????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@```!!""##$$%%&&''(())**++,,--..//00112233445566665544333445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!``!!!!!!!!!!"""""#####""!!`!!""##""!!``!!""##$$$$$###"""##$$%%&%%$$##""!!``!!"!!```````!!""##$$%%&&%%%%%%%&%%%%$$$$###"""##$##""!!``!!!``!!""#"""""!!!!```````!!"""###""!!`Ȏ`!!""#""##$$%%%%%%%%&&'''(((''''(())**))((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..//00112221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????>?????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//0011223344556666554433333445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!```````````!!!!!!""###""!!``!!""""!!``!!""###$$$#####"##$$%%&&&%%$$##""!!````!!"!!!!!``!!```!!""##$$%%%%%%%&%%%%&%%$$$$##"""!""##$##""!!```!!!``!!""####""""!!`````!!"""####""!!`ȑ`!!"""""##$$$%%$%%%%&&&''(''&&''(())))(('(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100////001122221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????>>>?????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..//00112233445566655443322233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!""##""!!``````!!!!!""""""!!``!!!""""!!``!!""""#####"""###$$%%&&'&&%%$$##""!!``!``!!""!!!!!``!!!!``!!""##$$%%%$$%%%$$%%%$$####"""!!!""###""""!!``!!``!!""######"""!!```!!!""###$##""!!``!!"!!""##$$$$$$$$%%&&&'''&&&&''(())(('''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//0011223221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????>>>>>????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445565544332222233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""####""!!````!`````!!""""""!!`!``!!!!""!!``!!""""""###"""""###$$%%&&&&&%%$$##""!!!!``!!""""""!!!!"!!``!!""##$$$$$$$$%$$$$%$$####""!!!`!!""#""!!""!!``!!!``!!""##$$####""!!```!````!!!""###$$$##""!!``!!!!!""###$$#$$$$%%%&&'&&%%&&''((((''&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????>>>???????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100001122333221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????>>===>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455554433221112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""##$$##""!!``!``!``!!!!!!""!!``!!!!!!!!!!!"!!!!"""""!!!"""##$$%%&%%%%%%$$##""!!!``!!"""""""!!"""!!``!!""##$$$$$$##$$$##$$$##""""!!!``!!"""!!!!""!!``!!!!``!!""##$$$##""!!``!!!!```````!!"""##$$$%$$##""!!``!``!!""########$$%%%&&&%%%%&&''((''&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????>>>>>>>>?????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110011223333221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????>>=====>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344555443322111112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""##$$$$##""!!!```!!!!!!!!!````!!!!!!!!!!!!!!"""!!!!!"""##$$%%%%%%%%%$$##""!!``!!""#"###""""#""!!!!""##$$$$######$####$##""""!!``!`!!"""!!``!!""!!!!"!!``!!""##$$$$$##""!!``!!!!!!```````!!!!!"""##$$$%%%$$##""!!````!!"""##"####$$$%%&%%$$%%&&''''&&%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????>>>>>===>>????????????????????????????????????????????????????????????>==<<;;::99887766554433221100//..--,,+++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111122334433221100//..--,,++**))((''&&%%$$##""!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????>>==<<<==>>??????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//001122334455544332211000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####$$%%$$##""!!```````!!``````!!`!````!!!!!```!!!""##$$%$$$$$%%%$$##""!!``!!""#"""###""###""!!""##$$$$####""###""###""!!!!``!!"""!!``!!""!!""!!``!!""##$$%$$##""!!``!!"!!!!!!!!!!!!!!""###$$%%%%%$$##""!!```!!""""""""##$$$%%%$$$$%%&&''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????>>????>>>========>>???????????????????????????????????????????????????????????==<<;;::99887766554433221100//..--,,++*++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322112233444433221100//..--,,++**))((''&&%%$$##""!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<==>>??????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344554433221100000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##$$%%%$$##""!!```@````!!!``!!!""##$$$$$$$$$$$$$##""!!``!!"""!""#####$##""""##$$$$##""""""#""""#""!!!!``!!"""!!``!!""""""!!``!!""##$$%$$##""!!``!!"""""!!!!!!!"""""###$$%%%&&%%$$##""!!``!!!""!""""###$$%$$##$$%%&&&&%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????>>>>?>>>>=====<<<==>>??????????????????????????????????????????????????????????=<<;;::99887766554433221100//..--,,++***++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322223344554433221100//..--,,++**))((''&&%%$$##""!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;<<==>>??????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233444433221100///00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$%%&%%$$##""!!`ÁÂÆ```````!!""##$#####$$$####""!!``!!"!!!""####$$##""########""""!!"""!!"""!!`````!!"""!!!````!!"""#""!!```!!""##$$%%$$##""!!````!!""#""""""""""""""##$$$%%&&&&%%$$##""!!``!!!!!!!!""###$$$####$$%%&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????>>==>>>>===<<<<<<<<==>>?????????????????????????????????????????????????????????<<;;::99887766554433221100//..--,,++**)**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322334455554433221100//..--,,++**))((''&&%%$$##""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;<<==>>?????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344433221100/////00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$%%&&&%%$$##""!!````````!!""##############""!!``!!!`!!""################""!!!!!!"!!!!"!!````!!!""!!````!!""##""!!``!`!!""##$$%%$$##""!!!````!!!""#####"""""""#####$$$%%%%&&&&%%$$##""!!```````!!`!!!!"""##$##""##$$%%%%$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????>>====>====<<<<<;;;<<==>>????????????????????????????????????????????????????????<;;::99887766554433221100//..--,,++**)))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443333445566554433221100//..--,,++**))((''&&%%$$##""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::;;<<==>>????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344433221100//...//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%&&'&&%%$$##""!!!!!!```````!!```!!""###"""""###""###""!!```!``!!""""#######"""""""!!!!``!!!``!!!!``!`!``!!!!!``!!""###""!!!!!!""##$$%%$$##""!!```!!""##$##############$$%%%%%%%%&&%%$$##""!!````!!``````!!"""###""""##$$%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????>>==<<====<<<;;;;;;;;<<==>>???????????????????????????????????????????????????????;;::99887766554433221100//..--,,++**))())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443344556666554433221100//..--,,++**))((''&&%%$$####""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::;;<<==>>????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!`!!""##$$%%&&''(())**++,,--..//00112233433221100//.....//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%&&'''&&%%$$##""!!!!!````````!!!!!!!``!!"""#"""""""""""""###""!!````!!""""""""""""""""!!````!``!!!!`!!!```!!```!!""##$##""!!"!""##$$%%$$##""!!``!!""##$$$#########"##$$%%$$$%%%%%$$##""!!``!!`````!!!""#""!!""##$$$$##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<<<=<<<<;;;;;:::;;<<==>>??????????????????????????????????????????????????????;::99887766554433221100//..--,,++**))((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444455667766554433221100//..--,,++**))((''&&%%$$###""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::999::;;<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&''(())**++,,--..//001122333221100//..---..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&''(''&&%%$$##"""""!!``````!!!!!!!!!"""""""!!!!!"""!!"""""""!!``!!```!!""!!"""""""!!!!!!!````!!"!!!"!!```!``!!""##$$##""""""##$$%%%$$##""!!``!!""##$$$$$$$$##"""##$$$$$$$$%%%%$$##""!!```!!````````!!!"""!!!!""##$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????>>==<<;;<<<<;;;::::::::;;<<==>>?????????????????????????????????????????????????????::99887766554433221100//..--,,++**))(('(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655445566777766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99999::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233221100//..-----..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&''(((''&&%%$$##"""""!!!!!!```!!!!!!!"!!!!"!!!!!!!!!!!!!"""!!!!!!!!!!!!!"!!!!!!!!!!!!!!!!!````!!!!"!!!!``!!``!!""##$$$$##""#"##$$%%%$$##""!!``!!""###$$$$$##""!""##$$###$$$%%%%$$##""!!!!!!`````!```!!"!!``!!""####""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????>>==<<;;;;<;;;;:::::999::;;<<==>>????????????????????????????????????????????????????:99887766554433221100//..--,,++**))(('''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655556677887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988899::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223221100//..--,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''(()((''&&%%$$#####""!!!!!!!``````````!!!!!!!!!!`````!!!``!!!!!!!!!!!!!!!!!!!!``!!!!!!!`````!``!``!```!!!!!!``!!!``!!""##$$%%$$######$$%%%%$$##""!!````!!""###$$$##""!!!""########$$%%%%$$##""!!!!!``!!!``!!!``!!""##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::;;;;:::99999999::;;<<==>>???????????????????????????????????????????????????99887766554433221100//..--,,++**))((''&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655667788887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998888899::;;<<==>>?????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122221100//..--,,,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''(()))((''&&%%$$#####""""""!!!!````!``!`````!!````!``````!!!```````!!``!!!``````````@``````!!```!``!!!``!!""##$$%%%%$$##$#$$%%&%%$$##""!!```!!```!!"""##$##""!!`!!""##"""###$$%%%%$$##""""!!``!!!``!!!``!!""##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::::;::::9999988899::;;<<==>>??????????????????????????????????????????????????9887766554433221100//..--,,++**))((''&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776666778899887766554433221100//..--,,++**))((''&&%%$$##""!!`†`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887778899::;;<<==>>?????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&''(())**++,,--....//0011221100//..--,,+++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((())*))((''&&%%$$$$$##"""""""!!!!!!!!!!!!!!``€```````````ć`@@@Ƀ```!``!!!``!!""##$$%%&&%%$$$$$$%%&%%$$##""!!````!!!!!!`````!!""""###""!!``!!""""""""##$$%%%%$$##"""!!```!!!```!``!!""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????>>==<<;;::99::::9998888888899::;;<<==>>?????????????????????????????????????????????????887766554433221100//..--,,++**))((''&&%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877667788999887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988777778899::;;<<==>>????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--......//00111100//..--,,+++++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(())***))((''&&%%$$$$$######""""!!!!"!!"!!!!!!``````€`````!!```!!!!!!``!!""##$$%%&&&&%%$$%$%%&&%%$$##""!!`````!``!!""!!!!!!``!!!!""#""!!``!!""!!!"""##$$%%%%$$###""!!``!``!!!!`````!!"""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::9999:9999888887778899::;;<<==>>????????????????????????????????????????????????87766554433221100//..--,,++**))((''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877778899:99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877666778899::;;<<==>>???????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--....--..//001100//..--,,++***++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))**+**))((''&&%%%%%$$#######""""""""""""""!!!!!!!```````````È````!!!!!!!!!!!"!!"!!```!!""##$$%%&&''&&%%%%%%&&&&%%$$##""!!````````!!!!!!``!!""""!!!!``!!!!""""!!``!!"!!!!!!""##$$%%%%$$###""!!!!``!!!!``!``!!""""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99889999888777777778899::;;<<==>>???????????????????????????????????????????????7766554433221100//..--,,++**))((''&&%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988778899::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766666778899::;;<<==>>?????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..----..//0000//..--,,++*****++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))**+++**))((''&&%%%%%$$$$$$####""""#""#""""""!!!!!!!!!!!!!!!``````````!````!``!!!!!""!!!""""""!!!!!""##$$%%&&''''&&%%&%&&''&&%%$$##""!!!!!!!!!!!!!"!!``!!""#"""""!!``!``!!"!!!!!``!!!!```!!!""##$$%%%%$$$##""!!!!``!!!`!```````!!""#""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::9988889888877777666778899::;;<<==>>??????????????????????????????????????????????766554433221100//..--,,++**))((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99888899:::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655566778899::;;<<==>>???????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--.--,,--..//00//..--,,++**)))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****++++**))((''&&%%$%%%$$$$$$$##############"""""""!!!!!!!!!!!!!!``````!!!!!!!!!!```!!""""""""""#""#""!!!""##$$%%&&''('''&&&&&&''''&&%%$$##""!!!!!!!!""""""!!``!!""###"""!!````!!!!!!!``!!!!```!!""##$$%%%%$$$##"""!!```!!``!````!!""#""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::998877888877766666666778899::;;<<==>>?????????????????????????????????????????????66554433221100//..--,,++**))((''&&%%$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998899::;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665555566778899::;;<<==>>??????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,---,,,,--..////..--,,++**)))))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**++++**))((''&&%%$$$%%%%%%%$$$$####$##$######"""""""""""""""!!!!!!!```!````````````````````````!``!!!!!!!``````!!!"""""##"""######"""""##$$%%&&&&''''''&&'&''((''&&%%$$##"""""""""""""#""!!```!!""######""!!``!!`````!`!!"!!``!!""##$$%%%%%$$##"""!!```!``!!``@`!!""#"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887777877776666655566778899::;;<<==>>????????????????????????????????????????????6554433221100//..--,,++**))((''&&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9999::;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554445566778899::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--,,++,,--..//..--,,++**))((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++++**))((''&&%%$$#$$%%%%%%%%$$$$$$$$$$$$$$#######""""""""""""""!!!!!!!!!!!!```!````````!!!!``!!!``!!``!!!!!"""!!`Ȏ```!!!!""##########$##$##"""##$$%%&&%&&&'&''''''''((((''&&%%$$##""""""""######""!!```!!!""##$$$###""!!``!``!!"""!!``!!""##$$%%&%%%$$###""!!!!!!!!!!```@`!!!""#"##$$%%&&''(())**++,,--.././/00112233445566778899::;;<<==>>???????>>==<<;;::9988776677776665555555566778899::;;<<==>>???????????????????????????????????????????554433221100//..--,,++**))((''&&%%$$##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99::;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444445566778899::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,-,,++++,,--....--,,++**))((((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++**))((''&&%%$$###$$%%&&&%%%%$$$$%$$%$$$$$$###############"""""""!!!"!!!!!!!!!!!!!!!!!!!!```!!!!!!!!"!!"""!!`„```!!!!!"""#####$$###$$$$$$#####$$%%%%%%%%&&&&''''('('((''&&&%%%$$#############$##""!!````````!!!!""##$$$$$$##""!!````!!"""!!````!!""##$$%%&&&&%%$$###""!!!"!!""!!!````!!!""##$$%%&&''(())**++,,--../...//00112233445566778899::;;<<==>>?????>>==<<;;::998877666676666555554445566778899::;;<<==>>??????????????????????????????????????????54433221100//..--,,++**))((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::::;;<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544333445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,,++**++,,--..--,,++**))(('''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"##$$%%&&&&%%%%%%%%%%%%%%$$$$$$$##############""""""""""""!!!"!!!!!!!!"!!``!!""!!""""""!!``!!!!!!""""##$$$$$$$$$$%$$%$$###$$%%%%%%$%%%&%&&&'''''''''&&&%%$$%$$########$$$$$$##""!!!!!!!!```!!!"""##$$%%%$$##""!!``!!"""!!!!!!""##$$%%&&'&&&%%$$$##""""""""""!!`````!!""##$$%%&&''(())**++,,--...-..//00112233445566778899::;;<<==>>???>>==<<;;::99887766556666555444444445566778899::;;<<==>>?????????????????????????????????????????4433221100//..--,,++**))((''&&%%$$##""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::;;<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433333445566778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,++****++,,----,,++**))(('''''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$%%&&&&&%%%%&%%&%%%%%%$$$$$$$$$$$$$$$#######"""#""""""""""""""""""!!``!!"""""""""!!``!!!!"""""###$$$$$%%$$$%%%%%%$$$$$$$%$$$$$$$%%%%&&&&'''&''&&%%%$$$$%$$$$$$$$$$$$$%$$##""!!!!!!!!!`!!""""##$$%%%%%$$##""!!``@`!!""""!!!!""##$$$%%&&'''&&%%$$$##"""#""##""!!`````!!""##$$%%&&''(())**++,,--.---..//00112233445566778899::;;<<==>>?>>==<<;;::9988776655556555544444333445566778899::;;<<==>>????????????????????????????????????????433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322233445566778899::;;<<==>>??????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++++**))**++,,--,,++**))((''&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!""##$$%%&&&&&&&&&&&&&&&&%%%%%%%$$$$$$$$$$$$$$############"""#""""""""""!!``!!""!!""#""!!``!!"""""####$$%%%%%%%%%%&%%%$$$$$$$$$$$$$#$$$%$%%%&&&&&&&&&%%%$$##$$%$$$$$$$$%%%%%%$$##"""""!!``!!!"""###$$%%&&&%%$$##""!!!`@@@`!!""""""""##$$$$$%%&&'''&&%%%$$#########""!!`````!!""##$$%%&&''(())**++,,----,--..//00112233445566778899::;;<<==>>>==<<;;::998877665544555544433333333445566778899::;;<<==>>???????????????????????????????????????33221100//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332222233445566778899::;;<<==>>??????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++**))))**++,,,,++**))((''&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&'&&&&'&&'&&&&&&%%%%%%%%%%%%%%%$$$$$$$###$##################""!!`````!!!!!!"""!!```!!"""#####$$$%%%%%&&%%%&&%%$$#######$#######$$$$%%%%&&&%&&%%$$$####$$%%%%%%%%%%%%&%%$$##"""!!``!!""###$$%%&&&&&%%$$##""!!`@`!!"""!!!""##$$##$$%%&&'''&&%%%$$###$##$##""!!`````!`````!!""##$$%%&&''(())**++,,----,,,--..//00112233445566778899::;;<<==>==<<;;::99887766554444544443333322233445566778899::;;<<==>>??????????????????????????????????????3221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<===<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221112233445566778899::;;<<==>>??????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())****))(())**++,,++**))((''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''''''''''''&&&&&&&%%%%%%%%%%%%%%$$$$$$$$$$$$###$##########""!!!!!``!!!``!!""!!``!!!""#####$$$$%%&&&&&&&&&&%%$$#############"###$#$$$%%%%%%%%%$$$##""##$$%%%%%%%&&&&&&%%$$##""!!``!!""##$$%%&&''&&%%$$##""!!`````!!""!!!!!""######$$%%&&'''&&&%%$$$$$$$$$##""!!!!!```!```!!""##$$%%&&''(())**++,,--,,+,,--..//00112233445566778899::;;<<===<<;;::9988776655443344443332222222233445566778899::;;<<==>>?????????????????????????????????????3221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<====<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƒ`!!""##$$%%&&''(())**))(((())**++++**))((''&&%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'''(''(''''''&&&&&&&&&&&&&&&%%%%%%%$$$%$$$$$$$$$$$$$$$$$$##""!!!!!````!!!``!!!!````!!!""###$$$$$%%%&&&&&''&&&%%$$##"""""""#"""""""####$$$$%%%$%%$$###""""##$$%%&&&&&&&&'&&%%$$##""!!```!!""##$$%%&&''''&&%%$$##""!!!!```````!!""!!```!!""##""##$$%%&&'''&&&%%$$$%$$%$$##""!!!!!!!``!!""##$$%%&&''(())**++,,,,+++,,--..//00112233445566778899::;;<<=<<;;::998877665544333343333222221112233445566778899::;;<<==>>????????????????????????????????????33221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>====>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000112233445566778899::;;<<==>>????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())*))((''(())**++**))((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(((((((('''''''&&&&&&&&&&&&&&%%%%%%%%%%%%$$$%$$$$$$$$$$##"""""!!!``!!!!``!!!````!!!!"""##$$$$$%%%%&&''''''&&%%$$##"""""""""""""!"""#"###$$$$$$$$$###""!!""##$$%%&&&''''&&%%$$##""!!``!!""##$$%%&&''''&&%%$$##""!!!!!!!!``````!!"!!``!!""""""##$$%%&&''''&&%%%%%%%%%$$##"""""!!!!```!!""##$$%%&&''(())**++,,,++*++,,--..//00112233445566778899::;;<<<;;::99887766554433223333222111111112233445566778899::;;<<==>>???????????????????????????????????433221100//..--,,++**))((''&&%%$$##""!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100000112233445566778899::;;<<==>>????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())))((''''(())****))((''&&%%$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(((()(((((('''''''''''''''&&&&&&&%%%&%%%%%%%%%%%%%%%%%%$$##"""""!!!!!!!!``!!``!!!!!"""##$$$%%%%%&&&''''''&&%%$$##""!!!!!!!"!!!!!!!""""####$$$#$$##"""!!!!""##$$%%&&''''&&%%$$##""!!``!!""##$$%%&&''''&&%%$$##""""!!!!!!!!!``!!"!!``!!"""!!""##$$%%&&''''&&%%%&%%&%%$$##"""""""!!``!!""##$$%%&&''(())**++,++***++,,--..//00112233445566778899::;;<;;::9988776655443322223222211111000112233445566778899::;;<<==>>??????????????????????????????????4433221100//..--,,++**))((''&&%%$$##""!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///00112233445566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()))((''&&''(())**))((''&&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!""##$$%%&&''(())))))))(((((((''''''''''''''&&&&&&&&&&&&%%%&%%%%%%%%%%$$#####"""!!"""!!```!!!``!!!""""###$$%%%%%&&&&''((''&&%%$$##""!!!!!!!!!!!!!`!!!"!"""#########"""!!``!!""##$$%%&&'''&&%%$$##""!!``!!""##$$%%&&''''&&%%$$##""""""""!!!!!``````!!"""!!```!!!!"!!!!""##$$%%&&''''&&&&&&&%%$$##""!!"""""!!```!!""##$$%%&&''(())**++++**)**++,,--..//00112233445566778899::;;;::998877665544332211222211100000000112233445566778899::;;<<==>>?????????????????????????????????54433221100//..--,,++**))((''&&%%$$##""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////00112233445566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())((''&&&&''(())))((''&&%%$$#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(())))*))))))((((((((((((((('''''''&&&'&&&&&&&&&&&&&&&&&&%%$$#####""""""""!!!!!!!``!!"""""###$$%%%&&&&&'''((''&&%%$$##""!!```````!``````!!!!""""###"##""!!!``!!""##$$%%&&''&&%%$$##""!!``!!""##$$%%&&''(''&&%%$$####"""""""""!!!``!!!!!""#""!!!!``!!!!``!!""##$$%%&&''''&&&&&%%$$##""!!!!!""""!!!````!!""##$$%%&&''(())**+++**)))**++,,--..//00112233445566778899::;::998877665544332211112111100000///00112233445566778899::;;<<==>>????????????????????????????????554433221100//..--,,++**))((''&&%%$$##""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ŋ`!!""##$$%%&&''(()((''&&%%&&''(())((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""##$$%%&&''(())********)))))))((((((((((((((''''''''''''&&&'&&&&&&&&&&%%$$$$$###""###""!!!""!!``!!"""####$$$%%&&&&&''''((''&&%%$$##""!!```!`!!!"""""""""!!!``!!""##$$%%&&''&&%%$$##""!!``!!""##$$%%&&''((''&&%%$$########"""""!!!!!!!!""###""!!```!``!!""##$$%%&&'''''&&%%$$##""!!``!!!""""!!!!!`!!""##$$%%&&''(())**++***))())**++,,--..//00112233445566778899:::998877665544332211001111000////////00112233445566778899::;;<<==>>???????????????????????????????6554433221100//..--,,++**))((''&&%%$$####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.....//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ȍ`!!""##$$%%&&''(()((''&&%%%%&&''((((''&&%%$$##"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$%%&&''(())****+******)))))))))))))))((((((('''(''''''''''''''''''&&%%$$$$$########"""""""!!!!""#####$$$%%&&&''''''''''&&%%$$##""!!```!!!!"""!""!!```!!""##$$%%&&'''&&%%$$##""!!``!!""##$$%%&&''(((''&&%%$$$$#########"""!!"""""##$##""!!```!!""##$$%%&&''''&&%%$$##""!!```!!"""""!!!!!""##$$%%&&''(())**++***))((())**++,,--..//00112233445566778899:998877665544332211000010000/////...//00112233445566778899::;;<<==>>??????????????????????????????66554433221100//..--,,++**))((''&&%%$$##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((((''&&%%$$%%&&''((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####$$%%&&''(())**++++++++*******))))))))))))))(((((((((((('''(''''''''''&&%%%%%$$$##$$$##"""##""!!""###$$$$%%%&&''''''&&&''&&%%$$##""!!`@``!!!!!!!!!``!!""##$$%%&&''&&%%$$##""!!``!!""##$$%%&&''((((''&&%%$$$$$$$$#####""""""""##$$##""!!``!!""##$$%%&&''''&&%%$$##""!!``!!"""""""!""##$$%%&&''(())**++**)))(('(())**++,,--..//001122334455667788999887766554433221100//0000///........//00112233445566778899::;;<<==>>?????????????????????????????766554433221100//..--,,++**))((''&&%%$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-----..//00112233445566778899::;;<<==>>??????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(((''&&%%$$$$%%&&''''&&%%$$##""!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###$$%%&&''(())**++++,++++++***************)))))))((()((((((((((((((((((''&&%%%%%$$$$$$$$#######""""##$$$$$%%%&&'''&'&&&&&&'&&%%$$##""!!`@@@@``!!!`!!```!!""##$$%%&&''&&%%$$##""!!```!!""##$$%%&&''((((''&&%%%%$$$$$$$$$###""#####$$$$##""!!````!!""##$$%%&&''(''&&%%$$##""!!``!!""#"""""##$$%%&&''(())**++**)))(('''(())**++,,--..//0011223344556677889887766554433221100////0////.....---..//00112233445566778899::;;<<==>>????????????????????????????7766554433221100//..--,,++**))((''&&%%$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`ɒ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,--..//00112233445566778899::;;<<==>>??????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ő`!!""##$$%%&&''(''&&%%$$##$$%%&&''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$%%&&''(())**++,,,,,,,,+++++++**************))))))))))))((()((((((((((''&&&&&%%%$$%%%$$###$$##""##$$$%%%%&&&'''&&&&&%%%&&&&%%$$##""!!`@@`````@@`!!""##$$%%&&''&&%%$$##""!!``!!""##$$%%&&''((((''&&%%%%%%%%$$$$$########$$%%$$##""!!```!!!!""##$$%%&&''(((''&&%%$$##""!!```!!""####"##$$%%&&''(())**++**))(((''&''(())**++,,--..//00112233445566778887766554433221100//..////...--------..//00112233445566778899::;;<<==>>???????????????????????????87766554433221100//..--,,++**))((''&&%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,--..//00112233445566778899::;;<<==>>????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''''&&%%$$####$$%%&&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%&&''(())**++,,,,-,,,,,,+++++++++++++++*******)))*))))))))))))))))))((''&&&&&%%%%%%%%$$$$$$$####$$%%%%%&&&'''&&%&%%%%%%&&&%%$$##""!!`@@@@@`!!""##$$%%&&&&%%$$##""!!``!!""##$$%%&&''((((''&&&&%%%%%%%%%$$$##$$$$$%%%%$$##""!!!!!!!""##$$%%&&''(()((''&&%%$$##""!!!```!!""######$$%%&&''(())**++**))(((''&&&''(())**++,,--..//001122334455667787766554433221100//..../....-----,,,--..//00112233445566778899::;;<<==>>??????????????????????????887766554433221100//..--,,++**))((''&&%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++,,--..//00112233445566778899::;;<<==>>??????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`ȏ`!!""##$$%%&&'''&&%%$$##""##$$%%&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%&&''(())**++,,--------,,,,,,,++++++++++++++************)))*))))))))))(('''''&&&%%&&&%%$$$%%$$##$$%%%&&&&'&&'&&%%%%%$$$%%&&&%%$$##""!!``````!!""##$$%%&&&&%%$$##""!!``!!""##$$%%&&''(())((''&&&&&&&&%%%%%$$$$$$$$%%&&%%$$##""!!!""""##$$%%&&''(()))((''&&%%$$##""!!!!`!!""##$$$#$$%%&&''(())**++**))(('''&&%&&''(())**++,,--..//0011223344556677766554433221100//..--....---,,,,,,,,--..//00112233445566778899::;;<<==>>?????????????????????????9887766554433221100//..--,,++**))((''&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++++,,--..//00112233445566778899::;;<<==>>????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''&&%%$$##""""##$$%%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%&&''(())**++,,----.------,,,,,,,,,,,,,,,+++++++***+******************))(('''''&&&&&&&&%%%%%%%$$$$%%&&&&&'&&&&&%%$%$$$$$$%%&&&%%$$##""!!!``!!""##$$%%&&&%%$$##""!!``!!""##$$%%&&''(())((''''&&&&&&&&&%%%$$%%%%%&&&&%%$$##"""""""##$$%%&&''(())*))((''&&%%$$##"""!!!!""##$$$$$$%%&&''(())**++**))(('''&&%%%&&''(())**++,,--..//00112233445566766554433221100//..----.----,,,,,+++,,--..//00112233445566778899::;;<<==>>????????????????????????99887766554433221100//..--,,++**))((''&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***++,,--..//00112233445566778899::;;<<==>>??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'&&%%$$##""!!""##$$%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&''(())**++,,--........-------,,,,,,,,,,,,,,++++++++++++***+**********))((((('''&&'''&&%%%&&%%$$%%&&&'''&&%%&%%$$$$$###$$%%&&%%$$##""!!``!!""##$$%%&&&%%$$##""!!``!!""##$$%%&&''(()))((''''''''&&&&&%%%%%%%%&&''&&%%$$##"""####$$%%&&''(())***))((''&&%%$$##""""!""##$$%%%$%%&&''(())**++**))((''&&&%%$%%&&''(())**++,,--..//001122334455666554433221100//..--,,----,,,++++++++,,--..//00112233445566778899::;;<<==>>???????????????????????:99887766554433221100//..--,,++**))((''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*****++,,--..//00112233445566778899::;;<<==>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&%%$$##""!!!!""##$$%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&''(())**++,,--..../......---------------,,,,,,,+++,++++++++++++++++++**))(((((''''''''&&&&&&&%%%%&&''''&&%%%%%$$#$######$$%%%%$$##""!!``!!""##$$%%&&&%%$$##""!!``!!""##$$%%&&''(())))(((('''''''''&&&%%&&&&&''''&&%%$$#######$$%%&&''(())**+**))((''&&%%$$###""""##$$%%%%%%&&''(())**++**))((''&&&%%$$$%%&&''(())**++,,--..//0011223344556554433221100//..--,,,,-,,,,+++++***++,,--..//00112233445566778899::;;<<==>>??????????????????????::99887766554433221100//..--,,++**))((''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677878899::;;<<==>>?????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))**++,,--..//00112233445566778899::;;<<==>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&%%$$##""!!``!!""##$$%$$##""!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''''(())**++,,--..////////.......--------------,,,,,,,,,,,,+++,++++++++++**)))))(((''(((''&&&''&&%%&&''''&&%%$$%$$#####"""##$$%%$$##""!!``!!""##$$%%&&'&&%%$$##""!!``!!""##$$%%&&''(())))(((((((('''''&&&&&&&&''((''&&%%$$###$$$$%%&&''(())**+++**))((''&&%%$$####"##$$%%&&&%&&''(())**++**))((''&&%%%$$#$$%%&&''(())**++,,--..//00112233445554433221100//..--,,++,,,,+++********++,,--..//00112233445566778899::;;<<==>>?????????????????????;::99887766554433221100//..--,,++**))(((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667787778899::;;<<==>>???????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))**++,,--..//00112233445566778899::;;<<==>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&%%$$##""!!``!!""##$$$##""!!`!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''(())**++,,--..////0//////...............-------,,,-,,,,,,,,,,,,,,,,,,++**)))))(((((((('''''''&&&&''''&&%%$$$$$##"#""""""##$$%$$##""!!``!!""##$$%%&&&&%%$$##""!!``!!""##$$%%&&''(())*))))((((((((('''&&'''''((((''&&%%$$$$$$$%%&&''(())**++,++**))((''&&%%$$$####$$%%&&&&&&''(())**++**))((''&&%%%$$###$$%%&&''(())**++,,--..//001122334454433221100//..--,,++++,++++*****)))**++,,--..//00112233445566778899::;;<<==>>????????????????????;;::99887766554433221100//..--,,++**))(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778776778899::;;<<==>>?????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((())**++,,--..//00112233445566778899::;;<<====<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&%%$$##""!!``!!""##$$$##""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((((())**++,,--..//00000000///////..............------------,,,-,,,,,,,,,,++*****)))(()))(('''((''&&''''&&%%$$##$##"""""!!!""##$$$$##""!!``!!""##$$%%&&'&&%%$$##""!!``!!""##$$%%&&''(())**))))))))(((((''''''''(())((''&&%%$$$%%%%&&''(())**++,,,++**))((''&&%%$$$$#$$%%&&'''&''(())**++**))((''&&%%$$$##"##$$%%&&''(())**++,,--..//0011223344433221100//..--,,++**++++***))))))))**++,,--..//00112233445566778899::;;<<==>>???????????????????<;;::99887766554433221100//..--,,++**))))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//0011223344556677877666778899::;;<<==>>???????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((((())**++,,--..//00112233445566778899::;;<<==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&%%$$##""!!!!""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((())**++,,--..//00001000000///////////////.......---.------------------,,++*****))))))))(((((((''''''&&%%$$#####""!"!!!!!!""##$$##""!!``!!""##$$%%&&'&&%%$$##""!!``!!""##$$%%&&''(())****)))))))))(((''((((())))((''&&%%%%%%%&&''(())**++,,-,,++**))((''&&%%%$$$$%%&&''''''(())**++**))((''&&%%$$$##"""##$$%%&&''(())**++,,--..//00112233433221100//..--,,++****+****)))))((())**++,,--..//00112233445566778899::;;<<==>>??????????????????<<;;::99887766554433221100//..--,,++**))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ő`!!""##$$%%&&''(())**++,,--..//001122334455667787766566778899::;;<<==>>?????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''(())**++,,--..//00112233445566778899::;;<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'&&%%$$##""!!""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))**++,,--..//00111111110000000//////////////............---.----------,,+++++***))***))((())((''''&&%%$$##""#""!!!!!```!!""#####""!!````!!""##$$%%&&&&%%$$##""!!``!!"""##$$%%&&''(())********)))))(((((((())**))((''&&%%%&&&&''(())**++,,---,,++**))((''&&%%%%$%%&&''((('(())**++**))((''&&%%$$###""!""##$$%%&&''(())**++,,--..//001122333221100//..--,,++**))****)))(((((((())**++,,--..//00112233445566778899::;;<<==>>?????????????????=<<;;::99887766554433221100//..--,,++****++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677776655566778899::;;<<==>>???????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''''(())**++,,--..//00112233445566778899::;;<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''&&%%$$##""""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))**++,,--..//0011112111111000000000000000///////.../..................--,,+++++********)))))))((''&&%%$$##"""""!!`!```!!""###""!!``!!""##$$%%&&&%%$$##""!!``!!!!""##$$%%&&''(())***********)))(()))))****))((''&&&&&&&''(())**++,,--.--,,++**))((''&&&%%%%&&''(((((())**++**))((''&&%%$$###""!!!""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))))*))))((((('''(())**++,,--..//00112233445566778899::;;<<==>>????????????????==<<;;::99887766554433221100//..--,,++**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566777665545566778899::;;<<==>>?????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&''(())**++,,--..//00112233445566778899::;;<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'''&&%%$$##""##$$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*****++,,--..//001122222222111111100000000000000////////////.../..........--,,,,,+++**+++**)))))((''&&%%$$##""!!"!!```!!"""""!!```!!""##$$%%&&&%%$$##""!!``!!!!!""##$$%%&&''(())**++++*****))))))))**++**))((''&&&''''(())**++,,--...--,,++**))((''&&&&%&&''(()))())**++**))((''&&%%$$##"""!!`!!""##$$%%&&''(())**++,,--..//00112221100//..--,,++**))(())))(((''''''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????>==<<;;::99887766554433221100//..--,,++++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667766554445566778899::;;<<==>>???????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&''(())**++,,--..//00112233445566778899::;;<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''''&&%%$$####$$%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***++,,--..//0011222232222221111111111111110000000///0//////////////////..--,,,,,++++++++***))((''&&%%$$##""!!!!!``!!"""!!``!!""##$$%%&&&%%$$##""!!``!!``!!""##$$%%&&''(())**+++++++***))*****++++**))(('''''''(())**++,,--../..--,,++**))(('''&&&&''(())))))**++**))((''&&%%$$##"""!!``!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))(((()(((('''''&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//..--,,++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556676655443445566778899::;;<<==>>?????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%&&''(())**++,,--..//00112233445566778899::;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''''&&%%$$##$$%$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++++,,--..//00112233333333222222211111111111111000000000000///0//////////..-----,,,++,,++**))((''&&%%$$##""!!``!``!!!!!!```!!""##$$%%&&&%%$$##""!!`````!!""##$$%%&&''(())**+++++++********++,,++**))(('''(((())**++,,--..///..--,,++**))((''''&''(())***)**++**))((''&&%%$$##""!!!!``!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''(((('''&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//..--,,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667665544333445566778899::;;<<==>>???????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%&&''(())**++,,--..//00112233445566778899::;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(''&&%%$$$$$$$$###""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++,,--..//0011223333433333322222222222222211111110001000000000000000000//..-----,,,,,++**))((''&&%%$$##""!!```!!!!!````!!""##$$%%&&&%%$$##""!!``!!""##$$%%&&''(())**++,,,+++**+++++,,,,++**))((((((())**++,,--..//0//..--,,++**))(((''''(())******++**))((''&&%%$$##""!!!!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''''(''''&&&&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//..--,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556666554433233445566778899::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'''&&%%%%$$$$$####""!!``„`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,--..//001122334444444433333332222222222222211111111111100010000000000//.....---,,,++**))((''&&%%$$##""!!````!!``!!````!!""##$$%%&&&%%%$$##""!!``!!""##$$%%&&''(())**++,,,++++++++,,--,,++**))((())))**++,,--..//000//..--,,++**))(((('(())**+++*++**))((''&&%%$$##""!!``!!!``!!!""##$$%%&&''(())**++,,--..//00100//..--,,++**))((''&&''''&&&%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//..----..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566655443322233445566778899::;;<<==>>???????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$%%&&''(())**++,,--..//00112233445566778899::::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ǎ`!!""##$$%%&&''&&%%%%$$$$####"""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,--..//00112233444454444443333333333333332222222111211111111111111111100//.....--,,++**))((''&&%%%$$##""!!``````!!!!!!!""##$$%%&&&%%%%$$##""!!```!!""##$$%%&&''(())**++,,,,++,,,,,----,,++**)))))))**++,,--..//00100//..--,,++**)))(((())**++++++**))((''&&%%$$##""!!``!!!!!!!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&&&'&&&&%%%%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//..--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455665544332212233445566778899::;;<<==>>?????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###$$%%&&''(())**++,,--..//00112233445566778899:::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'&&%%$$$$#####""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-----..//0011223344555555554444444333333333333332222222222221111111111110000///..--,,++**))((''&&%%$$$##""!!!``!!!!!""##$$%%&&&%%$$$$$##""!!``!!""##$$%%&&''(())**++,,,,,,,,,--..--,,++**)))****++,,--..//0011100//..--,,++**))))())**++,,,++**))((''&&%%$$##""!!````!!!!`!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%&&&&%%%$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//....//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556554433221112233445566778899::;;<<==>>???????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####$$%%&&''(())**++,,--..//00112233445566778899::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'&&%%$$$$####""""!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---..//00112233445555655555544444444444444433333332222211222211111111100000//..--,,++**))((''&&%%$$$##""!!!``!!!!!""##$$%%%%%%$$$$$$##""!!``!!""##$$%%&&''(())**++,,-,,-----....--,,++*******++,,--..//001121100//..--,,++***))))**++,,,,++**))((''&&%%$$##""!!`È`!!``!!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%%%&%%%%$$$$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445555443322110112233445566778899::;;<<==>>?????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$%%&&''(())**++,,--..//0011223344556677889999887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&%%$$####"""""!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.....//00112233445566666666555555544444444444444333332211112211000001000/////..--,,++**))((''&&%%$$###""!!```!!!!!""##$$$%%%$$###$$##""!!``!!""##$$%%&&''(())**++,,-------..//..--,,++***++++,,--..//00112221100//..--,,++****)**++,,-,,++**))((''&&%%$$##""!!``!``!!""##$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$%%%%$$$########$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100////00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455544332211000112233445566778899::;;<<==>>???????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""##$$%%&&''(())**++,,--..//001122334455667788999887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&%%$$####""""!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...//00112233445566667666666555555555555555444444332211001111000000000/////..--,,++**))((''&&%%$$###""!!`````!!""##$$$$$$#####$##""!!``!!""##$$%%&&''(())**++,,---.....////..--,,+++++++,,--..//0011223221100//..--,,+++****++,,--,,++**))((''&&%%$$##""!!````!!""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$$$%$$$$#####"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334454433221100/00112233445566778899::;;<<==>>?????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%&%%$$##""""!!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////0011223344556677777777666666655555555555544333221100001100/////0///.....--,,++**))((''&&%%$$##"#""!!``!!""###$$$##"""###""!!``!!""##$$%%&&''(())**++,,--.....//00//..--,,+++,,,,--..//00112233221100//..--,,+++++*++,,----,,++**))((''&&%%$$##""!!`ʇ`!!""##$$%%&&''(())**++,,--...--,,++**))((''&&%%$$##$$$$###""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::9988776655443322110000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233444433221100///00112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!""##$$%%&&''(())**++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%$$%%%$$##""""!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///0011223344556677778777777666666666666665544333221100//0000/////////.....--,,++**))((''&&%%$$##""""!!!``!!""######"""""##""!!``!!""##$$%%&&''(())**++,,--..////0000//..--,,,,,,,--..//00112233221100//..--,,++**++++,,--.--,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..--,,++**))((''&&%%$$####$####"""""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//0011223344433221100//.//00112233445566778899::;;<<==>>?????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//0011223344556677887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%$$$$%$$##""!!!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110000011223344556677888888887777777666666665544332221100////00//...../...-----,,++**))((''&&%%$$##""!"!!!!``!!!"""###""!!!""#""!!``!!""##$$%%&&''(())**++,,--..///001100//..--,,,----..//00112233221100//..--,,++****++,,--..--,,++**))((''&&%%$$##""!!`@@@`!!""##$$%%&&''(())**++,,--.--,,++**))((''&&%%$$##""####"""!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::998877665544332211112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!```!!""##$$%%&&''(())**++,,--..//001122334433221100//...//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667787766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%$$##$$$##""!!!!`@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100011223344556677888898888887777777777665544332221100//..////.........-----,,++**))((''&&%%$$##""!!!!```!```!!""""""!!!!!""""!!``!!""##$$%%&&''(())**++,,--..//0011100//..-------..//00112233221100//..--,,++**))**++,,--..--,,++**))((''&&%%$$##""!!``@@`!!""##$$%%&&''(())**++,,----,,++**))((''&&%%$$##""""#""""!!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::9988776655443322112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!```!!""##$$%%&&''(())**++,,--..//00112233433221100//..-..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$####$##""!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211111223344556677889999999988888887777665544332211100//....//..-----.---,,,,,++**))((''&&%%$$##""!!`!```!!!"""!!```!!"""!!``!!""##$$%%&&''(())**++,,--..//00111100//..---....//00112233221100//..--,,++**))))**++,,--..--,,++**))((''&&%%$$##""!!`@@`!!""##$$%%&&''(())**++,,---,,++**))((''&&%%$$##""!!""""!!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433222233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!!``!!""##$$%%&&''(())**++,,--..//00112233433221100//..---..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$##""###""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111223344556677889999:99999988888877665544332211100//..--....---------,,,,,++**))((''&&%%$$##""!!````!!!!!!``!!""!!``!!""##$$%%&&''(())**++,,--..//001121100//.......//00112233221100//..--,,++**))(())**++,,--..--,,++**))((''&&%%$$##""!!``ʄ`!!""##$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!!!"!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????>>==<<;;::998877665544332233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!!````!!""##$$%%&&''(())**++,,--..//0011223333221100//..--,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$##""""##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332222233445566778899::::::::999998877665544332211000//..----..--,,,,,-,,,+++++**))((''&&%%$$##""!!````!!!``!!"!!``!!""##$$%%&&''(())**++,,--..//0011221100//...////00112233221100//..--,,++**))(((())**++,,----,,++**)*))((''&&%%$$##""!!`…`!!""##$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!``!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????>>==<<;;::9988776655443333445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""""!!!!``!!""##$$%%&&''(())**++,,--..//001122333221100//..--,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!""##$$%%&&''(())**++,,--..//0011223344556677889887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$##""!!""#""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322233445566778899::::;::::::998877665544332211000//..--,,----,,,,,,,,,+++++**))((''&&%%$$##""!!`````!!!!``!!""##$$%%&&''(())**++,,--..//0011221100///////00112233221100//..--,,++**))((''(())**++,,--,,++**)))))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!``!```!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????>>==<<;;::99887766554433445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####"""!!!!```!!""##$$%%&&''(())**++,,--..//00112233221100//..--,,+,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$##""!!!!""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433333445566778899::;;;;;;;::99887766554433221100///..--,,,,--,,+++++,+++*****))((''&&%%$$##""!!`@``!!"!!```!!""##$$%%&&''(())**++,,--..//0011221100///0000112233221100//..--,,++**))((''''(())**++,,,,++**))())))((''&&%%$$##""!!```!!!""##$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!````!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>?????????????????>>==<<;;::998877665544445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$####""""!!!```!!""##$$%%&&''(())**++,,--..//00112233221100//..--,,+++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"##$$%%&&''(())**++,,--..//001122334455667788999887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$$##""!!``!!""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544333445566778899::;;;;<;;::99887766554433221100///..--,,++,,,,+++++++++*****))((''&&%%$$##""!!``!!"!!``!!""##$$%%&&''(())**++,,--..//001122110000000112233221100//..--,,++**))((''&&''(())**++,,++**))((())))((''&&%%$$##""!!!!!!""##$$%%&&''(())**++,,---,,++**))((''&&%%$$##""!!``!```!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==??????????????????>>==<<;;::9988776655445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$###""""!!!!``!!""##$$%%&&''(())**++,,--..//0011223221100//..--,,++*++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###$$%%&&''(())**++,,--..//0011223344556677889999887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$$##""!!``!!"!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444445566778899::;;<<<;;::99887766554433221100//...--,,++++,,++*****+***)))))((''&&%%$$##""!!``!!!!``!!""##$$%%&&''(())**++,,--..//00112221100011112233221100//..--,,++**))((''&&&&''(())**++++**))(('(())))((''&&%%$$##""!!!"""##$$%%&&''(())**++,,---,,++**))((''&&%%$$##""!!`````````````!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=???????????????????>>==<<;;::99887766555566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$$$####"""!!!```!!""##$$%%&&''(())**++,,--..//001122221100//..--,,++***++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#$$%%&&''(())**++,,--..//00112233445566778899:99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!""##$$%$$##""!!``!!"!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554445566778899::;;<<<;;::99887766554433221100//...--,,++**++++*********)))))(((''&&%%$$##""!!```!!!``!!""##$$%%&&''(())**++,,--..//0011222211111112233221100//..--,,++**))((''&&%%&&''(())**++**))(('''(())))((''&&%%$$##""""""##$$%%&&''(())**++,,----,,++**))((''&&%%$$##""!!`````````!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<>==<<;;::998877665566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%$$$####""""!!!```!!""##$$%%&&''(())**++,,--..//00112221100//..--,,++**)**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!"""##$$%%%$$##""!!!!"!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665555566778899::;;<<<;;::99887766554433221100//..---,,++****++**)))))*)))(((((''''&&%%$$##""!!`````!!""##$$%%&&''((())**++,,--..//00112222111222233221100//..--,,++**))((''&&%%%%&&''(())****))((''&''((()))((''&&%%$$##"""###$$%%&&''(())**++,,--.--,,++**))((''&&%%$$##""!!``````!!!"!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=?????????????????????>>==<<;;::9988776666778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%%%$$$$###"""!!!!`Ó`!!""##$$%%&&''(())**++,,--..//0011221100//..--,,++**)))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$%%&&''(())**++,,--..//00112233445566778899:::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!!"""##$$%%&%%$$##""!!""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655566778899::;;<<<;;::99887766554433221100//..---,,++**))****)))))))))((((('''''&&%%$$##""!!``!!""##$$%%&&'''(())**++,,--..//001122222222233221100//..--,,++**))((''&&%%$$%%&&''(())**))((''&&&''((()))((''&&%%$$######$$%%&&''(())**++,,--...--,,++**))((''&&%%$$##""!!```!!!"""!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==??????????????????????>>==<<;;::99887766778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&%%%$$$$####"""!!``!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%&&''(())**++,,--..//00112233445566778899::::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!""""###$$%%&&&%%$$##"""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766666778899::;;<<<;;::99887766554433221100//..--,,,++**))))**))((((()((('''''&&'&&&%%$$##""!!``!!""##$$%%&&''''(())**++,,--..//0011222223333221100//..--,,++**))((''&&%%$$$$%%&&''(())))((''&&%&&'''(()))((''&&%%$$###$$$%%&&''(())**++,,--....--,,++**))((''&&%%$$##""!!``!!"""#""!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>???????????????????????>>==<<;;::998877778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''&&&&%%%%$$$###"""!!``!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!""""""###$$%%&&'&&%%$$##""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877666778899::;;<<<;;::99887766554433221100//..--,,,++**))(())))((((((((('''''&&&&&&&%%$$##""!!``!!""##$$%%&&&&&&''(())**++,,--..//00112233333221100//..--,,++**))((''&&%%$$##$$%%&&''(())((''&&%%%&&'''((())((''&&%%$$$$$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!```!!"""###""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????>>==<<;;::9988778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''&&&%%%%$$$$###""!!``!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))(('(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&''(())**++,,--..//00112233445566778899::;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`‹`!!!"""""####$$$%%&&'''&&%%$$###""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988777778899::;;<<<;;::99887766554433221100//..--,,+++**))(((())(('''''('''&&&&&%%&%%%%%$$##""!!```!!""##$$%%&&&&&&''(())**++,,--..//001122333221100//..--,,++**))((''&&%%$$####$$%%&&''((((''&&%%$%%&&&''((())((''&&%%$$$%%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""!!``!!!""###$##""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????>>==<<;;::99888899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((''''&&&&%%%$$$###""!!``!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))(('''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&''(())**++,,--..//00112233445566778899::;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""######$$$%%&&''(''&&%%$$###""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887778899::;;<<<;;::99887766554433221100//..--,,+++**))((''(((('''''''''&&&&&%%%%%%%%$$##""!!``!!""##$$%%%%%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%$$##""##$$%%&&''((''&&%%$$$%%&&&'''(())((''&&%%%%%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!```!!!""###$$$####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????>>==<<;;::998899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((('''&&&&%%%%$$$##""!!```!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''(())**++,,--..//00112233445566778899::;;<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""#####$$$$%%%&&''(((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998888899::;;<<<;;::99887766554433221100//..--,,++***))((''''((''&&&&&'&&&%%%%%$$%$$$$$##""!!``!!"""##$$%%%%%%&&''(())**++,,--..//00112221100//..--,,++**))((''&&%%$$##""""##$$%%&&''''&&%%$$#$$%%%&&'''((((''''&&%%%&&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!````!!!"""##$$$%$$##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????>>==<<;;::9999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))((((''''&&&%%%$$$##""!!``!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('(())**++,,--..//00112233445566778899::;;<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""###$$$$$$%%%&&''((((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988899::;;<<<;;::99887766554433221100//..--,,++***))((''&&''''&&&&&&&&&%%%%%$$$$$$$$##""!!``!!"""##$$$$$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!""##$$%%&&''&&%%$$###$$%%%&&&''((''''''&&&&&&''(())**++,,--..//000//..--,,++**))((''&&%%$$##""!!```!!!"""##$$$%%%$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????>>==<<;;::99::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))(((''''&&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$%%%%&&&''(())((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99999::;;<<<;;::99887766554433221100//..--,,++**)))((''&&&&''&&%%%%%&%%%$$$$$##$######""!!``!!!""##$$$$$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!!!""##$$%%&&&&%%$$##"##$$$%%&&&''''&&''''&&&'''(())**++,,--..//00100//..--,,++**))((''&&%%$$##""!!`!!!"""###$$%%%&%%$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????>>==<<;;::::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***))))(((('''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00100//..--,,++**))((''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))())**++,,--..//00112233445566778899::;;<<===<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$%%%%%%&&&''(()))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::999::;;<<<;;::99887766554433221100//..--,,++**)))((''&&%%&&&&%%%%%%%%%$$$$$########""""!!``!!!!""######$$%%&&''(())**++,,--..//00100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&%%$$##"""##$$$%%%&&''&&&&''''''''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!!!"""###$$%%%&&&%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????>>==<<;;::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****)))((((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))**++,,--..//00112233445566778899::;;<<====<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%&&&&'''(())))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::;;<<<;;::99887766554433221100//..--,,++**))(((''&&%%%%&&%%$$$$$%$$$#####""#"""""""!!````!!""######$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%$$##""!""###$$%%%&&&&%%&&'''''((())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!"""###$$$%%&&&'&&%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????>>==<<;;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++****))))((''&&%%$$##""!!`ϕ`!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)**++,,--..//00112233445566778899::;;<<==>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&&&&&'''(()))))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::;;<<<;;::99887766554433221100//..--,,++**))(((''&&%%$$%%%%$$$$$$$$$#####""""""""!!!!!``!!""""""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%$$##""!!!""###$$$%%&&%%%%&&''(((())**++,,--..//00112221100//..--,,++**))((''&&%%$$##""""###$$$%%&&&'''&&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????>>==<<;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++***)))((''&&%%$$##""!!`ƕ`!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***++,,--..//00112233445566778899::;;<<==>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Š`!!!!""##$$%%&&&&''''((())())))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;<<<;;::99887766554433221100//..--,,++**))(('''&&%%$$$$%%$$#####$###"""""!!"!!!!!!!```!!""""""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!``!!""##$$%%$$##""!!`!!"""##$$$%%%%$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%$$##"###$$$%%%&&'''(''&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????>>==<<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,++++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*++,,--..//00112233445566778899::;;<<==>>?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!""##$$%%&&''''''((())((()))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;<<<;;::99887766554433221100//..--,,++**))(('''&&%%$$##$$$$#########"""""!!!!!!!!````!!!!!!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!``!!""##$$%%$$##""!!``!!"""###$$%%$$$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%$$####$$$%%%&&'''(((''''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????>>==<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++,,--..//00112233445566778899::;;<<==>>??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""##$$%%&&''''(((()))(('(())((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<;;::99887766554433221100//..--,,++**))((''&&&%%$$####$$##"""""#"""!!!!!``!``````!!!!!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!!!""##$$%%%$$##""!!``!!!""###$$$$##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%$$#$$$%%%&&&''((()((''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????>>====>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,,,++**))((''&&%%$$##""!!`Г`!!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,+,,--..//00112233445566778899::;;<<==>>????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""##$$%%&&''(((((()))(('''(()((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<;;::99887766554433221100//..--,,++**))((''&&&%%$$##""####"""""""""!!!!!```````!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!""##$$%%%%$$##""!!```!!!"""##$$####$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%$$$$%%%&&&''((()))(((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????>>==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,,++**))((''&&%%$$##""!!`ϗ`!!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,,--..//00112233445566778899::;;<<==>>?????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""####$$%%&&''(((()))))((''&''((((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$##""""##""!!!!!"!!!`````!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""""##$$%%&&%%$$##""!!```!!"""####""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%$%%%&&&'''(()))*))(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,--..//00112233445566778899::;;<<==>>???????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""###$$%%&&''(()))))))((''&&&''(((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$##""!!""""!!!!!!!!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""##$$%%&&&&%%$$##""!!``!!!""##""""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%%%&&&'''(()))***))))**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..---..//00112233445566778899::;;<<==>>????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())))*))((''&&%&&''(''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$##""!!!!""!!`````!```!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$####$$%%&&'&&%%$$##""!!``!!!""""!!""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%&&&'''((())***+**))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..-..//00112233445566778899::;;<<==>>??????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())*))((''&&%%%&&'''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$##""!!``!!!!```!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$##$$%%&&'''&&%%$$##""!!```!!""!!!!""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&&&'''((())***+++****++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????>>==<<;;::99887766554433221100//...//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())))((''&&%%$%%&&''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""!!``!!```!!""""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$$$%%&&''''&&%%$$##""!!``!!!!``!!""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&'''((()))**+++,++**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????>>==<<;;::99887766554433221100//.//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())((''&&%%$$$%%&&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####""!!`````!!"""""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$%%&&''((''&&%%$$##""!!``!!``!!""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''''((()))**+++,,,++++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????>>==<<;;::99887766554433221100///00112233445566778899::;;<<==>>??????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()((''&&%%$$#$$%%&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""!!````!!"!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%%%&&''((((''&&%%$$##""!!```!!``!!""##$$%%&&''(())**++,,--..//001122333221100//..--,,++**))(('((()))***++,,,-,,++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʔ`!!""##$$%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%$$##""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????>>==<<;;::99887766554433221100/00112233445566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((((''&&%%$$###$$%%&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""""!!!``!!!!!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%&&''(())((''&&%%$$##""!!``Ď`!!!!""##$$%%&&''(())**++,,--..//00112233433221100//..--,,++**))(((()))***++,,,---,,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`×`!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????>>==<<;;::998877665544332211000112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''((''&&%%$$##"##$$%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!"!!!```!!``!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&&&''(())))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//001122334433221100//..--,,++**))()))***+++,,---.--,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ǘ`!!""##$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????>>==<<;;::9988776655443322110112233445566778899::;;<<==>>??????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''''&&%%$$##"""##$$%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!`````!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&''(())**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334433221100//..--,,++**))))***+++,,---...----..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`֞`!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????>>==<<;;::99887766554433221112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'''&&%%$$##""!""##$$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!````!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''''(())****))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334433221100//..--,,++**)***+++,,,--.../..--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????>>==<<;;::998877665544332212233445566778899::;;<<==>>??????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''&&%%$$##""!!!""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````!!""##$$%%&&''(())**++,,--..//00100//..--,,++**))((''(())**++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233444433221100//..--,,++****+++,,,--...///....//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????>>==<<;;::9988776655443322233445566778899::;;<<==>>???????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''&&%%$$##""!!`!!""##$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!""##$$%%&&''(())**++,,--..//00100//..--,,++**))(((())**++++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//001122334454433221100//..--,,++*+++,,,---..///0//..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ě`!!""##$$%%&&''(())**++,,--..//00112221100//..--,,++**))((''&&%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433233445566778899::;;<<==>>?????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&%%$$##""!!``!!""##$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00100//..--,,++**))(())**++,,++**))((''&&%%$$##""!!!```!!""##$$%%&&''(())**++,,--..//0011223344554433221100//..--,,++++,,,---..///000////00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʚ```!!""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????>>==<<;;::998877665544333445566778899::;;<<==>>???????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&%%$$##""!!``!!""##$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'''(())**++,,--..//00100//..--,,++**))))**++,,,,++**))((''&&%%$$##""!!!!``!!""##$$%%&&''(())**++,,--..//001122334455554433221100//..--,,+,,,---...//000100//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̘``!!!!""##$$%%&&''(())**++,,--..//001122333221100//..--,,++**))((''&&%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????>>==<<;;::9988776655443445566778899::;;<<==>>????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&%%$$##""!!``!!""##$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&''(())**++,,--..//00100//..--,,++**))**++,,--,,++**))((''&&%%$$##"""!!!!!""##$$%%&&''(())**++,,--..//00112233445566554433221100//..--,,,,---...//0001110000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ӗ`!!!!""##$$%%&&''(())**++,,--..//00112233433221100//..--,,++**))((''&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????>>==<<;;::99887766554445566778899::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ì`!!""##$$%%&&'&&%%$$##""!!!!""##$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&&''(())**++,,--..//00100//..--,,++****++,,----,,++**))((''&&%%$$##""""!!""##$$%%&&''(())**++,,--..//0011223344556666554433221100//..--,---...///0011121100112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``ӛ`!!"""##$$%%&&''(())**++,,--..//0011223344433221100//..--,,++**))((''&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::998877665545566778899::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'&&%%$$##""!!""##$$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&%%&&''(())**++,,--..//00100//..--,,++**++,,--..--,,++**))((''&&%%$$###"""""##$$%%&&''(())**++,,--..//001122334455667766554433221100//..----...///0011122211112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334454433221100//..--,,++**))(('''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>==<<;;::9988776655566778899::;;<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''&&%%$$##""""##$$%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%%%&&''(())**++,,--..//00100//..--,,++++,,--....--,,++**))((''&&%%$$####""##$$%%&&''(())**++,,--..//00112233445566777766554433221100//..-...///00011222322112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`‰`!!""##$$%%&&''(())**++,,--..//00112233445554433221100//..--,,++**))(('(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????>>==<<;;::99887766566778899::;;<<==>>????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''''&&%%$$##""##$$%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%$$%%&&''(())**++,,--..//00100//..--,,++,,--..//..--,,++**))((''&&%%$$$#####$$%%&&''(())**++,,--..//0011223344556677887766554433221100//....///00011222333222233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````````````!!""##$$%%&&''(())**++,,--..//0011223344556554433221100//..--,,++**))((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????>>==<<;;::998877666778899::;;<<==>>??????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ǎ`!!""##$$%%&&''(''&&%%$$####$$%%&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%$$$$%%&&''(())**++,,--..//00100//..--,,,,--..////..--,,++**))((''&&%%$$$$##$$%%&&''(())**++,,--..//001122334455667788887766554433221100//.///000111223334332233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//001122334455666554433221100//..--,,++**))())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????>>==<<;;::9988776778899::;;<<==>>??????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((''&&%%$$##$$%%&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$##$$%%&&''(())**++,,--..//00100//..--,,--..//00//..--,,++**))((''&&%%%$$$$$%%&&''(())**++,,--..//00112233445566778899887766554433221100////000111223334443333445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566766554433221100//..--,,++**)))**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????>>==<<;;::99887778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((((''&&%%$$$$%%&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$####$$%%&&''(())**++,,--..//00100//..----..//0000//..--,,++**))((''&&%%%%$$%%&&''(())**++,,--..//0011223344556677889999887766554433221100/0001112223344454433445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!""""""""""""""##$$%%&&''(())**++,,--..//0011223344556677766554433221100//..--,,++**)**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????>>==<<;;::998878899::;;<<==>>?????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɏ`!!""##$$%%&&''((((''&&%%$$%%&&&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""###""##$$%%&&''(())**++,,--..//00100//..--..//001100//..--,,++**))((''&&&%%%%%&&''(())**++,,--..//00112233445566778899::99887766554433221100001112223344455544445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƒ`!!""""""""""""""##$$%%&&''(())**++,,--..//001122334455667787766554433221100//..--,,++***++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????>>==<<;;::9988899::;;<<==>>?????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()((''&&%%%%&&'&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""#""""##$$%%&&''(())**++,,--..//00100//....//00111100//..--,,++**))((''&&&&%%&&''(())**++,,--..//00112233445566778899::::998877665544332211011122233344555655445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ñ``````!!""##############$$%%&&''(())**++,,--..//00112233445566778887766554433221100//..--,,++*++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????>>==<<;;::99899::;;<<==>>??????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())((''&&%%&&''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!""##$$%%&&''(())**++,,--..//00100//..//0011221100//..--,,++**))(('''&&&&&''(())**++,,--..//00112233445566778899::;;::9988776655443322111122233344555666555566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`͚```!!!!!!!""##############$$%%&&''(())**++,,--..//0011223344556677889887766554433221100//..--,,+++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::999::;;<<==>>????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())))((''&&&&'''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"!!!!""##$$%%&&''(())**++,,--..//00100////001122221100//..--,,++**))((''''&&''(())**++,,--..//00112233445566778899::;;;;::99887766554433221222333444556667665566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ԛ`!!!!!!!!!""##$$$$$$$$$$$$$$%%&&''(())**++,,--..//001122334455667788999887766554433221100//..--,,+,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????>>==<<;;::9::;;<<==>>?????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())*))((''&&''''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!``!!""##$$%%&&''(())**++,,--..//00100//00112233221100//..--,,++**))((('''''(())**++,,--..//00112233445566778899::;;<<;;::998877665544332222333444556667776666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`֛`!!!!"""""""##$$$$$$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899:99887766554433221100//..--,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::;;<<==>>??????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())***))((''''((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!``!!""##$$%%&&''(())**++,,--..//001000011223333221100//..--,,++**))((((''(())**++,,--..//00112233445566778899::;;<<<<;;::9988776655443323334445556677787766778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϔ`!!"""""""""##$$%%%%%%%%%%%%%%&&''(())**++,,--..//00112233445566778899:::99887766554433221100//..--,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????>>==<<;;:;;<<==>>????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())****))((''(((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!``!!""##$$%%&&''(())**++,,--..//0011001122334433221100//..--,,++**)))((((())**++,,--..//00112233445566778899::;;<<==<<;;::99887766554433334445556677788877778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""""#######$$%%%%%%%%%%%%%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..---..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;<<==>>?????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&''(())**++**))((((((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!``!!""##$$%%&&''(())**++,,--..//00111112233444433221100//..--,,++**))))(())**++,,,--..//00112233445566778899::;;<<===<<;;::998877665544344455566677888988778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""#########$$%%&&&&&&&&&&&&&&''(())**++,,--..//00112233445566778899::;;;::99887766554433221100//..-..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????>>==<<;<<==>>??????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!""##$$%%&&''(())**++++**))(())((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@``!!""##$$%%&&''(())**++,,--..//001111223344554433221100//..--,,++***)))))**++,,,,,--..//00112233445566778899::;;<<===<<;;::9988776655444455566677888999888899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ӗ`!!!""####$$$$$$$%%&&&&&&&&&&&&&&''(())**++,,--..//00112233445566778899::;;<;;::99887766554433221100//...//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????>>==<<<==>>???????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ŋ````!!!!!""##$$%%&&''(())**++,,++**))))))((''&&%%$$##""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@`!!""##$$%%&&''(())**++,,--..//0011222334455554433221100//..--,,++****))**++,,,,+,,--..//00112233445566778899::;;<<===<<;;::9988776655455566677788999:998899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$$$$$$$$%%&&''''''''''''''(())**++,,--..//00112233445566778899::;;<<<;;::99887766554433221100//.//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????>>==<==>>????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!!""""##$$%%&&''(())**++,,,,++**))**))((''&&%%$$##""!!!``````!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..//001122233445566554433221100//..--,,+++*****++,,,,+++,,--..//00112233445566778899::;;<<===<<;;::99887766555566677788999:::9999::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$$$%%%%%%%&&''''''''''''''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100///00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????>>===>>?????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!"""""##$$%%&&''(())**++,,--,,++******))((''&&%%$$##""!!!!````!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@`!!""##$$%%&&''(())**++,,--..//0011223344556666554433221100//..--,,++++**++,,,,++*++,,--..//00112233445566778899::;;<<===<<;;::99887766566677788899:::;::99::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`В`!!""##$$%%%%%%%%%&&''(((((((((((((())**++,,--..//00112233445566778899::;;<<===<<;;::99887766554433221100/00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????>>=>>??????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""""""####$$%%&&''(())**++,,----,,++**++**))((''&&%%$$##"""!!!!```!!!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667766554433221100//..--,,,+++++,,,,++***++,,--..//00112233445566778899::;;<<===<<;;::998877666677788899:::;;;::::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ŋ`!!""##$$%%%%&&&&&&&''(((((((((((((())**++,,--..//00112233445566778899::;;<<==>==<<;;::998877665544332211000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????>>>???????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""#####$$%%&&''(())**++,,--..--,,++++++**))((''&&%%$$##""""!!!`!!!!""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..//001122334455667766554433221100//..--,,,,++,,,,++**)**++,,--..//00112233445566778899::;;<<===<<;;::9988776777888999::;;;<;;::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ç`!!""##$$%%&&&&&&&&''(())))))))))))))**++,,--..//00112233445566778899::;;<<==>>>==<<;;::9988776655443322110112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????>?????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""####$$$$%%&&''(())**++,,--....--,,++,,++**))((''&&%%$$###""""!!!!""""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677766554433221100//..---,,,,,,,++**)))**++,,--..//00112233445566778899::;;<<===<<;;::99887777888999::;;;<<<;;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ŋ`!!""##$$%%&&''''''(())))))))))))))**++,,--..//00112233445566778899::;;<<==>>?>>==<<;;::99887766554433221112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$%%&&''(())**++,,--..//..--,,,,,,++**))((''&&%%$$####"""!""""######$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00011223344556677766554433221100//..----,,,,++**))())**++,,--..//00112233445566778899::;;<<===<<;;::99887888999:::;;<<<=<<;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʑ`!!""##$$%%&&''''''(())**************++,,--..//00112233445566778899::;;<<==>>???>>==<<;;::998877665544332212233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%&&''(())**++,,--..////..--,,--,,++**))((''&&%%$$$####""""######$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00/0011223344556677766554433221100//...---,,++**))((())**++,,--..//00112233445566778899::;;<<===<<;;::998888999:::;;<<<===<<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((((())**************++,,--..//00112233445566778899::;;<<==>>?????>>==<<;;::9988776655443322233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%&&''(())**++,,--..//00//..------,,++**))((''&&%%$$$$###"####$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--../////0011223344556677766554433221100//..--,,++**))(('(())**++,,--..//00112233445566778899::;;<<===<<;;::998999:::;;;<<===>==<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(((())**++++++++++++++,,--..//00112233445566778899::;;<<==>>???????>>==<<;;::99887766554433233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0000//..--..--,,++**))((''&&%%%$$$$####$$$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..///.//00112233445566766554433221100//..--,,++**))(('''(())**++,,--..//00112233445566778899::;;<<===<<;;::9999:::;;;<<===>>>====>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ė`!!""##$$%%&&''(()))**++++++++++++++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::998877665544333445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//......--,,++**))((''&&%%%%$$$#$$$$%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--../...//001122334455666554433221100//..--,,++**))((''&''(())**++,,--..//00112233445566778899::;;<<===<<;;::9:::;;;<<<==>>>?>>==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,,,,,,,,,,,,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::9988776655443445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011100//..//..--,,++**))((''&&&%%%%$$$$%%%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--...-..//0011223344556554433221100//..--,,++**))((''&&&''(())**++,,--..//00112233445566778899::;;<<===<<;;::::;;;<<<==>>>???>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,,,,,,,,,,,--..//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00111100//////..--,,++**))((''&&&&%%%$%%%%&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..---..//00112233445554433221100//..--,,++**))((''&&%&&''(())**++,,--..//00112233445566778899::;;<<===<<;;:;;;<<<===>>??????>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,-----------..//00112233445566778899::;;<<==>>???????????????>>==<<;;::998877665545566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011221100//00//..--,,++**))(('''&&&&%%%%&&&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--.--,--..//001122334454433221100//..--,,++**))((''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<===<<;;;;<<<===>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,----------..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988776655566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122211000000//..--,,++**))((''''&&&%&&&&''''''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,----,,,--..//0011223344433221100//..--,,++**))((''&&%%$%%&&''(())**++,,--..//00112233445566778899::;;<<===<<;<<<===>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--.........//00112233445566778899::;;<<==>>???????????????????>>==<<;;::99887766566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011222211001100//..--,,++**))(((''''&&&&''''''((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,---,,+,,--..//00112233433221100//..--,,++**))((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<===<<<<===>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`͏`!!""##$$%%&&''(())**++,,--.........//00112233445566778899::;;<<==>>?????????????????????>>==<<;;::998877666778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112232211111100//..--,,++**))(((('''&''''(((((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--,,+++,,--..//001122333221100//..--,,++**))((''&&%%$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<===<=====>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..////////00112233445566778899::;;<<==>>???????????????????????>>==<<;;::9988776778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122332211221100//..--,,++**)))((((''''(((((()))**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,-,,++*++,,--..//0011223221100//..--,,++**))((''&&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<====<<===>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..///////00112233445566778899::;;<<==>>?????????????????????????>>==<<;;::99887778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223332222221100//..--,,++**))))((('(((())))))**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!``!!""##$$%%&&''(())**++,,,++***++,,--..//00112221100//..--,,++**))((''&&%%$$##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<<<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0000000112233445566778899::;;<<==>>???????????????????????????>>==<<;;::998878899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//001122334332233221100//..--,,++***))))(((())))))***++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!``!!""##$$%%&&''(())**++,,++**)**++,,--..//001121100//..--,,++**))((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<;;<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//000000112233445566778899::;;<<==>>?????????????????????????????>>==<<;;::9988899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344333333221100//..--,,++****)))())))******++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!``!!""##$$%%&&''(())**++,++**)))**++,,--..//0011100//..--,,++**))((''&&%%$$##""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<;;;;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00111112233445566778899::;;<<==>>???????????????????????????????>>==<<;;::99899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334444334433221100//..--,,+++****))))******+++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!``!!""##$$%%&&''(())**++++**))())**++,,--..//00100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;::;;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00111112233445566778899::;;<<==>>?????????????????????????????????>>==<<;;::999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445544444433221100//..--,,++++***)****++++++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!``!!""##$$%%&&''(())**+++**))((())**++,,--..//000//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;::::::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//00112222233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::9::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344555544554433221100//..--,,,++++****++++++,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!"!!``!!""##$$%%&&''(())**+++**))(('(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::::99:::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//00112222233445566778899::;;<<==>>?????????????????????????????????????>>==<<;;:::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//001122334455665555554433221100//..--,,,,+++*++++,,,,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!``!!""##$$%%&&''(())**++**))(('''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//001122334455566778899::999999::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$%%&&''(())**++,,--..//00112233333445566778899::;;<<==>>???????????????????????????????????????>>==<<;;:;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//00112233445566665566554433221100//..---,,,,++++,,,,,,---..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"#""!!``!!""##$$%%&&''(())**++**))((''&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//0011112233444556677889999988999::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$%%&&''(())**++,,--..//00112233333445566778899::;;<<==>>?????????????????????????????????????????>>==<<;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//0011223344556677666666554433221100//..----,,,+,,,,------..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""!!``!!""##$$%%&&''(())**+**))((''&&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!""##$$%%&&''(())**++,,--....//0001112233444556677889988888899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233444445566778899::;;<<==>>???????????????????????????????????????????>>==<<;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667777667766554433221100//...----,,,,------...//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())****))((''&&%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##"""##$$%%&&''(())**++,,--......//0000112233344556677888887788899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233444445566778899::;;<<==>>?????????????????????????????????????????????>>==<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677877777766554433221100//....---,----......//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())***))((''&&%%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##"##$$%%&&''(())**++,,--....--..///000112233344556677887777778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƒ`!!""##$$%%&&''(())**++,,--..//0011223344555566778899::;;<<==>>???????????????????????????????????????????????>>==<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455667788877887766554433221100///....----......///00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**))((''&&%%$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$###$$%%&&''(())**++,,--....----..////00112223344556677777667778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344555566778899::;;<<==>>?????????????????????????????????????????????????>>===>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778898888887766554433221100////...-....//////00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**))((''&&%%$$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$#$$%%&&''(())**++,,--....--,,--...///00112223344556677666666778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`‡`!!""##$$%%&&''(())**++,,--..//001122334455666778899::;;<<==>>???????????????????????????????????????????????????>>=>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899988998877665544332211000////....//////000112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())*))((''&&%%$$#$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$$%%&&''(())**++,,--....--,,,,--....//00111223344556666655666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̉`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677889999999988776655443322110000///.////000000112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`‡`!!""##$$%%&&''(())*))((''&&%%$$###$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$%%&&''(())**++,,--....--,,++,,---...//00111223344556655555566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`͉@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899:99::99887766554433221110000////0000001112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())))((''&&%%$$##"##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%%&&''(())**++,,--....--,,++++,,----..//00011223344555554455566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʏ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899:::::::99887766554433221111000/00001111112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()))((''&&%%$$##"""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%&&''(())**++,,--....--,,++**++,,,---..//00011223344554444445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɛ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;::;;::998877665544332221111000011111122233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())((''&&%%$$##""!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&&''(())**++,,--....--,,++****++,,,,--..///0011223344444334445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɠ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;;;;::9988776655443322221110111122222233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&''(())**++,,--....--,,++**))**+++,,,--..///0011223344333333445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;<<;;::99887766554433322221111222222333445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//0//..--,,++**))(('''(())**++,,--....--,,++**))))**++++,,--...//0011223333322333445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<<<;;::998877665544333322212222333333445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0//..--,,++**))(('(())**++,,--....--,,++**))(())***+++,,--...//0011223322222233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȏ@``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<==<<;;::9988776655444333322223333334445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((())**++,,--....--,,++**))(((())****++,,---..//0011222221122233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ə`!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<======<<;;::99887766554444333233334444445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````````!```!!""##$$%%&&''(()((''&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//0000//..--,,++**))())**++,,--....--,,++**))((''(()))***++,,---..//0011221111112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȑ`!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<====>>==<<;;::998877665554444333344444455566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!!!!!!!!!!``!!""##$$%%&&''(()))((''&&%%$$##""!!!""##$$%%&&''(())**++,,--..//001100//..--,,++**)))**++,,--....--,,++**))((''''(())))**++,,,--..//0011111001112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ŏ``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ˆ`!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>>>>==<<;;::9988776655554443444455555566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!!!!!!!!!!!"!!!```````!!""##$$%%&&''(())*))((''&&%%$$##""!""##$$%%&&''(())**++,,--..//00111100//..--,,++**)**++,,--....--,,++**))((''&&''((()))**++,,,--..//0011000000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>>??>>==<<;;::99887766655554444555555666778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!!!!!"""""""""""!!!!!!!```!!""##$$%%&&''(())**))((''&&%%$$##"""##$$%%&&''(())**++,,--..//0011221100//..--,,++***++,,--....--,,++**))((''&&&&''(((())**+++,,--..//00000//000112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????>>==<<;;::998877666655545555666666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````````!!!!!!!""""""""""""#"""!!!!!!!!````!!""##$$%%&&''(())***))((''&&%%$$##"##$$%%&&''(())**++,,--..//001122221100//..--,,++*++,,--....--,,++**))((''&&%%&&'''((())**+++,,--..//00//////00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????>>==<<;;::9988777666655556666667778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!!!!!""""""""###########"""""""!!!!``!!""##$$%%&&''(())**+**))((''&&%%$$###$$%%&&''(())**++,,--..//00112233221100//..--,,+++,,--....--,,++**))((''&&%%%%&&''''(())***++,,--../////..///00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????>>==<<;;::99887777666566667777778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!!!!!!!"""""""############$###""""""""!!!``!!""##$$%%&&''(())**++**))((''&&%%$$#$$%%&&''(())**++,,--..//0011223333221100//..--,,+,,--....--,,++**))((''&&%%$$%%&&&'''(())***++,,--..//......//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::998887777666677777788899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!!!""""""""""""########$$$$$$$$$$$#######"""!!``!!""##$$%%&&''(())**++++**))((''&&%%$$$%%&&''(())**++,,--..//001122334433221100//..--,,,--....--,,++**))((''&&%%$$$$%%&&&&''(()))**++,,--.....--...//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::9988887776777788888899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!`````!!!!""""""""""#######$$$$$$$$$$$$%$$$########""!!```!!""##$$%%&&''(())**++,,++**))((''&&%%$%%&&''(())**++,,--..//00112233444433221100//..--,--....--,,++**))((''&&%%$$##$$%%%&&&''(()))**++,,--..------..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȋ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????>>==<<;;::99988887777888888999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!!!""""############$$$$$$$$%%%%%%%%%%%$$$$$$$###""!!``!!""##$$%%&&''(())**++,,,,++**))((''&&%%%&&''(())**++,,--..//0011223344554433221100//..---....--,,++**))((''&&%%$$####$$%%%%&&''((())**++,,-----,,---..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ċ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????>>==<<;;::999988878888999999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!""""##########$$$$$$$%%%%%%%%%%%%&%%%$$$$$$$$##""!!``@`!!""##$$%%&&''(())**++,,--,,++**))((''&&%&&''(())**++,,--..//001122334455554433221100//..-....--,,++**))((''&&%%$$##""##$$$%%%&&''((())**++,,--,,,,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;:::99998888999999:::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""####$$$$$$$$$$$$%%%%%%%%&&&&&&&&&&&%%%%%%%$$##""!!`@`!!""##$$%%&&''(())**++,,----,,++**))((''&&&''(())**++,,--..//00112233445566554433221100//.....--,,++**))((''&&%%$$##""""##$$$$%%&&'''(())**++,,,,,++,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`‡`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!"""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????>>==<<;;::::99989999::::::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""####$$$$$$$$$$%%%%%%%&&&&&&&&&&&&'&&&%%%%%%$$##""!!```!!""##$$%%&&''(())**++,,--.--,,++**))((''&''(())**++,,--..//0011223344556666554433221100//...--,,++**))((''&&%%$$##""!!""###$$$%%&&'''(())**++,,++++++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ā````!!!!"""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????>>==<<;;;::::9999::::::;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""####$$$$%%%%%%%%%%%%&&&&&&&&'''''''''''&&&&&%%$$##""!!```````!!""##$$%%&&''(())**++,,--...--,,++**))(('''(())**++,,--..//00112233445566766554433221100//..--,,++**))((''&&%%$$##""!!!!""####$$%%&&&''(())**+++++**+++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`€``!`!!!!!"""###$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????>>==<<;;;;:::9::::;;;;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````````````!!""####$$$$%%%%%%%%%%&&&&&&&''''''''''''('''&&&&&%%$$##""!!`!```!``!!""##$$%%&&''(())**++,,--....--,,++**))(('(())**++,,--..//00112233445566766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""###$$%%&&&''(())**++******++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!`````````````!!!!!!""""###$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????>>==<<<;;;;::::;;;;;;<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!````!!!!!!!````!!``!!""##$$$$%%%%&&&&&&&&&&&&''''''''((((((((((('''''&&%%$$##""!!!!``!!!``!!""##$$%%&&''(())**++,,--../..--,,++**))((())**++,,--..//00112233445566766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""##$$%%%&&''(())*****))***++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Â``!!!!!!!!!!!````!!!!!"!"""""###$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????>>==<<<<;;;:;;;;<<<<<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!!!!!!!!!!!!!!""##$$$$%%%%&&&&&&&&&&'''''''(((((((((((()((('''''&&%%$$##""!!``!!!!```!!""##$$%%&&''(())**++,,--..///..--,,++**))())**++,,--..//00112233445566766554433221100//..--,,++**))((''&&%%$$##""!!``!!!"""##$$%%%&&''(())**))))))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````````!!!"!!!!!!!!!!!!!!!!!""""""####$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????>>===<<<<;;;;<<<<<<===>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!!!!!"""""""!!!!""!!""##$$%%%%&&&&''''''''''''(((((((()))))))))))((((''&&%%$$##""!!``!!!```!!""##$$%%&&''(())**++,,--..////..--,,++**)))**++,,--..//0011223344556677766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!""##$$$%%&&''(()))))(()))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!`````!!!!!!!"""""""""""!!!!"""""#"#####$$$%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????>>====<<<;<<<<======>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!````!!!"""""""""""""""""""""##$$%%%%&&&&''''''''''((((((())))))))))))*)))(((''&&%%$$##""!!``!!``````!!""##$$%%&&''(())**++,,--..//00//..--,,++**)**++,,--..//00112233445566777766554433221100//..--,,++**))((''&&%%$$##""!!```!!!""##$$$%%&&''(())(((((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!``!!!!!!!!!"""#"""""""""""""""""######$$$$%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????>>>====<<<<======>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!``!!!!!""""""#######""""##""##$$%%&&&&''''(((((((((((())))))))***********)))((''&&%%$$##""!!``````!!""##$$%%&&''(())**++,,--..//000//..--,,++***++,,--..//0011223344556677887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""###$$%%&&''(((((''((())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`‹`!`````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""!!````!!!!!"""""""###########""""#####$#$$$$$%%%&&&'''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????>>>>===<====>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!``!!!!"""#####################$$%%&&&&''''(((((((((()))))))************+***)))((''&&%%$$##""!!!``````!!""##$$%%&&''(())**++,,--..//0000//..--,,++*++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""###$$%%&&''((''''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ï`!!!``!!!!```!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""!!!!!!"""""""""###$#################$$$$$$%%%%&&&'''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????>>>>====>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!`````````````!!"""""######$$$$$$$####$$##$$%%&&''''(((())))))))))))********+++++++++++***))((''&&%%$$##""!!!!````````!!""##$$%%&&''(())**++,,--..//00100//..--,,+++,,--..//0011223344556677889887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$%%&&'''''&&'''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####""!!!!"""""#######$$$$$$$$$$$####$$$$$%$%%%%%&&&'''((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????>>>=>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####""!!!!!!!!!!!!!!!""""###$$$$$$$$$$$$$$$$$$$$$%%&&''''(((())))))))))*******++++++++++++,+++***))((''&&%%$$##"""!!!!!!```````````!!""##$$%%&&''(())**++,,--..//0011100//..--,,+,,--..//00112233445566778899887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$%%&&''&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"!!""""!!!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####""""""#########$$$%$$$$$$$$$$$$$$$$$%%%%%%&&&&'''((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####""!!!!!!!!!!!!!""#####$$$$$$%%%%%%%$$$$%%$$%%&&''(((())))************++++++++,,,,,,,,,,,+++**))((''&&%%$$##""""!!!!````!!""##$$%%&&''(())**++,,--..//001121100//..--,,,--..//0011223344556677889999887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!""##$$%%&&&&&%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$##""""#####$$$$$$$%%%%%%%%%%%$$$$%%%%%&%&&&&&'''((()))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$##"""""""""""""""####$$$%%%%%%%%%%%%%%%%%%%%%&&''(((())))**********+++++++,,,,,,,,,,,,-,,,+++**))((''&&%%$$###"""!!`Ƅ€``!!""##$$%%&&''(())**++,,--..//00112221100//..--,--..//00112233445566778899::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!""##$$%%&&%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!"""####"""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$######$$$$$$$$$%%%&%%%%%%%%%%%%%%%%%&&&&&&''''((()))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$##"""""""""""""##$$$$$%%%%%%&&&&&&&%%%%&&%%&&''(())))****++++++++++++,,,,,,,,-----------,,,++**))((''&&%%$$###""!!````!``!!""##$$%%&&''(())**++,,--..//0011223221100//..---..//00112233445566778899::::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!```!!""##$$%%%%%$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʐ``!!""##########$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%$$####$$$$$%%%%%%%&&&&&&&&&&&%%%%&&&&&'&'''''((()))***++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%$$###############$$$$%%%&&&&&&&&&&&&&&&&&&&&&''(())))****++++++++++,,,,,,,------------.---,,,++**))((''&&%%$$##""!!``!!!!``!!""##$$%%&&''(())**++,,--..//00112233221100//..-..//00112233445566778899::;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$###$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%$$$$$$%%%%%%%%%&&&'&&&&&&&&&&&&&&&&&''''''(((()))***++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%$$#############$$%%%%%&&&&&&'''''''&&&&''&&''(())****++++,,,,,,,,,,,,--------...........---,,++**))((''&&%%$$##""!!``````````!!!"!!``!!""##$$%%&&''(())**++,,--..//001122333221100//...//00112233445566778899::;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$##$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&%%$$$$%%%%%&&&&&&&'''''''''''&&&&'''''('((((()))***+++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&%%$$$$$$$$$$$$$$$%%%%&&&'''''''''''''''''''''(())****++++,,,,,,,,,,-------............/...---,,++**))((''&&%%$$##""!!!!!!!!!!!!""""!!``!!""##$$%%&&''(())**++,,--..//0011223333221100//.//00112233445566778899::;;<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""##$$$######$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&%%%%%%&&&&&&&&&'''('''''''''''''''''(((((())))***+++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&%%$$$$$$$$$$$$$%%&&&&&''''''(((((((''''((''(())**++++,,,,------------........///////////...--,,++**))((''&&%%$$##""!!!!!!!!!!"""""!!``!!""##$$%%&&''(())**++,,--..//00112233433221100///00112233445566778899::;;<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""##$###""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''''&&%%%%&&&&&'''''''(((((((((((''''((((()()))))***+++,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''&&%%%%%%%%%%%%%%%&&&&'''((((((((((((((((((((())**++++,,,,----------.......////////////0///...--,,++**))((''&&%%$$##""""""""""""##""!!``!!""##$$%%&&''(())**++,,--..//0011223344433221100/00112233445566778899::;;<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""####""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''''&&&&&&'''''''''((()((((((((((((((((())))))****+++,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''&&%%%%%%%%%%%%%&&'''''(((((()))))))(((())(())**++,,,,----............////////00000000000///..--,,++**))((''&&%%$$##""""""""""###""!!``!!""##$$%%&&''(())**++,,--..//001122334444332211000112233445566778899::;;<<==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""###"""!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((((''&&&&'''''((((((()))))))))))(((()))))*)*****+++,,,---..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((((''&&&&&&&&&&&&&&&''''((()))))))))))))))))))))**++,,,,----..........///////0000000000001000///..--,,++**))((''&&%%$$##############""!!``!!""##$$%%&&''(())**++,,--..//00112233445443322110112233445566778899::;;<<===<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""""!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((((''''''((((((((()))*)))))))))))))))))******++++,,,---..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((((''&&&&&&&&&&&&&''((((())))))*******))))**))**++,,----....////////////0000000011111111111000//..--,,++**))((''&&%%$$##########$##""!!``!!""##$$%%&&''(())**++,,--..//0011223344554433221112233445566778899::;;<<==>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!!``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ç`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))((''''((((()))))))***********))))*****+*+++++,,,---...//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))(('''''''''''''''(((()))*********************++,,----....//////////00000001111111111112111000//..--,,++**))((''&&%%$$$$$$$$$$$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455544332212233445566778899::;;<<==>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`É`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))(((((()))))))))***+*****************++++++,,,,---...//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))(('''''''''''''(()))))******+++++++****++**++,,--....////000000000000111111112222222222211100//..--,,++**))((''&&%%$$$$$$$$$$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445555443322233445566778899::;;<<==>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`…`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*****))(((()))))*******+++++++++++****+++++,+,,,,,---...///00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****))((((((((((((((())))***+++++++++++++++++++++,,--....////00000000001111111222222222222322211100//..--,,++**))((''&&%%%%%%%%%%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566554433233445566778899::;;<<==>>?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*****))))))*********+++,+++++++++++++++++,,,,,,----...///00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****))((((((((((((())*****++++++,,,,,,,++++,,++,,--..////000011111111111122222222333333333332221100//..--,,++**))((''&&%%%%%%%%%%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566665544333445566778899::;;<<==>>?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++++**))))*****+++++++,,,,,,,,,,,++++,,,,,-,-----...///000112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++**)))))))))))))))****+++,,,,,,,,,,,,,,,,,,,,,--..////00001111111111222222233333333333343332221100//..--,,++**))((''&&&&&&&&&&&&%%$$##""!!`````````!!""##$$%%&&''(())**++,,--..//00112233445566776655443445566778899::;;<<==>>??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++++******+++++++++,,,-,,,,,,,,,,,,,,,,,------....///000112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++**)))))))))))))**+++++,,,,,,-------,,,,--,,--..//000011112222222222223333333344444444444333221100//..--,,++**))((''&&&&&&&&&&&&%%$$##""!!``````!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566777766554445566778899::;;<<==>>??>>==<<;;::998877665544433221100//..--,,++**))((''&&%%$$##""!!`†`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``̒``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,++****+++++,,,,,,,-----------,,,,-----.-.....///0001112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,++***************++++,,,---------------------..//00001111222222222233333334444444444445444333221100//..--,,++**))((''''''''''''&&%%$$##""!!!!````!!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778877665545566778899::;;<<==>>??>>==<<;;::9988776655444332211100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``ʎ`!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,++++++,,,,,,,,,---.-----------------......////0001112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,++*************++,,,,,------.......----..--..//0011112222333333333333444444445555555555544433221100//..--,,++**))((''''''''''''&&%%$$##""!!!!````````!!!!!"""""""""##$$%%&&''(())**++,,--..//00112233445566778888776655566778899::;;<<==>>??>>==<<;;::9988776655443332211100//..--,,++**))((''&&%%$$##""!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-----,,++++,,,,,-------...........----....././////00011122233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..----,,+++++++++++++++,,,,---.....................//001111222233333333334444444555555555555655544433221100//..--,,++**))((((((((((((''&&%%$$##""""!!``!!!!````!!```!!"""""""""""##$$%%&&''(())**++,,--..//00112233445566778899887766566778899::;;<<==>>??>>==<<;;::9988776655443332211000//..--,,++**))((''&&%%$$##""!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-----,,,,,,---------.../.................//////000011122233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..----,,+++++++++++++,,-----......///////....//..//00112222333344444444444455555555666666666665554433221100//..--,,++**))((((((((((((''&&%%$$##""""!!!!!!!!!```!!!!!``````!!""""#########$$%%&&''(())**++,,--..//00112233445566778899998877666778899::;;<<==>>??>>==<<;;::9988776655443322211000//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.....--,,,,-----.......///////////..../////0/00000111222333445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//....--,,,,,,,,,,,,,,,----.../////////////////////0011222233334444444444555555566666666666676665554433221100//..--,,++**))))))))))))((''&&%%$$####""!!""""!!!!```!!""!!!!!``!!!"""""########$$%%&&''(())**++,,--..//00112233445566778899::9988776778899::;;<<==>>??>>==<<;;::998877665544332221100///..--,,++**))((''&&%%$$##""!!`ň€`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````````````!!!!!!""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.....------.........///0/////////////////0000001111222333445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//....--,,,,,,,,,,,,,--.....//////0000000////00//001122333344445555555555556666666677777777777666554433221100//..--,,++**))))))))))))((''&&%%$$####"""""""""!!!!``!!!""""!!!!```!!"""!!""##$$$$$$%%&&''(())**++,,--..//00112233445566778899::::99887778899::;;<<==>>??>>==<<;;::998877665544332211100///..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȉ`!!!!!!!!!!!!!!!""""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////..----.....///////00000000000////0000010111112223334445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100////..---------------....///000000000000000000000112233334444555555555566666667777777777778777666554433221100//..--,,++************))((''&&%%$$$$##""####""""!!!!``!!""""""!!!```!!"""!!!!""##$$$$%%&&''(())**++,,--..//00112233445566778899::;;::998878899::;;<<==>>??>>==<<;;::998877665544332211100//...--,,++**))((''&&%%$$$##""!!``!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`È`!!!!!!!!!!!!""""""####$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////....../////////00010000000000000000011111122223334445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100////..-------------../////00000011111110000110011223344445555666666666666777777778888888888877766554433221100//..--,,++************))((''&&%%$$$$#########"""!!``!!""""""!!!!!!"""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;::9988899::;;<<==>>??>>==<<;;::998877665544332211000//...--,,++**))((''&&%%$$####""!!``!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``Ń`!!"""""""""""""######$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100000//..../////000000011111111111000011111212222233344455566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110000//...............////00011111111111111111111122334444555566666666667777777888888888888988877766554433221100//..--,,++++++++++++**))((''&&%%%%$$##$$$$##""!!``!!"""##"""!!!"""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;::99899::;;<<==>>??>>==<<;;::998877665544332211000//..---,,++**))((''&&%%$$###"""""!!```!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""""""""######$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100000//////000000000111211111111111111111222222333344455566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110000//.............//000001111112222222111122112233445555666677777777777788888888999999999998887766554433221100//..--,,++++++++++++**))((''&&%%%%$$$$$$$##""!!``!!!!""##"""""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;::999::;;<<==>>??>>==<<;;::99887766554433221100///..---,,++**))((''&&%%$$##""""!!""!!!```!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""############$$$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221111100////000001111111222222222221111222223233333444555666778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111100///////////////000011122222222222222222222233445555666677777777778888888999999999999:9998887766554433221100//..--,,,,,,,,,,,,++**))((''&&&&%%$$%%$$##""!!``!!!!!"""##"""#""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;::9::;;<<==>>??>>==<<;;::99887766554433221100///..--,,,++**))((''&&%%$$##"""!!!!!""!!!!``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""########$$$$$$%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111110000001111111112223222222222222222223333334444555666778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111100/////////////00111112222223333333222233223344556666777788888888888899999999:::::::::::999887766554433221100//..--,,,,,,,,,,,,++**))((''&&&&%%%%%%$$##""!!``!!``!!""""###""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<;;:::;;<<==>>??>>==<<;;::99887766554433221100//...--,,,++**))((''&&%%$$##""!!!!``!!""!!!!````!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ë`!!""##$$$$$$$$%%%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433222221100001111122222223333333333322223333343444445556667778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433222211000000000000000111122233333333333333333333344556666777788888888889999999::::::::::::;:::999887766554433221100//..------------,,++**))((''''&&%%&&%%$$##""!!``!!``!!!"""""""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<;;:;;<<==>>??>>==<<;;::99887766554433221100//...--,,+++**))((''&&%%$$##""!!!```!!!!!!!!!``!!""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ĉ`!!""##$$$$$$%%%%%%&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332222211111122222222233343333333333333333344444455556667778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332222110000000000000112222233333344444443333443344556677778888999999999999::::::::;;;;;;;;;;;:::99887766554433221100//..------------,,++**))((''''&&&&&&%%$$##""!!!!!```!!!!"""!!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<;;;<<==>>??>>==<<;;::99887766554433221100//..---,,+++**))((''&&%%$$##""!!``À`!!!``!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%%%%&&&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443333322111122222333333344444444444333344444545555566677788899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433332211111111111111122223334444444444444444444445566777788889999999999:::::::;;;;;;;;;;;;<;;;:::99887766554433221100//............--,,++**))((((''&&''&&%%$$##""!!!```!!!!!!!!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<;<<==>>??>>==<<;;::99887766554433221100//..---,,++***))((''&&%%$$##""!!``!!``!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%%&&&&&&''''((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433333222222333333333444544444444444444444555555666677788899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443333221111111111111223333344444455555554444554455667788889999::::::::::::;;;;;;;;<<<<<<<<<<<;;;::99887766554433221100//............--,,++**))((((''''''&&%%$$##""!!```!!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<<==>>??>>==<<;;::99887766554433221100//..--,,,++***)))((''&&%%$$##""!!````!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`͏`!!""##$$%%&&&&&&&''''''((())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544444332222333334444444555555555554444555556566666777888999::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554444332222222222222223333444555555555555555555555667788889999::::::::::;;;;;;;<<<<<<<<<<<<=<<<;;;::99887766554433221100////////////..--,,++**))))((''(''&&%%$$##""!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==<==>>??>>==<<;;::99887766554433221100//..--,,,++**)))))((''&&%%$$##""!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ņ```````!!""##$$%%&&&&&''''''(((()))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444443333334444444445556555555555555555556666667777888999::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444433222222222222233444445555556666666555566556677889999::::;;;;;;;;;;;;<<<<<<<<===========<<<;;::99887766554433221100////////////..--,,++**))))((((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<====>>??>>==<<;;::99887766554433221100//..--,,+++**)))(((((''&&%%$$##""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!````````!!!""##$$%%&&'''''''(((((()))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655555443333444445555555666666666665555666667677777888999:::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766555544333333333333333444455566666666666666666666677889999::::;;;;;;;;;;<<<<<<<============>===<<<;;::998877665544332211000000000000//..--,,++****))(((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<===>>??>>==<<;;::99887766554433221100//..--,,+++**))((((('''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!!!!!!!""##$$%%&&'''''(((((())))***++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766555554444445555555556667666666666666666667777778888999:::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655554433333333333334455555666666777777766667766778899::::;;;;<<<<<<<<<<<<========>>>>>>>>>>>===<<;;::998877665544332211000000000000//..--,,++****)))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??>>==<<;;::99887766554433221100//..--,,++***))((('''''&&%%$$##""!!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!!!!!"""##$$%%&&''((((((())))))***++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766666554444555556666666777777777776666777778788888999:::;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766665544444444444444455556667777777777777777777778899::::;;;;<<<<<<<<<<=======>>>>>>>>>>>>?>>>===<<;;::998877665544332211111111111100//..--,,++++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?>>==<<;;::99887766554433221100//..--,,++***))(('''''&&&%%$$##""!!``````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!""""""##$$%%&&''((((())))))****+++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877666665555556666666667778777777777777777778888889999:::;;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877666655444444444444455666667777778888888777788778899::;;;;<<<<============>>>>>>>>???????????>>>==<<;;::998877665544332211111111111100//..--,,++++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>>==<<;;::99887766554433221100//..--,,++**)))(('''&&&&&%%$$##""!!`Œ`!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````````!!"""###$$%%&&''(()))))))******+++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877777665555666667777777888888888887777888889899999:::;;;<<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988777766555555555555555666677788888888888888888888899::;;;;<<<<==========>>>>>>>????????????????>>>==<<;;::998877665544332222222222221100//..--,,,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>==<<;;::99887766554433221100//..--,,++**)))((''&&&&&%%%$$$##""!!``!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɇ@`!!""##$$%%&&''(()))))******++++,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877777666666777777777888988888888888888888999999::::;;;<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887777665555555555555667777788888899999998888998899::;;<<<<====>>>>>>>>>>>>??????????????????????>>==<<;;::998877665544332222222222221100//..--,,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>==<<;;::99887766554433221100//..--,,++**))(((''&&&%%%%%$$$###""!!`Ȕ`!!""!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())******++++++,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998888877666677777888888899999999999888899999:9:::::;;;<<<===>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998888776666666666666667777888999999999999999999999::;;<<<<====>>>>>>>>>>??????????????????????????>>==<<;;::998877665544333333333333221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>==<<;;::99887766554433221100//..--,,++**))(((''&&%%%%%$$$###"""!!``!!""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@@`!!""##$$%%&&''(())***++++++,,,,---..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988888777777888888888999:99999999999999999::::::;;;;<<<===>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988887766666666666667788888999999:::::::9999::99::;;<<====>>>>????????????????????????????????????>>==<<;;::99887766554433333333333221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<====<<;;::99887766554433221100//..--,,++**))(('''&&%%%$$$$$###"""!!``!!""##""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++++,,,,,,---..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99999887777888889999999:::::::::::9999:::::;:;;;;;<<<===>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9999887777777777777778888999:::::::::::::::::::::;;<<====>>>>??????????????????????????????????????>>==<<;;::9988776655444444444433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<====<<;;::99887766554433221100//..--,,++**))(('''&&%%$$$$$###"""!!!``!!""#######$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,,,,----...//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99999888888999999999:::;:::::::::::::::::;;;;;;<<<<===>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99998877777777777778899999::::::;;;;;;;::::;;::;;<<==>>>>??????????????????????????????????????????>>==<<;;::9988776655444444444433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<===<<;;::99887766554433221100//..--,,++**))((''&&&%%$$$#####"""!!!```!!""##$####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`Í@`!!""##$$%%&&''(())**++,,------...//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::99888899999:::::::;;;;;;;;;;;::::;;;;;<;<<<<<===>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::::998888888888888889999:::;;;;;;;;;;;;;;;;;;;;;<<==>>>>????????????????????????????????????????????>>==<<;;::998877665555555554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<===<<;;::99887766554433221100//..--,,++**))((''&&&%%$$#####"""!!!```!!""##$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`@````!!""##$$%%&&''(())**++,,----....///00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::999999:::::::::;;;<;;;;;;;;;;;;;;;;;<<<<<<====>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::::99888888888888899:::::;;;;;;<<<<<<<;;;;<<;;<<==>>????????????????????????????????????????????????>>==<<;;::998877665555555554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$###"""""!!!``!!""##$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```@```!!!!!""##$$%%&&''(())**++,,--......///00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;::9999:::::;;;;;;;<<<<<<<<<<<;;;;<<<<<=<=====>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;::999999999999999::::;;;<<<<<<<<<<<<<<<<<<<<<==>>??????????????????????????????????????????????????>>==<<;;::998877666666666554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%%$$##"""""!!!`````!!""##$$%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@Ë`!!!!!!!""##$$%%&&''(())**++,,--....////000112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;::::::;;;;;;;;;<<<=<<<<<<<<<<<<<<<<<======>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;::9999999999999::;;;;;<<<<<<=======<<<<==<<==>>????????????????????????????????????????????????????>>==<<;;::998877666666666554433221100//..--,,++**))((''&&%%$$##""!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$$##"""!!!!!```!!""##$$%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@@@@@`!!!!"""""##$$%%&&''(())**++,,--..//////000112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<;;::::;;;;;<<<<<<<===========<<<<=====>=>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<;;:::::::::::::::;;;;<<<=====================>>??????????????????????????????????????????????????????>>==<<;;::998877777777766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$$##""!!!!!```!!""##$$%%&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@@`!!""""""##$$%%&&''(())**++,,--..////00001112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<;;;;;;<<<<<<<<<===>=================>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<;;:::::::::::::;;<<<<<======>>>>>>>====>>==>>????????????????????????????????????????????????????????>>==<<;;::998877777777766554433221100//..--,,++**))((''&&%%$$##""!!``````!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""!!!```ʒ`!!""##$$%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""#####$$%%&&''(())**++,,--..//0000001112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=====<<;;;;<<<<<=======>>>>>>>>>>>====>>>>>?>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>====<<;;;;;;;;;;;;;;;<<<<===>>>>>>>>>>>>>>>>>>>>>??????????????????????????????????????????????????????????>>==<<;;::998888888887766554433221100//..--,,++**))((''&&%%$$##""!!!!!``!!!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!""###$$%%&&''(())**++,,--..//0000111122233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=====<<<<<<=========>>>?>>>>>>>>>>>>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>====<<;;;;;;;;;;;;;<<=====>>>>>>???????>>>>??>>????????????????????????????????????????????????????????????>>==<<;;::998888888887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!``````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$$%%&&''(())**++,,--..//0011111122233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>==<<<<=====>>>>>>>???????????>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>==<<<<<<<<<<<<<<<====>>>?????????????????????????????????????????????????????????????????????????????????>>==<<;;::999999999887766554433221100//..--,,++**))((''&&%%$$##"""""!!"""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!`````!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001112222333445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>======>>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>==<<<<<<<<<<<<<==>>>>>???????????????????????????????????????????????????????????????????????????????????>>==<<;;::999999999887766554433221100//..--,,++**))((''&&%%$$##""""""""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122222333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>====>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===============>>>>??????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::::::99887766554433221100//..--,,++**))((''&&%%$$#####""###$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!!!!""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122233334445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=============>>??????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::::::99887766554433221100//..--,,++**))((''&&%%$$########$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&''(())**++,,--..//001122333333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;;;;;::99887766554433221100//..--,,++**))((''&&%%$$$$$##$$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɔ`!!"""######$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!``!!""##$$%%&&''(())**++,,--..//0011222223333445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;;;;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""######$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!`````!!""##$$%%&&''(())**++,,--..//001122222222233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<<<<;;::99887766554433221100//..--,,++**))((''&&%%%%%$$%%%&&&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````!!!!!""##$$%%&&''(())**++,,--..//00111221111222233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<<<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%%%&&&&''(())**++,,--..//00112233445566778899::;;<<==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!""##$$%%&&''(())**++,,--..//0011111111111112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=========<<;;::99887766554433221100//..--,,++**))((''&&&&&%%&&&''''(())**++,,--..//00112233445566778899::;;<<==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!"""""##$$%%&&''(())**++,,--..//000000011000011112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=========<<;;::99887766554433221100//..--,,++**))((''&&&&&&&&''''(())**++,,--..//00112233445566778899::;;<<==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""""##$$%%&&''(())**++,,--..//00000000000000000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>==<<;;::99887766554433221100//..--,,++**))(('''''&&'''(((())**++,,--..//00112233445566778899::;;<<===<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!"""#####$$%%&&''(())**++,,--..///0/0/////00////0000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>==<<;;::99887766554433221100//..--,,++**))((''''''''(((())**++,,--..//00112233445566778899::;;<<====<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!""""""##$$%%&&''(())**++,,--.././/////////////////00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((((''((())))**++,,--..//00112233445566778899::;;<<==>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&'''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""""""##$$%%&&''(())**++,,--...././.....//....////00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((((((())))**++,,--..//00112233445566778899::;;<<==>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``````!!!""##$$%%&&'''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!""##$$%%&&''(())**++,,--.-..................//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))(()))****++,,--..//00112233445566778899::;;<<==>>??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!````!!!""##$$%%&&''((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!""##$$%%&&''(())**++,,----.-.-----..----....//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))))))****++,,--..//00112233445566778899::;;<<==>>????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!!`€`!!"""##$$%%&&''((())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```````!!""##$$%%&&''(())**++,,-,------------------..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*****))***++++,,--..//00112233445566778899::;;<<==>>??????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!````````!!"""##$$%%&&''(()))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&''(())**++,,,,-,-,,,,,--,,,,----..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++********++++,,--..//00112233445566778899::;;<<==>>????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!""###$$%%&&''(()))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!``!!""##$$%%&&''(())**++,,+,,,,,,,,,,,,,,,,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++++**+++,,,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!""###$$%%&&''(())***++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!````!!""##$$%%&&''(())**++,+++,+,+++++,,++++,,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++++++,,,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!````!!""""""""##$$$%%&&''(())***++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++++*++++++++++++++++++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,++,,,----..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""!!`!!!!""""""""##$$$%%&&''(())**+++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**+++***+*+*****++****++++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,,,,----..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!""!!!!!""########$$%%%&&''(())**+++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++**)******************++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-----,,---....//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""!""""########$$%%%&&''(())**++,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**+**)))*)*)))))**))))****++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--------....//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""""##$$$$$$$$%%&&&''(())**++,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())****))())))))))))))))))))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.....--...////00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""####$$$$$$$$%%&&&''(())**++,,---..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&''(())****))((()()((((())(((())))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//........////00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!""#####$$%%%%%%%%&&'''(())**++,,---..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!""##$$%%&&''(())****))(('(((((((((((((((((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////..///0000112233445566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""###$$$$%%%%%%%%&&'''(())**++,,--...//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!""##$$%%&&''(())****))(('''('('''''((''''(((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100////////0000112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""##$$$$$%%&&&&&&&&''((())**++,,--...//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""""##$$%%&&''(())****))((''&''''''''''''''''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100000//00011112233445566778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""##$$$%%%%&&&&&&&&''((())**++,,--..///00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""""##$$%%&&''(())****))((''&&&'&'&&&&&''&&&&''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110000000011112233445566778899::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####$$%%%%%&&''''''''(()))**++,,--..///00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!"""####$$%%&&''(())****))((''&&%&&&&&&&&&&&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221111100111222233445566778899::;;<<==>>???????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##$$%%%&&&&''''''''(()))**++,,--..//000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""####$$%%&&''(())****))((''&&%%%&%&%%%%%&&%%%%&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211111111222233445566778899::;;<<==>>?????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$%%&&&&&''(((((((())***++,,--..//000112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""###$$$$%%&&''(())****))((''&&%%$%%%%%%%%%%%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322222112223333445566778899::;;<<==>>???????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$%%&&&''''(((((((())***++,,--..//001112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$%%&&''(())****))((''&&%%$$$%$%$$$$$%%$$$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433222222223333445566778899::;;<<==>>?????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%&&'''''(())))))))**+++,,--..//001112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())****))((''&&%%$$#$$$$$$$$$$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544333332233344445566778899::;;<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%&&'''(((())))))))**+++,,--..//001122233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())****))((''&&%%$$###$#$#####$$####$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443333333344445566778899::;;<<==>>?????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&''((((())********++,,,--..//001122233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())****))((''&&%%$$##"##################$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554444433444555566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&''((())))********++,,,--..//001122333445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&''(())****))((''&&%%$$##"""#"#"""""##""""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544444444555566778899::;;<<==>>?????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''(()))))**++++++++,,---..//001122333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!""##$$%%&&''(())****))((''&&%%$$##""!""""""""""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655555445556666778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''(()))****++++++++,,---..//001122334445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!""##$$%%&&''(())****))((''&&%%$$##""!!!"!"!!!!!""!!!!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766555555556666778899::;;<<==>>?????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((())*****++,,,,,,,,--...//001122334445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""##$$%%&&''(())****))((''&&%%$$##""!!`!!!!!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877666665566677778899::;;<<==>>???????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(())***++++,,,,,,,,--...//001122334455566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!"""##$$%%&&''(())****))((''&&%%$$##""!!``!`!`````!!````!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776666666677778899::;;<<==>>?????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))**+++++,,--------..///001122334455566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())*****))((''&&%%$$##""!!`````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887777766777888899::;;<<==>>???????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))**+++,,,,--------..///001122334455666778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())******))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877777777888899::;;<<==>>?????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++****++,,,,,--........//0001122334455666778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`À`!!""##$$%%&&''(()))))**))((''&&%%$$##""!!`!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988888778889999::;;<<==>>???????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**++,,,----........//0001122334455667778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()))))))((''&&%%$$##""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99888888889999::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++,,-----..////////0011122334455667778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(((((()))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9999988999::::;;<<==>>???????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++,,---....////////0011122334455667788899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((((((((((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99999999::::;;<<==>>?????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,--.....//0000000011222334455667788899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''''''((((((''&&%%$$##""!!````!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::99:::;;;;<<==>>???????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,--...////0000000011222334455667788999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''''''''''''''&&%%$$##""!!```````!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::::::::;;;;<<==>>?????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..----../////0011111111223334455667788999::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@`!!""##$$%%&&&&&&&''''''''''&&%%$$##""!!```!!````!!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;::;;;<<<<==>>???????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--..///00001111111122333445566778899:::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%&&&&&&&&&&&&&''''&&%%$$##""!!!!!!!``!`!!!!!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;;;;<<<<==>>?????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//....//000001122222222334445566778899:::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%%%%%%&&&&&&&&''''&&%%$$##""!!!""!!!!!!!"""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<;;<<<====>>???????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..//000111122222222334445566778899::;;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""###$$$$%%%%%%%%%%%%%&&''''&&%%$$##"""""""!!"!"""""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<<<====>>?????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100////001111122333333334455566778899::;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""####$$$$$$$$$%%%%%%%%&&''''&&%%$$##"""##"""""""#####$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=====<<===>>>>???????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//001112222333333334455566778899::;;<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``@`!!""""####$$$$$$$$$$$$$%%&&''''&&%%$$#######""#"#####$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>========>>>>?????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100001122222334444444455666778899::;;<<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@`!!""""#########$$$$$$$$%%&&''''&&%%$$###$$#######$$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>==>>>?????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211001122233334444444455666778899::;;<<===>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!""""#############$$%%&&''''&&%%$$$$$$$##$#$$$$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111122333334455555555667778899::;;<<===>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!"""""""""########$$%%&&''''&&%%$$$%%$$$$$$$%%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>??????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221122333444455555555667778899::;;<<==>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!````!!!!"""""""""""""##$$%%&&''''&&%%%%%%%$$%$%%%%%&&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332222334444455666666667788899::;;<<==>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!!!""""""""##$$%%&&''''&&%%%&&%%%%%%%&&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322334445555666666667788899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````````!!!!!!!!!!!!!""##$$%%&&''''&&&&&&&%%&%&&&&&''''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433334455555667777777788999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````````!!!!!!!!""##$$%%&&''''&&&''&&&&&&&'''''((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544334455566667777777788999::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````````````!!""##$$%%&&'''''''''&&'&'''''(((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544445566666778888888899:::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!``!!""##$$%%&&'''''(('''''''((((()))**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655445566677778888888899:::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!````!!""##$$%%&&''((((((''('((((())))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766555566777778899999999::;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""!!``!```!`````!!""##$$%%&&''(((())((((((()))))***++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665566777888899999999::;;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""""!!!!!`!```````!!!``!!!!!""##$$%%&&''(())))))(()()))))****++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>????????>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776666778888899::::::::;;<<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""##""!!"!!!!!````!!!!!!"!!!!!!!""##$$%%&&''(())))**)))))))*****+++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>??????>>==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766778889999::::::::;;<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$######"""""!"!!!!!````````!!!!!!"""!!"""""##$$%%&&''(())******))*)*****++++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>====>>????>>====>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877778899999::;;;;;;;;<<===>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##$$##""#"""""!!!!!!!```````!!!""""""#"""""""##$$%%&&''(())****++*******+++++,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>????????????????????????????????????????>>======>>??>>==<<==>>?????????????????????????????????????????????????>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887788999::::;;;;;;;;<<===>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$#####"#"""""!!!!!!!!!!``!!""""""###""#####$$%%&&''(())**++++++**+*+++++,,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>??????????????????????????????????????>>==<<<<==>>>>==<<<<==>>?????????????????????????????????????????>>>>>>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99888899:::::;;<<<<<<<<==>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$%%$$##$#####"""""""!!!!!!!```!!""######$#######$$%%&&''(())**++++,,+++++++,,,,,---..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>>>>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>====>>?????????????????>>>>>??????????????>>==<<<<<<==>>==<<;;<<==>>>>??????????????????????????????????>>>>>>>>>>>====>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998899:::;;;;<<<<<<<<==>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%$$$$$#$#####""""""""""!!!````!!""######$$$##$$$$$%%&&''(())**++,,,,,,++,+,,,,,----..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>==============>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>======>>???????????????>>>>>>>>??????>>???>>==<<;;;;<<====<<;;;;<<==>>>>>>>>>>>>???????????????????????>>>>>>=============>>>>??????????????????????????????????????????????????????????????>>>?>??????????????????>>>>>>>>>>>>>>>>>>>>>>>>>>?>>>>>>>>>>?>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9999::;;;;;<<========>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%&&%%$$%$$$$$#######"""""""!!!!!!!""##$$$$$$%$$$$$$$%%&&''(())**++,,,,--,,,,,,,-----...//001122334445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>=========================>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<==>>??????>>>>>??>>=====>>>??>>>>>>>>>==<<;;;;;;<<==<<;;::;;<<====>>>>>>>>>>>>>>>????????????????>>>===========<<<<=====>>>>>????????????????????????????????????????????????????????>>>>>>>>>???????????????>>>>>>>>>>>>>>>>>>>====>>>>>>>>>>>>>>>>>>>>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99::;;;<<<<========>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&&%%%%%$%$$$$$##########"""!!!!""##$$$$$$%%%$$%%%%%&&''(())**++,,------,,-,-----....//00112233444445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==============<<<<<<<<<<<<<<=====>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>??????????????????????????????>>>>==<<<<<<==>>>??>>>>>>>>>>========>>>>>>==>>>==<<;;::::;;<<<<;;::::;;<<============>>>>>>>>>>>>?????????>>======<<<<<<<<<<<<<====>>>>>>>???????????????????????????????????????????>>>>>>???>>>===>=>>>?????????????>>==========================>==========>=======>>>>>>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::::;;<<<<<==>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&''&&%%&%%%%%$$$$$$$#######"""""""##$$%%%%%%&%%%%%%%&&''(())**++,,----..-------.....///0011223333333445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>?????>>=======<<<<<<<<<<<<<<<<<<<<<<<<<=======>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>?>>>>??????>>>>>>>???>>>?>>>>>==<<;;;;<<==>>>>>>=====>>==<<<<<===>>=========<<;;::::::;;<<;;::99::;;<<<<===============>>>>>>>???????>>===<<<<<<<<<<<;;;;<<<<<=====>>>>????????????????????????????>>???????>>>>>>>>>>>>>>>=========>>???????????>>===================<<<<=========================>>>>>>>>>>>>>>>>>?>>?>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::;;<<<====>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''''&&&&&%&%%%%%$$$$$$$$$$###""""##$$%%%%%%&&&%%&&&&&''(())**++,,--......--.-...../////00112223333333445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>?>>==<<<<<<<<<<<<<<;;;;;;;;;;;;;;<<<<<======>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>====<<;;;;;;<<===>>==========<<<<<<<<======<<===<<;;::9999::;;;;::9999::;;<<<<<<<<<<<<============>>>>>>>>>==<<<<<<;;;;;;;;;;;;;<<<<=======>>???????????????????????>>>>>>>?>>>>>>>>>>======>>>===<<<=<===>>?????????>>==<<<<<<<<<<<<<<<<<<<<<<<<<<=<<<<<<<<<<=<<<<<<<===========>>>>>>>>>>>>>>???>>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;<<=====>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''((''&&'&&&&&%%%%%%%$$$$$$$#######$$%%&&&&&&'&&&&&&&''(())**++,,--....//......./////////00112222222233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>====>>>>>==<<<<<<<;;;;;;;;;;;;;;;;;;;;;;;;;<<<<<<<==>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=======>====>>>>>>=======>>>===>=====<<;;::::;;<<======<<<<<==<<;;;;;<<<==<<<<<<<<<;;::999999::;;::998899::;;;;<<<<<<<<<<<<<<<=======>>>>>>>==<<<;;;;;;;;;;;::::;;;;;<<<<<====>>?>>>????>>>>>????>>>>>>>>>==>>>>>>>===============<<<<<<<<<==>>>>>>>>>>>==<<<<<<<<<<<<<<<<<<<;;;;<<<<<<<<<<<<<<<<<<<<<<<<<=================>==>=>>>>>>>>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;<<===>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((((('''''&'&&&&&%%%%%%%%%%$$$####$$%%&&&&&&'''&&'''''(())**++,,--..//////.././/........//00111222222233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>???>>========>==<<;;;;;;;;;;;;;;::::::::::::::;;;;;<<<<<<==>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>==<<<==============================<<<<;;::::::;;<<<==<<<<<<<<<<;;;;;;;;<<<<<<;;<<<;;::99888899::::99888899::;;;;;;;;;;;;<<<<<<<<<<<<=========<<;;;;;;:::::::::::::;;;;<<<<<<<==>>>>>>>>>>>>>>>>>>>>>>>=======>==========<<<<<<===<<<;;;<;<<<==>>>>>>>>>==<<;;;;;;;;;;;;;;;;;;;;;;;;;;<;;;;;;;;;;<;;;;;;;<<<<<<<<<<<==============>>>=======>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<==>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(())((''('''''&&&&&&&%%%%%%%$$$$$$$%%&&''''''('''''''(())**++,,--..///////////...........//00111111112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>==<<<<=====<<;;;;;;;:::::::::::::::::::::::::;;;;;;;<<===>>>>>>>?>>>>>>>>>?????????????>?????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>==<<<<<<<=<<<<======<<<<<<<===<<<=<<<<<;;::9999::;;<<<<<<;;;;;<<;;:::::;;;<<;;;;;;;;;::9988888899::9988778899::::;;;;;;;;;;;;;;;<<<<<<<=======<<;;;:::::::::::9999:::::;;;;;<<<<==>===>>>>=====>>>>=========<<=======<<<<<<<<<<<<<<<;;;;;;;;;<<===========<<;;;;;;;;;;;;;;;;;;;::::;;;;;;;;;;;;;;;;;;;;;;;;;<<<<<<<<<<<<<<<<<=<<=<===============>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<==>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))))))((((('('''''&&&&&&&&&&%%%$$$$%%&&''''''(((''((((())**++,,--../////////.....--------..//00011111112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=====>>>==<<<<<<<<=<<;;::::::::::::::99999999999999:::::;;;;;;<<========>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>=====<<;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;;;;::999999::;;;<<;;;;;;;;;;::::::::;;;;;;::;;;::998877778899998877778899::::::::::::;;;;;;;;;;;;<<<<<<<<<;;::::::9999999999999::::;;;;;;;<<=======================<<<<<<<=<<<<<<<<<<;;;;;;<<<;;;:::;:;;;<<=========<<;;::::::::::::::::::::::::::;::::::::::;:::::::;;;;;;;;;;;<<<<<<<<<<<<<<===<<<<<<<=====>>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????>>====>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))**))(()((((('''''''&&&&&&&%%%%%%%&&''(((((()((((((())**++,,--..///..........-----------..//00000000112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>==========<<;;;;<<<<<;;:::::::9999999999999999999999999:::::::;;<<<=======>=========>>>>>>>>>>>>>=>>>>>>>>>>>>>>>>>?>>>?????????>>>>?????????????????????????????????????????????????????????????????>>>>>>>>>>======<<;;;;;;;<;;;;<<<<<<;;;;;;;<<<;;;<;;;;;::99888899::;;;;;;:::::;;::99999:::;;:::::::::9988777777889988776677889999:::::::::::::::;;;;;;;<<<<<<<;;:::99999999999888899999:::::;;;;<<=<<<====<<<<<====<<<<<<<<<;;<<<<<<<;;;;;;;;;;;;;;;:::::::::;;<<<<<<<<<<<;;:::::::::::::::::::9999:::::::::::::::::::::::::;;;;;;;;;;;;;;;;;<;;<;<<<<<<<<<<<<<<<==>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++******)))))()(((((''''''''''&&&%%%%&&''(((((()))(()))))**++,,--..///........-----,,,,,,,,--..///0000000112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>==<<<<<===<<;;;;;;;;<;;::999999999999998888888888888899999::::::;;<<<<<<<<===============================>>>>>>>>>>>>>>>>>>>>>>>>>>>>>??????????????????????????????????????????????????????????>>>>>>>>>>>=======<<<<<;;:::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::9988888899:::;;::::::::::99999999::::::99:::99887766667788887766667788999999999999::::::::::::;;;;;;;;;::99999988888888888889999:::::::;;<<<<<<<<<<<<<<<<<<<<<<<;;;;;;;<;;;;;;;;;;::::::;;;:::999:9:::;;<<<<<<<<<;;::99999999999999999999999999:9999999999:9999999:::::::::::;;;;;;;;;;;;;;<<<;;;;;;;<<<<<=======>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**++**))*)))))((((((('''''''&&&&&&&''(())))))*)))))))**++,,--../....----------,,,,,,,,,,,--..////////00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>========<<<<<<<<<<;;::::;;;;;::999999988888888888888888888888889999999::;;;<<<<<<<=<<<<<<<<<=============<=================>===>>>>>>>>>====>>????????????????????????????????????????????????????>>>>>>>>>>>==========<<<<<<;;:::::::;::::;;;;;;:::::::;;;:::;:::::998877778899::::::99999::9988888999::9999999998877666666778877665566778888999999999999999:::::::;;;;;;;::9998888888888877778888899999::::;;<;;;<<<<;;;;;<<<<;;;;;;;;;::;;;;;;;:::::::::::::::999999999::;;;;;;;;;;;::999999999999999999988889999999999999999999999999:::::::::::::::::;::;:;;;;;;;;;;;;;;;<<========>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++++++*****)*)))))(((((((((('''&&&&''(())))))***))*****++,,--../....--------,,,,,++++++++,,--...///////00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>========<<;;;;;<<<;;::::::::;::99888888888888887777777777777788888999999::;;;;;;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<=============================>>??????????????????????????????????????????????>>>>>>>>>>===========<<<<<<<;;;;;::999::::::::::::::::::::::::::::::99998877777788999::9999999999888888889999998899988776655556677776655556677888888888888999999999999:::::::::99888888777777777777788889999999::;;;;;;;;;;;;;;;;;;;;;;;:::::::;::::::::::999999:::99988898999::;;;;;;;;;::9988888888888888888888888888988888888889888888899999999999::::::::::::::;;;:::::::;;;;;<<<<<<<===>>>??????????????????????????????????>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++,,++**+*****)))))))((((((('''''''(())******+*******++,,--.....----,,,,,,,,,,+++++++++++,,--........//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>=========<<<<<<<<;;;;;;;;;;::9999:::::9988888887777777777777777777777777888888899:::;;;;;;;<;;;;;;;;;<<<<<<<<<<<<<;<<<<<<<<<<<<<<<<<=<<<=========<<<<==>>????????????????????????????????????????????>>>>>>===========<<<<<<<<<<;;;;;;::9999999:9999::::::9999999:::999:99999887766667788999999888889988777778889988888888877665555556677665544556677778888888888888889999999:::::::9988877777777777666677777888889999::;:::;;;;:::::;;;;:::::::::99:::::::99999999999999988888888899:::::::::::9988888888888888888887777888888888888888888888888899999999999999999:99:9:::::::::::::::;;<<<<<<<<===>>>>>>>>>>>>>>>>>>>>>>????????????>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,,+++++*+*****))))))))))(((''''(())******+++**+++++,,--.--..----,,,,,,,,+++++********++,,---.......//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>===========<<<<<<<<;;:::::;;;::99999999:998877777777777777666666666666667777788888899::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<==>>??????????????????????????????????????????>>==========<<<<<<<<<<<;;;;;;;:::::99888999999999999999999999999999999888877666666778889988888888887777777788888877888776655444455666655444455667777777777778888888888889999999998877777766666666666667777888888899:::::::::::::::::::::::9999999:99999999998888889998887778788899:::::::::99887777777777777777777777777787777777777877777778888888888899999999999999:::9999999:::::;;;;;;;<<<===>>>>>>>>>>>>>>>>>>>>>>??????????>>====>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,--,,++,+++++*******)))))))((((((())**++++++,+++++++,,--.------,,,,++++++++++***********++,,--------..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>????????????????????????????????>>>>>>=========<<<<<<<<<;;;;;;;;::::::::::998888999998877777776666666666666666666666666777777788999:::::::;:::::::::;;;;;;;;;;;;;:;;;;;;;;;;;;;;;;;<;;;<<<<<<<<<;;;;<<==>>????????????????????????????????????????>>======<<<<<<<<<<<;;;;;;;;;;::::::9988888889888899999988888889998889888887766555566778888887777788776666677788777777777665544444455665544334455666677777777777777788888889999999887776666666666655556666677777888899:999::::99999::::9999999998899999998888888888888887777777778899999999999887777777777777777777666677777777777777777777777778888888888888888898898999999999999999::;;;;;;;;<<<======================>>>>>>>>>>>>========>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..------,,,,,+,+++++**********)))(((())**++++++,,,++,,,,,--.--,,--,,,,++++++++*****))))))))**++,,,-------..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>????????????????????????????>>>>>>=========<<<<<<<<<<<;;;;;;;;::99999:::9988888888988776666666666666655555555555555666667777778899999999:::::::::::::::::::::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<<==>>??????????????????????????????????????>>==<<<<<<<<<<;;;;;;;;;;;:::::::999998877788888888888888888888888888888877776655555566777887777777777666666667777776677766554433334455554433334455666666666666777777777777888888888776666665555555555555666677777778899999999999999999999999888888898888888888777777888777666767778899999999988776666666666666666666666666676666666666766666667777777777788888888888888999888888899999:::::::;;;<<<======================>>>>>>>>>>==<<<<====>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--..--,,-,,,,,+++++++*******)))))))**++,,,,,,-,,,,,,,--.--,,,,,,++++**********)))))))))))**++,,,,,,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>==========>>??????????????????????????>>>>======<<<<<<<<<;;;;;;;;;::::::::99999999998877778888877666666655555555555555555555555556666666778889999999:999999999:::::::::::::9:::::::::::::::::;:::;;;;;;;;;::::;;<<==>>????????????????????????????????????>>==<<<<<<;;;;;;;;;;;::::::::::999999887777777877778888887777777888777877777665544445566777777666667766555556667766666666655443333334455443322334455556666666666666667777777888888877666555555555554444555556666677778898889999888889999888888888778888888777777777777777666666666778888888888877666666666666666666655556666666666666666666666666777777777777777778778788888888888888899::::::::;;;<<<<<<<<<<<<<<<<<<<<<<============<<<<<<<<==>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//......-----,-,,,,,++++++++++***))))**++,,,,,,---,,-----.--,,++,,++++********)))))(((((((())**+++,,,,,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=============>>>???????????????????????>>======<<<<<<<<<;;;;;;;;;;;::::::::998888899988777777778776655555555555555444444444444445555566666677888888889999999999999999999999999999999:::::::::::::::::::::::::::::;;<<==>>??????????????????????????????>>>>>>==<<;;;;;;;;;;:::::::::::99999998888877666777777777777777777777777777777666655444444556667766666666665555555566666655666554433222233444433222233445555555555556666666666667777777776655555544444444444445555666666677888888888888888888888887777777877777777776666667776665556566677888888888776655555555555555555555555555655555555556555555566666666666777777777777778887777777888889999999:::;;;<<<<<<<<<<<<<<<<<<<<<<==========<<;;;;<<<<===>>>>>>>>>>>>>>>>>?>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..//..--.-----,,,,,,,+++++++*******++,,------.-------.--,,++++++****))))))))))((((((((((())**++++++++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===<<<<<<<<<<==>>>?????????????????????>>====<<<<<<;;;;;;;;;:::::::::999999998888888888776666777776655555554444444444444444444444444555555566777888888898888888889999999999999899999999999999999:999:::::::::9999::;;<<==>>?????????????????????????>>>>>>>>>==<<;;;;;;:::::::::::999999999988888877666666676666777777666666677766676666655443333445566666655555665544444555665555555554433222222334433221122334444555555555555555666666677777776655544444444444333344444555556666778777888877777888877777777766777777766666666666666655555555566777777777776655555555555555555554444555555555555555555555555566666666666666666766767777777777777778899999999:::;;;;;;;;;;;;;;;;;;;;;;<<<<<<<<<<<<;;;;;;;;<<=====>>>>>>>>>>>>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//////.....-.-----,,,,,,,,,,+++****++,,------...--....--,,++**++****))))))))(((((''''''''(())***+++++++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<<<<<<<<===>>???>>??????????????>>==<<<<<<;;;;;;;;;:::::::::::9999999988777778887766666666766554444444444444433333333333333444445555556677777777888888888888888888888888888888899999999999999999999999999999::;;<<==>>??????????????????????>>>>>>======<<;;::::::::::9999999999988888887777766555666666666666666666666666666666555544333333445556655555555554444444455555544555443322111122333322111122334444444444445555555555556666666665544444433333333333334444555555566777777777777777777777776666666766666666665555556665554445455566777777777665544444444444444444444444444544444444445444444455555555555666666666666667776666666777778888888999:::;;;;;;;;;;;;;;;;;;;;;;<<<<<<<<<<;;::::;;;;<<<=================>=>>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//00//../.....-------,,,,,,,+++++++,,--....../......--,,++******))))(((((((((('''''''''''(())********++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>??????????????????????????????????????????????????????????????????????????????????>>==<<<;;;;;;;;;;<<===>>>>>>>>??>>>>>>???>>==<<<<;;;;;;:::::::::9999999998888888877777777776655556666655444444433333333333333333333333334444444556667777777877777777788888888888887888888888888888889888999999999888899::;;<<==>>???????????>>???????>>>=========<<;;::::::99999999999888888888877777766555555565555666666555555566655565555544332222334455555544444554433333444554444444443322111111223322110011223333444444444444444555555566666665544433333333333222233333444445555667666777766666777766666666655666666655555555555555544444444455666666666665544444444444444444443333444444444444444444444444455555555555555555655656666666666666667788888888999::::::::::::::::::::::;;;;;;;;;;;;::::::::;;<<<<<===================>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000000/////./.....----------,,,++++,,--......///....--,,++**))**))))(((((((('''''&&&&&&&&''(()))*******++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;;;;;;;;;<<<==>>>==>>>>>>>>>>>?>>==<<;;;;;;:::::::::99999999999888888887766666777665555555565544333333333333332222222222222233333444444556666666677777777777777777777777777777778888888888888888888888888888899::;;<<==>>?????>>>>>>>>>>>>>>>======<<<<<<;;::99999999998888888888877777776666655444555555555555555555555555555555444433222222334445544444444443333333344444433444332211000011222211000011223333333333334444444444445555555554433333322222222222223333444444455666666666666666666666665555555655555555554444445554443334344455666666666554433333333333333333333333333433333333334333333344444444444555555555555556665555555666667777777888999::::::::::::::::::::::;;;;;;;;;;::9999::::;;;<<<<<<<<<<<<<<<<<=<=======>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211001100//0/////.......-------,,,,,,,--..//////0//..--,,++**))))))((((''''''''''&&&&&&&&&&&''(())))))))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>??????????????????????????????????????????????????>>>???????????????????????>>>======>>??????????????????????????????????????????????????????????????????????????????>>==<<;;;::::::::::;;<<<========>>======>>>==<<;;;;::::::999999999888888888777777776666666666554444555554433333332222222222222222222222222333333344555666666676666666667777777777777677777777777777777877788888888877778899::;;<<==>>>>>>>>>>>==>>>>>>>===<<<<<<<<<;;::9999998888888888877777777776666665544444445444455555544444445554445444443322111122334444443333344332222233344333333333221100000011221100//001122223333333333333334444444555555544333222222222221111222223333344445565556666555556666555555555445555555444444444444444333333333445555555555544333333333333333333322223333333333333333333333333444444444444444445445455555555555555566777777778889999999999999999999999::::::::::::99999999::;;;;;<<<<<<<<<<<<<<<<<<<=====>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211111100000/0/////..........---,,,,--..//////0//..--,,++**))(())((((''''''''&&&&&%%%%%%%%&&''((()))))))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>???????????????????>>>>>?????????????>>>?????>>??>>>???>>>>?????>>>>>???>>>>>??????>>>>>>>????>>>>>>=========>>??????>>>>>????????????>>>??????????????????????>>>>>?????????????????>>>>>>>>==<<;;:::::::::::::;;;<<===<<===========>==<<;;::::::9999999998888888888877777777665555566655444444445443322222222222222111111111111112222233333344555555556666666666666666666666666666666777777777777777777777777777778899::;;<<==>>>>>===============<<<<<<;;;;;;::9988888888887777777777766666665555544333444444444444444444444444444444333322111111223334433333333332222222233333322333221100////00111100////001122222222222233333333333344444444433222222111111111111122223333333445555555555555555555555544444445444444444433333344433322232333445555555554433222222222222222222222222223222222222232222222333333333334444444444444455544444445555566666667778889999999999999999999999::::::::::9988889999:::;;;;;;;;;;;;;;;;;<;<<<<<<<==>>>>???>?>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211221100100000///////.......-------..//0///0//..--,,++**))((((((''''&&&&&&&&&&%%%%%%%%%%%&&''(((((((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>?????????????>>>>>>?????????????????>>===>>????>>>>>??>>>>>???>>>>>>>>>?>>>>>>???>>>>>>>?>>===>>????>>>>>>>>>>>>>>>>>===<<<<<<==>>????>>>>>>>??????????>>>>>>???????>>>>????????>>>>>>>????????????>>>>>>>>>>>==<<;;:::9999999999::;;;<<<<<<<<==<<<<<<===<<;;::::99999988888888877777777766666666555555555544333344444332222222111111111111111111111111122222223344455555556555555555666666666666656666666666666666676667777777776666778899::;;<<===========<<=======<<<;;;;;;;;;::9988888877777777777666666666655555544333333343333444444333333344433343333322110000112233333322222332211111222332222222221100//////001100//..//00111122222222222222233333334444444332221111111111100001111122222333344544455554444455554444444443344444443333333333333332222222223344444444444332222222222222222222111122222222222222222222222223333333333333333343343444444444444444556666666677788888888888888888888889999999999998888888899:::::;;;;;;;;;;;;;;;;;;;<<<<<==>>>>?>>>>>>>>?>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433222222111110100000//////////...----..//0//////..--,,++**))((''((''''&&&&&&&&%%%%%$$$$$$$$%%&&'''((((((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>???????????>>>===>>???????????????>>=====>>??>>>>>>>>>===>>?>>==>>===>>>====>>>>>=====>>>=====>>??>>=======>>>>======<<<<<<<<<==>>>>>>=====>>????????>>===>>>>????>>>>>>??????>>=====>>????????>>>>>>>========<<;;::9999999999999:::;;<<<;;<<<<<<<<<<<=<<;;::999999888888888777777777776666666655444445554433333333433221111111111111100000000000000111112222223344444444555555555555555555555555555555566666666666666666666666666666778899::;;<<=====<<<<<<<<<<<<<<<;;;;;;::::::9988777777777766666666666555555544444332223333333333333333333333333333332222110000001122233222222222211111111222222112221100//....//0000//....//001111111111112222222222223333333332211111100000000000001111222222233444444444444444444444443333333433333333332222223332221112122233444444444332211111111111111111111111111211111111112111111122222222222333333333333334443333333444445555555666777888888888888888888888899999999998877778888999:::::::::::::::::;:;;;;;;;<<====>>>=>===>>>>>>?>>>>>>>>>????>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433223322112111110000000///////.......//0//.../..--,,++**))((''''''&&&&%%%%%%%%%%$$$$$$$$$$$%%&&''''''''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>====>>?????????>>======>>?????????????>>==<<<==>>>>=====>>=====>>>=========>======>>>=======>==<<<==>>>>=================<<<;;;;;;<<==>>>>=======>>??????>>======>>>??>>====>>????>>=======>>??>>>>>>>>===========<<;;::999888888888899:::;;;;;;;;<<;;;;;;<<<;;::99998888887777777776666666665555555544444444443322223333322111111100000000000000000000000001111111223334444444544444444455555555555554555555555555555556555666666666555566778899::;;<<<<<<<<<<<;;<<<<<<<;;;:::::::::99887777776666666666655555555554444443322222223222233333322222223332223222221100////0011222222111112211000001112211111111100//......//00//..--..//0000111111111111111222222233333332211100000000000////000001111122223343334444333334444333333333223333333222222222222222111111111223333333333322111111111111111111100001111111111111111111111111222222222222222223223233333333333333344555555556667777777777777777777777888888888888777777778899999:::::::::::::::::::;;;;;<<====>========>==>>>>>>>>>>>>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443333332222212111110000000000///....//0//......--,,++**))((''&&''&&&&%%%%%%%%$$$$$########$$%%&&&'''''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>======>>???????>>===<<<==>>???????????>>==<<<<<==>>=========<<<==>==<<==<<<===<<<<=====<<<<<===<<<<<==>>==<<<<<<<====<<<<<<;;;;;;;;;<<======<<<<<==>>????>>==<<<====>>>>======>>??>>==<<<<<==>>>>>>>>=======<<<<<<<<;;::998888888888888999::;;;::;;;;;;;;;;;<;;::998888887777777776666666666655555555443333344433222222223221100000000000000//////////////00000111111223333333344444444444444444444444444444445555555555555555555555555555566778899::;;<<<<<;;;;;;;;;;;;;;;::::::999999887766666666665555555555544444443333322111222222222222222222222222222222111100//////00111221111111111000000001111110011100//..----..////..----..//00000000000011111111111122222222211000000/////////////000011111112233333333333333333333333222222232222222222111111222111000101112233333333322110000000000000000000000000010000000000100000001111111111122222222222222333222222233333444444455566677777777777777777777778888888888776666777788899999999999999999:9:::::::;;<<<<===<=<<<======>=========>>>>==>>>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443344332232222211111110000000//////////..---.--,,++**))((''&&&&&&%%%%$$$$$$$$$$###########$$%%&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>?????????>>>>>>>==<<<<==>>?????>>==<<<<<<==>>?????????>>==<<;;;<<====<<<<<==<<<<<===<<<<<<<<<=<<<<<<===<<<<<<<=<<;;;<<====<<<<<<<<<<<<<<<<<;;;::::::;;<<====<<<<<<<==>>>>>>==<<<<<<===>>==<<<<==>>>>==<<<<<<<==>>========<<<<<<<<<<<;;::99888777777777788999::::::::;;::::::;;;::99888877777766666666655555555544444444333333333322111122222110000000/////////////////////////000000011222333333343333333334444444444444344444444444444444544455555555544445566778899::;;;;;;;;;;;::;;;;;;;:::999999999887766666655555555555444444444433333322111111121111222222111111122211121111100//....//00111111000001100/////00011000000000//..------..//..--,,--..////0000000000000001111111222222211000///////////..../////00000111122322233332222233332222222221122222221111111111111110000000001122222222222110000000000000000000////00000000000000000000000001111111111111111121121222222222222222334444444455566666666666666666666667777777777776666666677888889999999999999999999:::::;;<<<<=<<<<<<<<=<<===================>>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::::99887766554444443333323222221111111111000///////..------,,++**))((''&&%%&&%%%%$$$$$$$$#####""""""""##$$%%%&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>?????>>>>>>>>>>???>>=======<<<<<<==>>???>>==<<<;;;<<==>>?>>????>>==<<;;;;;<<==<<<<<<<<<;;;<<=<<;;<<;;;<<<;;;;<<<<<;;;;;<<<;;;;;<<==<<;;;;;;;<<<<;;;;;;:::::::::;;<<<<<<;;;;;<<==>>>>==<<;;;<<<<====<<<<<<==>>==<<;;;;;<<========<<<<<<<;;;;;;;;::9988777777777777788899:::99:::::::::::;::998877777766666666655555555555444444443322222333221111111121100//////////////............../////00000011222222223333333333333333333333333333333444444444444444444444444444445566778899::;;;;;:::::::::::::::9999998888887766555555555544444444444333333322222110001111111111111111111111111111110000//......//000110000000000////////000000//000//..--,,,,--....--,,,,--..////////////00000000000011111111100//////.............////00000001122222222222222222222222111111121111111111000000111000///0/000112222222221100//////////////////////////0//////////0///////0000000000011111111111111222111111122222333333344455566666666666666666666667777777777665555666677788888888888888888989999999::;;;;<<<;<;;;<<<<<<=<<<<<<<<<====<<========>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::9998877665544554433433333222222211111100000///...--,,,-,,++**))((''&&%%%%%%$$$$##########"""""""""""##$$%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>??>>====>>>>>>?>>=======<<;;;;<<==>>>>>==<<;;;;;;<<==>>>>>>?>>==<<;;:::;;<<<<;;;;;<<;;;;;<<<;;;;;;;;;<;;;;;;<<<;;;;;;;<;;:::;;<<<<;;;;;;;;;;;;;;;;;:::999999::;;<<<<;;;;;;;<<======<<;;;;;;<<<==<<;;;;<<====<<;;;;;;;<<==<<<<<<<<;;;;;;;;;;;::998877766666666667788899999999::999999:::998877776666665555555554444444443333333322222222221100001111100///////.........................///////0011122222223222222222333333333333323333333333333333343334444444443333445566778899:::::::::::99:::::::9998888888887766555555444444444443333333333222222110000000100001111110000000111000100000//..----..//000000/////00//.....///00/////////..--,,,,,,--..--,,++,,--....///////////////0000000111111100///...........----...../////00001121112222111112222111111111001111111000000000000000/////////001111111111100///////////////////..../////////////////////////000000000000000001001011111111111111122333333334445555555555555555555555666666666666555555556677777888888888888888888899999::;;;;<;;;;;;;;<;;<<<<<<<<<<<<<<<<<<<=======>>>>>>>???>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99999999887766555555444443433333222222111000////....--,,,,,,++**))((''&&%%$$%%$$$$########"""""!!!!!!!!""##$$$%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>===>>>>>==========>>>==<<<<<<<;;;;;;<<==>>>==<<;;;:::;;<<==>==>>>>==<<;;:::::;;<<;;;;;;;;;:::;;<;;::;;:::;;;::::;;;;;:::::;;;:::::;;<<;;:::::::;;;;::::::999999999::;;;;;;:::::;;<<====<<;;:::;;;;<<<<;;;;;;<<==<<;;:::::;;<<<<<<<<;;;;;;;::::::::9988776666666666666777889998899999999999:998877666666555555555444444444443333333322111112221100000000100//..............--------------.....//////0011111111222222222222222222222222222222233333333333333333333333333333445566778899:::::999999999999999888888777777665544444444443333333333322222221111100///000000000000000000000000000000////..------..///00//////////........//////..///..--,,++++,,----,,++++,,--............////////////000000000//......-------------....///////0011111111111111111111111000000010000000000//////000///..././//0011111111100//........................../........../.......///////////0000000000000011100000001111122222223334445555555555555555555555666666666655444455556667777777777777777787888888899::::;;;:;:::;;;;;;<;;;;;;;;;<<<<;;<<<<<<<<=====>>>>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9999988899887766556655445444443333332211000/////...---,,+++,++**))((''&&%%$$$$$$####""""""""""!!!!!!!!!!!""##$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=======>>==<<<<======>==<<<<<<<;;::::;;<<=====<<;;::::::;;<<======>==<<;;::999::;;;;:::::;;:::::;;;:::::::::;::::::;;;:::::::;::999::;;;;:::::::::::::::::99988888899::;;;;:::::::;;<<<<<<;;::::::;;;<<;;::::;;<<<<;;:::::::;;<<;;;;;;;;:::::::::::99887766655555555556677788888888998888889998877666655555544444444433333333322222222111111111100////00000//.......-------------------------.......//0001111111211111111122222222222221222222222222222223222333333333222233445566778899999999999889999999888777777777665544444433333333333222222222211111100///////0////000000///////000///0/////..--,,,,--..//////.....//..-----...//.........--,,++++++,,--,,++**++,,----...............///////0000000//...-----------,,,,-----.....////0010001111000001111000000000//0000000///////////////.........//00000000000//...................----........................./////////////////0//0/0000000000000001122222222333444444444444444444444455555555555544444444556666677777777777777777778888899::::;::::::::;::;;;;;;;;;;;;;;;;;;;<<<<<<<=======>>>==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>?????>>>>>>>????>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988888888998877666666555554544444332211000///....----,,++++++**))((''&&%%$$##$$####""""""""!!!!!````````!!""###$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===<<<=====<<<<<<<<<<===<<;;;;;;;::::::;;<<===<<;;:::999::;;<<=<<====<<;;::99999::;;:::::::::999::;::99::999:::9999:::::99999:::99999::;;::9999999::::99999988888888899::::::99999::;;<<<<;;::999::::;;;;::::::;;<<;;::99999::;;;;;;;;:::::::99999999887766555555555555566677888778888888888898877665555554444444443333333333322222222110000011100////////0//..--------------,,,,,,,,,,,,,,-----......//00000000111111111111111111111111111111122222222222222222222222222222334455667788999998888888888888887777776666665544333333333322222222222111111100000//...//////////////////////////////....--,,,,,,--...//..........--------......--...--,,++****++,,,,++****++,,------------............/////////..------,,,,,,,,,,,,,----.......//00000000000000000000000///////0//////////......///...---.-...//000000000//..--------------------------.----------.-------...........//////////////000///////00000111111122233344444444444444444444445555555555443333444455566666666666666666767777777889999:::9:999::::::;:::::::::;;;;::;;;;;;;;<<<<<=========>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998888877788998877666666555555554433221100///.....---,,,++***+**))((''&&%%$$######""""!!!!!!!!!!```!!""########$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<<==<<;;;;<<<<<<=<<;;;;;;;::9999::;;<<<<<;;::999999::;;<<<<<<=<<;;::9988899::::99999::99999:::999999999:999999:::9999999:9988899::::999999999999999998887777778899::::9999999::;;;;;;::999999:::;;::9999::;;;;::9999999::;;::::::::99999999999887766555444444444455666777777778877777788877665555444444333333333222222222111111110000000000//..../////..-------,,,,,,,,,,,,,,,,,,,,,,,,,-------..///00000001000000000111111111111101111111111111111121112222222221111223344556677888888888887788888887776666666665544333333222222222221111111111000000//......./....//////.......///.../.....--,,++++,,--......-----..--,,,,,---..---------,,++******++,,++**))**++,,,,---------------.......///////..---,,,,,,,,,,,++++,,,,,-----....//0///0000/////0000/////////..///////...............---------..///////////..-------------------,,,,-------------------------................./.././//////////////00111111112223333333333333333333333444444444444333333334455555666666666666666666677777889999:99999999:99:::::::::::::::::::;;;;;;;<<<<<<<===<<==>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>===>>>>>=======>>>>======>>>>??????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877777777889887766666555444444433221100///...----,,,,++******))((''&&%%$$##""##""""!!!!!!!!````!!""""#######$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<;;;<<<<<;;;;;;;;;;<<<;;:::::::999999::;;<<<;;::99988899::;;<;;<<<<;;::998888899::99999999988899:998899888999888899999888889998888899::9988888889999888888777777777889999998888899::;;;;::998889999::::999999::;;::998888899::::::::99999998888888877665544444444444445556677766777777777778776655444444333333333222222222221111111100/////000//......../..--,,,,,,,,,,,,,,++++++++++++++,,,,,------..////////0000000000000000000000000000000111111111111111111111111111112233445566778888877777777777777766666655555544332222222222111111111110000000/////..---..............................----,,++++++,,---..----------,,,,,,,,------,,---,,++**))))**++++**))))**++,,,,,,,,,,,,------------.........--,,,,,,+++++++++++++,,,,-------..///////////////////////......./..........------...---,,,-,---../////////..--,,,,,,,,,,,,,,,,,,,,,,,,,,-,,,,,,,,,,-,,,,,,,-----------..............///......./////00000001112223333333333333333333333444444444433222233334445555555555555555565666666677888899989888999999:999999999::::99::::::::;;;;;<<<<<<<<<===>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>====================================>>>>????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877777666778887766555554444444433221100//...-----,,,+++**)))*))((''&&%%$$##""""""!!!!```````````!!"""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;;;<<;;::::;;;;;;<;;:::::::99888899::;;;;;::9988888899::;;;;;;<;;::9988777889999888889988888999888888888988888899988888889887778899998888888888888888877766666677889999888888899::::::99888888999::99888899::::99888888899::999999998888888888877665544433333333334455566666666776666667776655444433333322222222211111111100000000//////////..----.....--,,,,,,,+++++++++++++++++++++++++,,,,,,,--...///////0/////////0000000000000/0000000000000000010001111111110000112233445566777777777776677777776665555555554433222222111111111110000000000//////..-------.----......-------...---.-----,,++****++,,------,,,,,--,,+++++,,,--,,,,,,,,,++**))))))**++**))(())**++++,,,,,,,,,,,,,,,-------.......--,,,+++++++++++****+++++,,,,,----../...////.....////.........--.......---------------,,,,,,,,,--...........--,,,,,,,,,,,,,,,,,,,++++,,,,,,,,,,,,,,,,,,,,,,,,,-----------------.--.-...............//0000000011122222222222222222222223333333333332222222233444445555555555555555555666667788889888888889889999999999999999999:::::::;;;;;;;<<<;;<<===>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===========<<<=====<<<<<<<====<<<<<<====>>>>>>?????>>????????>>>>???????????????????????????????????????????????????????????????????>>==<<;;::998877666666667787766555554443333333221100//...---,,,,++++**))))))((''&&%%$$##""!!""!!!!`````!!!!""""!!"""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>?????????????>>==<<;;;:::;;;;;::::::::::;;;::999999988888899::;;;::998887778899::;::;;;;::998877777889988888888877788988778877788877778888877777888777778899887777777888877777766666666677888888777778899::::99887778888999988888899::9988777778899999999888888877777777665544333333333333344455666556666666666676655443333332222222221111111111100000000//.....///..--------.--,,++++++++++++++**************+++++,,,,,,--........///////////////////////////////00000000000000000000000000000112233445566777776666666666666665555554444443322111111111100000000000///////.....--,,,------------------------------,,,,++******++,,,--,,,,,,,,,,++++++++,,,,,,++,,,++**))(((())****))(((())**++++++++++++,,,,,,,,,,,,---------,,++++++*************++++,,,,,,,--.......................-------.----------,,,,,,---,,,+++,+,,,--.........--,,++++++++++++++++++++++++++,++++++++++,+++++++,,,,,,,,,,,--------------...-------.....///////0001112222222222222222222222333333333322111122223334444444444444444454555555566777788878777888888988888888899998899999999:::::;;;;;;;;;<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<====>>>>>>???>>>>??????>>>>>>??????>>>>>>?>???????????????????????????????????????????????????>>==<<;;::998877666665556677766554444433333333221100//..---,,,,,+++***))((()((''&&%%$$##""!!!!!!``````!!!!!!!!!""!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>???????????>>==<<;;:::::::;;::9999::::::;::99999998877778899:::::99887777778899::::::;::998877666778888777778877777888777777777877777788877777778776667788887777777777777777766655555566778888777777788999999887777778889988777788999988777777788998888888877777777777665544333222222222233444555555556655555566655443333222222111111111000000000////////..........--,,,,-----,,+++++++*************************+++++++,,---......./........./////////////./////////////////0///000000000////00112233445566666666666556666666555444444444332211111100000000000//////////......--,,,,,,,-,,,,------,,,,,,,---,,,-,,,,,++**))))**++,,,,,,+++++,,++*****+++,,+++++++++**))(((((())**))((''(())****+++++++++++++++,,,,,,,-------,,+++***********))))*****+++++,,,,--.---....-----....---------,,-------,,,,,,,,,,,,,,,+++++++++,,-----------,,+++++++++++++++++++****+++++++++++++++++++++++++,,,,,,,,,,,,,,,,,-,,-,---------------..////////000111111111111111111111122222222222211111111223333344444444444444444445555566777787777777787788888888888888888889999999:::::::;;;::;;<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>==<<<<<<<<<<<;;;<<<<<;;;;;;;<<<<;;;;;;<<<<======>>>>>==>>????>>====>>????>>>>>>>>>>?????????????????????????????????????????????????>>==<<;;::998877665555555566766554444433322222221100//..---,,,++++****))((((((''&&%%$$##""!!``!!````!!!!!!!!!!!!!!!``!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===>>???????>>>>==<<;;:::999:::::9999999999:::9988888887777778899:::9988777666778899:99::::998877666667788777777777666778776677666777666677777666667776666677887766666667777666666555555555667777776666677889999887766677778888777777889988776666677888888887777777666666665544332222222222222333445554455555555555655443322222211111111100000000000////////..-----...--,,,,,,,,-,,++**************))))))))))))))*****++++++,,--------.............................../////////////////////////////0011223344556666655555555555555544444433333322110000000000///////////.......-----,,+++,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++**))))))**+++,,++++++++++********++++++**+++**))((''''(())))((''''(())************++++++++++++,,,,,,,,,++******)))))))))))))****+++++++,,-----------------------,,,,,,,-,,,,,,,,,,++++++,,,+++***+*+++,,---------,,++**************************+**********+*******+++++++++++,,,,,,,,,,,,,,---,,,,,,,-----.......///000111111111111111111111122222222221100001111222333333333333333334344444445566667776766677777787777777778888778888888899999:::::::::;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>??????>>>>==<<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<<<<======>>>====>>??>>======>>>>>>======>=>>???????????????????????????????????????>>>>>???>>==<<;;::998877665555544455666554433333222222221100//..--,,,+++++***)))(('''(''&&%%$$##""!!``!!``````!!!!!!!!!!!!```!!```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=====>>?????>>>>==<<;;::9999999::998888999999:99888888877666677889999988776666667788999999:99887766555667777666667766666777666666666766666677766666667665556677776666666666666666655544444455667777666666677888888776666667778877666677888877666666677887777777766666666666554433222111111111122333444444445544444455544332222111111000000000/////////........----------,,++++,,,,,++*******)))))))))))))))))))))))))*******++,,,-------.---------.............-................./.../////////....//0011223344555555555554455555554443333333332211000000///////////..........------,,+++++++,++++,,,,,,+++++++,,,+++,+++++**))(((())**++++++*****++**)))))***++*********))((''''''(())((''&&''(())))***************+++++++,,,,,,,++***)))))))))))(((()))))*****++++,,-,,,----,,,,,----,,,,,,,,,++,,,,,,,+++++++++++++++*********++,,,,,,,,,,,++*******************))))*************************+++++++++++++++++,++,+,,,,,,,,,,,,,,,--........///0000000000000000000000111111111111000000001122222333333333333333333344444556666766666666766777777777777777777788888889999999:::99::;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>???>>====<<;;;;;;;;;;;:::;;;;;:::::::;;;;::::::;;;;<<<<<<=====<<==>>>>==<<<<==>>>>==========>>>>????>>>>>????????????????????????>>>>>>>>>>>>==<<;;::998877665544444444556554433333222111111100//..--,,,+++****))))((''''''&&%%$$##""!!``!!``!```!!!!!!!!!!```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<==>>>>>>>====<<;;::9998889999988888888889998877777776666667788999887766655566778898899998877665555566776666666665556676655665556665555666665555566655555667766555555566665555554444444445566666655555667788887766555666677776666667788776655555667777777766666665555555544332211111111111112223344433444444444445443322111111000000000///////////........--,,,,,---,,++++++++,++**))))))))))))))(((((((((((((()))))******++,,,,,,,,-------------------------------.............................//0011223344555554444444444444443333332222221100//////////...........-------,,,,,++***++++++++++++++++++++++++++++++****))(((((())***++**********))))))))******))***))((''&&&&''((((''&&&&''(())))))))))))************+++++++++**))))))((((((((((((())))*******++,,,,,,,,,,,,,,,,,,,,,,,+++++++,++++++++++******+++***)))*)***++,,,,,,,,,++**))))))))))))))))))))))))))*))))))))))*)))))))***********++++++++++++++,,,+++++++,,,,,-------...///0000000000000000000000111111111100////0000111222222222222222223233333334455556665655566666676666666667777667777777788888999999999:::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==>>>?>>====<<;;::::::::::::::::::::::::::::::::::::;;;;<<<<<<===<<<<==>>==<<<<<<======<<<<<<=<==>>>>>>>>>>>>>>?????????????????????>>>>=====>>>==<<;;::998877665544444333445554433222221111111100//..--,,+++*****)))(((''&&&'&&%%$$####""!!```!!!!!``!!!`!!!!````ǀ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<==>>>>>====<<;;::99888888899887777888888988777777766555566778888877665555556677888888988776655444556666555556655555666555555555655555566655555556554445566665555555555555555544433333344556666555555566777777665555556667766555566777766555555566776666666655555555555443322111000000000011222333333334433333344433221111000000/////////.........--------,,,,,,,,,,++****+++++**)))))))((((((((((((((((((((((((()))))))**+++,,,,,,,-,,,,,,,,,-------------,-----------------.---.........----..//00112233444444444443344444443332222222221100//////...........----------,,,,,,++*******+****++++++*******+++***+*****))((''''(())******)))))**))((((()))**)))))))))((''&&&&&&''((''&&%%&&''(((()))))))))))))))*******+++++++**)))(((((((((((''''((((()))))****++,+++,,,,+++++,,,,+++++++++**+++++++***************)))))))))**+++++++++++**)))))))))))))))))))(((()))))))))))))))))))))))))*****************+**+*+++++++++++++++,,--------...//////////////////////000000000000////////00111112222222222222222222333334455556555555556556666666666666666666777777788888889998899:::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=====>>>==<<<<;;:::::::::::999:::::9999999::::999999::::;;;;;;<<<<<;;<<====<<;;;;<<====<<<<<<<<<<====>>>>=====>>>>>>??>?????????????>>============<<;;::998877665544333333334454433222221110000000//..--,,+++***))))((((''&&&&&&%%$$####""""!!!``!!!```!!``!``˅`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;<<=======<<<<;;::998887778888877777777778887766666665555556677888776655544455667787788887766554444455665555555554445565544554445554444555554444455544444556655444444455554444443333333334455555544444556677776655444555566665555556677665544444556666666655555554444444433221100000000000001112233322333333333334332211000000/////////...........--------,,+++++,,,++********+**))((((((((((((((''''''''''''''((((())))))**++++++++,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----------------------------..//001122334444433333333333333322222211111100//..........-----------,,,,,,,+++++**)))******************************))))((''''''(()))**))))))))))(((((((())))))(()))((''&&%%%%&&''''&&%%%%&&''(((((((((((())))))))))))*********))(((((('''''''''''''(((()))))))**+++++++++++++++++++++++*******+**********))))))***)))((()()))**+++++++++**))(((((((((((((((((((((((((()(((((((((()((((((()))))))))))**************+++*******+++++,,,,,,,---...//////////////////////0000000000//....////000111111111111111112122222223344445554544455555565555555556666556666666677777888888888999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==========>>>???????????>>>>>>??????????????????????????????????????????????????????????????????????????????????????????>>==<<===>==<<<<;;::999999999999999999999999999999999999::::;;;;;;<<<;;;;<<==<<;;;;;;<<<<<<;;;;;;<;<<==============>>>>>>>>>>>????????>>====<<<<<===<<;;::998877665544333332223344433221111100000000//..--,,++***)))))((('''&&%%%&%%$$##""""!"""!!!````!!``!```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>??????????????>>==<<;;;;;<<=====<<<<;;::9988777777788776666777777877666666655444455667777766554444445566777777877665544333445555444445544444555444444444544444455544444445443334455554444444444444444433322222233445555444444455666666554444445556655444455666655444444455665555555544444444444332211000//////////00111222222223322222233322110000//////.........---------,,,,,,,,++++++++++**))))*****))((((((('''''''''''''''''''''''''((((((())***+++++++,+++++++++,,,,,,,,,,,,,+,,,,,,,,,,,,,,,,,-,,,---------,,,,--..//0011223333333333322333333322211111111100//......-----------,,,,,,,,,,++++++**)))))))*))))******)))))))***)))*)))))((''&&&&''(())))))((((())(('''''((())(((((((((''&&%%%%%%&&''&&%%$$%%&&''''((((((((((((((()))))))*******))((('''''''''''&&&&'''''((((())))**+***++++*****++++*********))*******)))))))))))))))((((((((())***********))(((((((((((((((((((''''((((((((((((((((((((((((()))))))))))))))))*))*)***************++,,,,,,,,---......................////////////........//000001111111111111111111222223344445444444445445555555555555555555666666677777778887788999::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=============>>>>>>>????>>>>>>>>>>>>>>>>>??>>>>>>>??????????????????????????????????????????????????????????????????????>>==<<<<<===<<;;;;::9999999999988899999888888899998888889999::::::;;;;;::;;<<<<;;::::;;<<<<;;;;;;;;;;<<<<====<<<<<======>>=>>>>>>>>>??>>==<<<<<<<<<<<<;;::9988776655443322222222334332211111000///////..--,,++***)))((((''''&&%%%%%%$$##""""!!!""!!!!``!```````!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>????????????>>==<<;;:::;;<<<<<<<;;;;::998877766677777666666666677766555555544444455667776655444333445566766777766554433333445544444444433344544334433344433334444433333444333334455443333333444433333322222222233444444333334455666655443334444555544444455665544333334455555555444444433333333221100/////////////0001122211222222222223221100//////.........-----------,,,,,,,,++*****+++**))))))))*))((''''''''''''''&&&&&&&&&&&&&&'''''(((((())********+++++++++++++++++++++++++++++++,,,,,,,,,,,,,,,,,,,,,,,,,,,,,--..//00112233333222222222222222111111000000//..----------,,,,,,,,,,,+++++++*****))((())))))))))))))))))))))))))))))((((''&&&&&&''((())((((((((((''''''''((((((''(((''&&%%$$$$%%&&&&%%$$$$%%&&''''''''''''(((((((((((()))))))))((''''''&&&&&&&&&&&&&''''((((((())***********************)))))))*))))))))))(((((()))((('''('((())*********))((''''''''''''''''''''''''''(''''''''''('''''''((((((((((())))))))))))))***)))))))*****+++++++,,,---......................//////////..----....///00000000000000000101111111223333444343334444445444444444555544555555556666677777777788899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<<<<<===>>>>>>>??>>======>>>>>>>>>>>>>>>>>>>>????????>>>>>???????>>>>>>??????????????????????????????????????????>>==<<;;<<<=<<;;;;::998888888888888888888888888888888888889999::::::;;;::::;;<<;;::::::;;;;;;::::::;:;;<<<<<<<<<<<<<<===========>>>>>>>>==<<<<;;;;;<<<;;::998877665544332222211122333221100000////////..--,,++**)))((((('''&&&%%$$$%$$##""!!!!`!!!!````!`Òۑ````!``!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===>>??????????>>==<<;;:::::;;<<<<<;;;;::998877666666677665555666666766555555544333344556666655443333334455666666766554433222334444333334433333444333333333433333344433333334332223344443333333333333333322211111122334444333333344555555443333334445544333344555544333333344554444444433333333333221100///..........//00011111111221111112221100////......---------,,,,,,,,,++++++++**********))(((()))))(('''''''&&&&&&&&&&&&&&&&&&&&&&&&&'''''''(()))*******+*********+++++++++++++*+++++++++++++++++,+++,,,,,,,,,++++,,--..//001122222222222112222222111000000000//..------,,,,,,,,,,,++++++++++******))((((((()(((())))))((((((()))((()(((((''&&%%%%&&''(((((('''''((''&&&&&'''(('''''''''&&%%$$$$$$%%&&%%$$##$$%%&&&&'''''''''''''''((((((()))))))(('''&&&&&&&&&&&%%%%&&&&&'''''(((())*)))****)))))****)))))))))(()))))))((((((((((((((('''''''''(()))))))))))(('''''''''''''''''''&&&&'''''''''''''''''''''''''((((((((((((((((()(()()))))))))))))))**++++++++,,,----------------------............--------../////000000000000000000011111223333433333333433444444444444444444455555556666666777667788899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>?????????????????????>>==<<<<<<<<<<<<<=======>>>>=================>>=======>>?????>>>>>>>>????>>>>>>>>>>>????????>>>>>?>???????????????????????>>==<<;;;;;<<<;;::::998888888888877788888777777788887777778888999999:::::99::;;;;::9999::;;;;::::::::::;;;;<<<<;;;;;<<<<<<==<=========>>==<<;;;;;;;;;;;;::998877665544332211111111223221100000///.......--,,++**)))(((''''&&&&%%$$$$$$##""!!!!``!!```````!!!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>=====>>????????>>==<<;;::999::;;;;;;;::::998877666555666665555555555666554444444333333445566655443332223344556556666554433222223344333333333222334332233222333222233333222223332222233443322222223333222222111111111223333332222233445555443322233334444333333445544332222233444444443333333222222221100//.............///00111001111111111121100//......---------,,,,,,,,,,,++++++++**)))))***))(((((((()((''&&&&&&&&&&&&&&%%%%%%%%%%%%%%&&&&&''''''(())))))))*******************************+++++++++++++++++++++++++++++,,--..//001122222111111111111111000000//////..--,,,,,,,,,,+++++++++++*******)))))(('''((((((((((((((((((((((((((((((''''&&%%%%%%&&'''((''''''''''&&&&&&&&''''''&&'''&&%%$$####$$%%%%$$####$$%%&&&&&&&&&&&&''''''''''''(((((((((''&&&&&&%%%%%%%%%%%%%&&&&'''''''(()))))))))))))))))))))))((((((()((((((((((''''''((('''&&&'&'''(()))))))))((''&&&&&&&&&&&&&&&&&&&&&&&&&&'&&&&&&&&&&'&&&&&&&'''''''''''(((((((((((((()))((((((()))))*******+++,,,----------------------..........--,,,,----.../////////////////0/000000011222233323222333333433333333344443344444444555556666666667778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>???????????????>>==<<;;;;;;;;;;<<<=======>>==<<<<<<====================>>>>?>>>=====>>??>>>======>>>>??????>>>>>>>>>>????????????????????>>==<<;;::;;;<;;::::99887777777777777777777777777777777777778888999999:::9999::;;::999999::::::999999:9::;;;;;;;;;;;;;;<<<<<<<<<<<========<<;;;;:::::;;;::998877665544332211111000112221100/////........--,,++**))((('''''&&&%%%$$###$##""!!`````Ŋ@`!!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>==<<<==>>??????>>==<<;;::99999::;;;;;::::998877665555555665544445555556554444444332222334455555443322222233445555556554433221112233332222233222223332222222223222222333222222232211122333322222222222222222111000000112233332222222334444443322222233344332222334444332222222334433333333222222222221100//...----------..///000000001100000011100//....------,,,,,,,,,+++++++++********))))))))))((''''(((((''&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&''((()))))))*)))))))))*************)*****************+***+++++++++****++,,--..//0011111111111001111111000/////////..--,,,,,,+++++++++++**********))))))(('''''''(''''(((((('''''''((('''('''''&&%%$$$$%%&&''''''&&&&&''&&%%%%%&&&''&&&&&&&&&%%$$######$$%%$$##""##$$%%%%&&&&&&&&&&&&&&&'''''''(((((((''&&&%%%%%%%%%%%$$$$%%%%%&&&&&''''(()((())))((((())))(((((((((''((((((('''''''''''''''&&&&&&&&&''(((((((((((''&&&&&&&&&&&&&&&&&&&%%%%&&&&&&&&&&&&&&&&&&&&&&&&&'''''''''''''''''(''('((((((((((((((())********+++,,,,,,,,,,,,,,,,,,,,,,------------,,,,,,,,--.....///////////////////0000011222232222222232233333333333333333334444444555555566655667778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>=>>>>>>>????????????>>==<<;;;;;;;;;;;;;<<<<<<<====<<<<<<<<<<<<<<<<<==<<<<<<<==>>>>>========>>>>===========>>????>>=====>=>>>??????????????????>>==<<;;:::::;;;::9999887777777777766677777666666677776666667777888888999998899::::99888899::::9999999999::::;;;;:::::;;;;;;<<;<<<<<<<<<==<<;;::::::::::::998877665544332211000000001121100/////...-------,,++**))((('''&&&&%%%%$$######""!!`Ą`!!""#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>======<<<<<==>>????>>==<<;;::9988899:::::::99998877665554445555544444444445554433333332222223344555443322211122334454455554433221111122332222222221112232211221112221111222221111122211111223322111111122221111110000000001122222211111223344443322111222233332222223344332211111223333333322222221111111100//..-------------...//000//00000000000100//..------,,,,,,,,,+++++++++++********))((((()))((''''''''(''&&%%%%%%%%%%%%%%$$$$$$$$$$$$$$%%%%%&&&&&&''(((((((()))))))))))))))))))))))))))))))*****************************++,,--..//0011111000000000000000//////......--,,++++++++++***********)))))))(((((''&&&''''''''''''''''''''''''''''''&&&&%%$$$$$$%%&&&''&&&&&&&&&&%%%%%%%%&&&&&&%%&&&%%$$##""""##$$$$##""""##$$%%%%%%%%%%%%&&&&&&&&&&&&'''''''''&&%%%%%%$$$$$$$$$$$$$%%%%&&&&&&&''((((((((((((((((((((((('''''''(''''''''''&&&&&&'''&&&%%%&%&&&''(((((((((''&&%%%%%%%%%%%%%%%%%%%%%%%%%%&%%%%%%%%%%&%%%%%%%&&&&&&&&&&&''''''''''''''((('''''''((((()))))))***+++,,,,,,,,,,,,,,,,,,,,,,----------,,++++,,,,---................././//////0011112221211122222232222222223333223333333344444555555555666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>???????>>========>>>??????????>>==<<;;::::::::::;;;<<<<<<<==<<;;;;;;<<<<<<<<<<<<<<<<<<<<====>===<<<<<==>>===<<<<<<====>>??>>==========>>????????????????>>==<<;;::99:::;::999988776666666666666666666666666666666666667777888888999888899::998888889999998888889899::::::::::::::;;;;;;;;;;;<<<<<<<<;;::::99999:::99887766554433221100000///0011100//.....--------,,++**))(('''&&&&&%%%$$$##"""##""!!`@`````!!""#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>======<<;;;<<==>>??>>==<<;;::998888899:::::9999887766554444444554433334444445443333333221111223344444332211111122334444445443322110001122221111122111112221111111112111111222111111121100011222211111111111111111000//////0011222211111112233333322111111222332211112233332211111112233222222221111111111100//..---,,,,,,,,,,--...////////00//////000//..----,,,,,,+++++++++*********))))))))((((((((((''&&&&'''''&&%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%&&'''((((((()((((((((()))))))))))))()))))))))))))))))*)))*********))))**++,,--..//00000000000//0000000///.........--,,++++++***********))))))))))((((((''&&&&&&&'&&&&''''''&&&&&&&'''&&&'&&&&&%%$$####$$%%&&&&&&%%%%%&&%%$$$$$%%%&&%%%%%%%%%$$##""""""##$$##""!!""##$$$$%%%%%%%%%%%%%%%&&&&&&&'''''''&&%%%$$$$$$$$$$$####$$$$$%%%%%&&&&''('''(((('''''(((('''''''''&&'''''''&&&&&&&&&&&&&&&%%%%%%%%%&&'''''''''''&&%%%%%%%%%%%%%%%%%%%$$$$%%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&'&&'&'''''''''''''''(())))))))***++++++++++++++++++++++,,,,,,,,,,,,++++++++,,-----.................../////0011112111111112112222222222222222222333333344444445554455666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>?????>>===<=======>>????????>>==<<;;:::::::::::::;;;;;;;<<<<;;;;;;;;;;;;;;;;;<<;;;;;;;<<=====<<<<<<<<====<<<<<<<<<<<==>>>>==<<<<<=<===>>??????????????>>==<<;;::99999:::998888776666666666655566666555555566665555556666777777888887788999988777788999988888888889999::::99999::::::;;:;;;;;;;;;<<;;::999999999999887766554433221100////////00100//.....---,,,,,,,++**))(('''&&&%%%%$$$$##"""""""!!`Œ``````!!!!````!!""##$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<;;;;;<<==>>>>==<<;;::99887778899999998888776655444333444443333333333444332222222111111223344433221110001122334334444332211000001122111111111000112110011000111000011111000001110000011221100000001111000000/////////00111111000001122333322110001111222211111122332211000001122222222111111100000000//..--,,,,,,,,,,,,,---..///..///////////0//..--,,,,,,+++++++++***********))))))))(('''''(((''&&&&&&&&'&&%%$$$$$$$$$$$$$$##############$$$$$%%%%%%&&''''''''((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))**++,,--..//00000///////////////......------,,++**********)))))))))))((((((('''''&&%%%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%$$######$$%%%&&%%%%%%%%%%$$$$$$$$%%%%%%$$%%%$$##""!!!!""####""!!!!""##$$$$$$$$$$$$%%%%%%%%%%%%&&&&&&&&&%%$$$$$$#############$$$$%%%%%%%&&'''''''''''''''''''''''&&&&&&&'&&&&&&&&&&%%%%%%&&&%%%$$$%$%%%&&'''''''''&&%%$$$$$$$$$$$$$$$$$$$$$$$$$$%$$$$$$$$$$%$$$$$$$%%%%%%%%%%%&&&&&&&&&&&&&&'''&&&&&&&'''''((((((()))***++++++++++++++++++++++,,,,,,,,,,++****++++,,,-----------------.-.......//0000111010001111112111111111222211222222223333344444444455566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>========>>>>>>>==<<<<<<<<===>>>>>>>>>>==<<;;::9999999999:::;;;;;;;<<;;::::::;;;;;;;;;;;;;;;;;;;;<<<<=<<<;;;;;<<==<<<;;;;;;<<<<==>>==<<<<<<<<<<==>>????????????>>==<<;;::9988999:998888776655555555555555555555555555555555555566667777778887777889988777777888888777777878899999999999999:::::::::::;;;;;;;;::999988888999887766554433221100/////...//000//..-----,,,,,,,,++**))((''&&&%%%%%$$$###""!!!"""!!```!!```!!``!!!!!!``!!!!""##$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<;;:::;;<<==>>==<<;;::9988777778899999888877665544333333344332222333333433222222211000011223333322110000001122333333433221100///00111100000110000011100000000010000001110000000100///00111100000000000000000///......//001111000000011222222110000001112211000011222211000000011221111111100000000000//..--,,,++++++++++,,---........//......///..--,,,,++++++*********)))))))))((((((((''''''''''&&%%%%&&&&&%%$$$$$$$#########################$$$$$$$%%&&&'''''''('''''''''((((((((((((('((((((((((((((((()((()))))))))(((())**++,,--..///////////..///////...---------,,++******)))))))))))((((((((((''''''&&%%%%%%%&%%%%&&&&&&%%%%%%%&&&%%%&%%%%%$$##""""##$$%%%%%%$$$$$%%$$#####$$$%%$$$$$$$$$##""!!!!!!""##""!!``!!""####$$$$$$$$$$$$$$$%%%%%%%&&&&&&&%%$$$###########""""#####$$$$$%%%%&&'&&&''''&&&&&''''&&&&&&&&&%%&&&&&&&%%%%%%%%%%%%%%%$$$$$$$$$%%&&&&&&&&&&&%%$$$$$$$$$$$$$$$$$$$####$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%&%%&%&&&&&&&&&&&&&&&''(((((((()))**********************++++++++++++********++,,,,,-------------------.....//0000100000000100111111111111111111122222223333333444334455566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>================>>>>>==<<<;<<<<<<<==>>>>>>>>==<<;;::9999999999999:::::::;;;;:::::::::::::::::;;:::::::;;<<<<<;;;;;;;;<<<<;;;;;;;;;;;<<====<<;;;;;<;<<<==>>>>>>>?????>>==<<;;::9988888999887777665555555555544455555444444455554444445555666666777776677888877666677888877777777778888999988888999999::9:::::::::;;::998888888888887766554433221100//........//0//..-----,,,+++++++**))((''&&&%%%$$$$####""!!!!!"""!!```!!!```!!!!""""!!!!!!""##$$%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;;:::::;;<<====<<;;::998877666778888888777766554433322233333222222222233322111111100000011223332211000///0011223223333221100/////0011000000000///00100//00///000////00000/////000/////001100///////0000//////.........//000000/////001122221100///0000111100000011221100/////00111111110000000////////..--,,+++++++++++++,,,--...--.........../..--,,++++++*********)))))))))))((((((((''&&&&&'''&&%%%%%%%%&%%$$##############""""""""""""""#####$$$$$$%%&&&&&&&&'''''''''''''''''''''''''''''''((((((((((((((((((((((((((((())**++,,--../////...............------,,,,,,++**))))))))))((((((((((('''''''&&&&&%%$$$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$##""""""##$$$%%$$$$$$$$$$########$$$$$$##$$$##""!!````!!""""!!``!!""############$$$$$$$$$$$$%%%%%%%%%$$######"""""""""""""####$$$$$$$%%&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%&%%%%%%%%%%$$$$$$%%%$$$###$#$$$%%&&&&&&&&&%%$$##########################$##########$#######$$$$$$$$$$$%%%%%%%%%%%%%%&&&%%%%%%%&&&&&'''''''((()))**********************++++++++++**))))****+++,,,,,,,,,,,,,,,,,-,-------..////000/0///000000100000000011110011111111222223333333334445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>========<<<<<<<<=======<<;;;;;;;;<<<==========<<;;::998888888888999:::::::;;::999999::::::::::::::::::::;;;;<;;;:::::;;<<;;;::::::;;;;<<==<<;;;;;;;;;;<<==>>>>>>>>>>>>==<<;;::998877888988777766554444444444444444444444444444444444445555666666777666677887766666677777766666676778888888888888899999999999::::::::998888777778887766554433221100//.....---..///..--,,,,,++++++++**))((''&&%%%$$$$$###"""!!```!!""!!`‘```!!!!``!!""""""!!""""##$$%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;;::999::;;<<==<<;;::998877666667788888777766554433222222233221111222222322111111100////0011222221100//////00112222223221100//...//0000/////00/////000/////////0//////000///////0//...//0000/////////////////...------..//0000///////0011111100//////0001100////00111100///////001100000000///////////..--,,+++**********++,,,--------..------...--,,++++******)))))))))(((((((((''''''''&&&&&&&&&&%%$$$$%%%%%$$#######"""""""""""""""""""""""""#######$$%%%&&&&&&&'&&&&&&&&&'''''''''''''&'''''''''''''''''('''(((((((((''''(())**++,,--...........--.......---,,,,,,,,,++**))))))(((((((((((''''''''''&&&&&&%%$$$$$$$%$$$$%%%%%%$$$$$$$%%%$$$%$$$$$##""!!!!""##$$$$$$#####$$##"""""###$$#########""!!``!!""!!``!!""""###############$$$$$$$%%%%%%%$$###"""""""""""!!!!"""""#####$$$$%%&%%%&&&&%%%%%&&&&%%%%%%%%%$$%%%%%%%$$$$$$$$$$$$$$$#########$$%%%%%%%%%%%$$###################""""#########################$$$$$$$$$$$$$$$$$%$$%$%%%%%%%%%%%%%%%&&''''''''((())))))))))))))))))))))************))))))))**+++++,,,,,,,,,,,,,,,,,,,-----..////0////////0//00000000000000000001111111222222233322334445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>?????????????????>>>>>??>>>>>>>>================<<<<<<<<<<<<<<<<=====<<;;;:;;;;;;;<<========<<;;::9988888888888889999999::::99999999999999999::9999999::;;;;;::::::::;;;;:::::::::::;;<<<<;;:::::;:;;;<<=======>>>>>==<<;;::998877777888776666554444444444433344444333333344443333334444555555666665566777766555566777766666666667777888877777888888998999999999::998877777777777766554433221100//..--------../..--,,,,,+++*******))((''&&%%%$$$####""""!!``!!!!`````!!!!!"!!````!!""####""""""##$$%%&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::::::99999::;;<<<<;;::998877665556677777776666554433222111222221111111111222110000000//////00112221100///...//001121122221100//.....//00/////////...//0//..//...///..../////.....///.....//00//.......////......---------..//////.....//00111100//...////0000//////001100//.....//00000000///////........--,,++*************+++,,---,,-----------.--,,++******)))))))))(((((((((((''''''''&&%%%%%&&&%%$$$$$$$$%$$##""""""""""""""!!!!!!!!!!!!!!"""""######$$%%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'''''''''''''''''''''''''''''(())**++,,--.....---------------,,,,,,++++++**))(((((((((('''''''''''&&&&&&&%%%%%$$###$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$####""!!!!!!""###$$##########""""""""######""###""!!``!!!!!!``!!""""""""""""############$$$$$$$$$##""""""!!!!!!!!!!!!!""""#######$$%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$%$$$$$$$$$$######$$$###"""#"###$$%%%%%%%%%$$##""""""""""""""""""""""""""#""""""""""#"""""""###########$$$$$$$$$$$$$$%%%$$$$$$$%%%%%&&&&&&&'''((())))))))))))))))))))))**********))(((())))***+++++++++++++++++,+,,,,,,,--....///./...//////0/////////0000//0000000011111222222222333445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>????>>>>>>>>>>>>>>>>>>>>>>>>=================<<<<<<<<;;;;;;;;<<<<<<<;;::::::::;;;<<<<<<<<<<;;::998877777777778889999999::9988888899999999999999999999::::;:::99999::;;:::999999::::;;<<;;::::::::::;;<<============<<;;::99887766777877666655443333333333333333333333333333333333334444555555666555566776655555566666655555565667777777777777788888888888999999998877776666677766554433221100//..-----,,,--...--,,+++++********))((''&&%%$$$#####"""!!!``!!!``!!!!!!"!!!!!!""######""####$$%%&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::::::9988899::;;<<;;::998877665555566777776666554433221111111221100001111112110000000//....//001111100//......//0011111121100//..---..////.....//.....///........./......///......./..---..////.................---,,,,,,--..////.......//000000//......///00//....//0000//.......//00////////...........--,,++***))))))))))**+++,,,,,,,,--,,,,,,---,,++****))))))((((((((('''''''''&&&&&&&&%%%%%%%%%%$$####$$$$$##"""""""!!!!!!!!!!!!!!!!!!!!!!!!!"""""""##$$$%%%%%%%&%%%%%%%%%&&&&&&&&&&&&&%&&&&&&&&&&&&&&&&&'&&&'''''''''&&&&''(())**++,,-----------,,-------,,,+++++++++**))(((((('''''''''''&&&&&&&&&&%%%%%%$$#######$####$$$$$$#######$$$###$#####""!!````!!""######"""""##""!!!!!"""##"""""""""!!``!!!!!!!``!!!!!"""""""""""""""#######$$$$$$$##"""!!!!!!!!!!!````!!!!!"""""####$$%$$$%%%%$$$$$%%%%$$$$$$$$$##$$$$$$$###############"""""""""##$$$$$$$$$$$##"""""""""""""""""""!!!!"""""""""""""""""""""""""#################$##$#$$$$$$$$$$$$$$$%%&&&&&&&&'''(((((((((((((((((((((())))))))))))(((((((())*****+++++++++++++++++++,,,,,--..../......../..///////////////////000000011111112221122333445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===>>>??>>>>>>>>>>>>=====>>========<<<<<<<<<<<<<<<<;;;;;;;;;;;;;;;;<<<<<;;:::9:::::::;;<<<<<<<<;;::99887777777777777888888899998888888888888888899888888899:::::99999999::::99999999999::;;;;::99999:9:::;;<<<<<<<=====<<;;::99887766666777665555443333333333322233333222222233332222223333444444555554455666655444455666655555555556666777766666777777887888888888998877666666666666554433221100//..--,,,,,,,,--.--,,+++++***)))))))((''&&%%$$$###""""!!!!!```````````!!"!!!!""##$$$$######$$%%&&'''''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>==<<;;::9999998888899::;;;;::9988776655444556666666555544332211100011111000000000011100///////......//0011100//...---..//00100111100//..-----..//.........---../..--..---...----.....-----...-----..//..-------....------,,,,,,,,,--......-----..//0000//..---....////......//00//..-----..////////.......--------,,++**)))))))))))))***++,,,++,,,,,,,,,,,-,,++**))))))((((((((('''''''''''&&&&&&&&%%$$$$$%%%$$########$##""!!!!!!!!!!!!!!``````````````!!!!!""""""##$$$$$$$$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&''(())**++,,-----,,,,,,,,,,,,,,,++++++******))((''''''''''&&&&&&&&&&&%%%%%%%$$$$$##"""##############################""""!!``!!"""##""""""""""!!!!!!!!""""""!!""""!!````!`````````!!!!!!!!!!!!!!!""""""""""""#########""!!!!!!`````````!!!!"""""""##$$$$$$$$$$$$$$$$$$$$$$$#######$##########""""""###"""!!!"!"""##$$$$$$$$$##""!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!!!!!!!"!!!!!!!"""""""""""##############$$$#######$$$$$%%%%%%%&&&'''(((((((((((((((((((((())))))))))((''''(((()))*****************+*+++++++,,----...-.---....../.........////..////////0000011111111122233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>======>>>>========================<<<<<<<<<<<<<<<<<;;;;;;;;::::::::;;;;;;;::99999999:::;;;;;;;;;;::998877666666666677788888889988777777888888888888888888889999:9998888899::9998888889999::;;::9999999999::;;<<<<<<<<<<<<;;::99887766556667665555443322222222222222222222222222222222222233334444445554444556655444444555555444444545566666666666666777777777778888888877666655555666554433221100//..--,,,,,+++,,---,,++*****))))))))((''&&%%$$###"""""!!!````@@@@`!!"""""##$$$$$$##$$$$%%&&'''''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>==<<;;::999999887778899::;;::998877665544444556666655554433221100000001100////000000100///////..----..//00000//..------..//000000100//..--,,,--....-----..-----...---------.------...-------.--,,,--....-----------------,,,++++++,,--....-------..//////..------...//..----..////..-------..//........-----------,,++**)))(((((((((())***++++++++,,++++++,,,++**))))(((((('''''''''&&&&&&&&&%%%%%%%%$$$$$$$$$$##""""#####""!!!!!!!```````````!!!!!!!""###$$$$$$$%$$$$$$$$$%%%%%%%%%%%%%$%%%%%%%%%%%%%%%%%&%%%&&&&&&&&&%%%%&&''(())**++,,,,,,,,,,,++,,,,,,,+++*********))((''''''&&&&&&&&&&&%%%%%%%%%%$$$$$$##"""""""#""""######"""""""###"""#"""""""!!``!!"""""""!!!!!""!!`````!!!""!!!!!!!"""!!````````!!!!!!!!!!!!!!!"""""""#######""!!!````Ϗ```!!!!!""""##$###$$$$#####$$$$#########""#######"""""""""""""""!!!!!!!!!""###########""!!!!!!!!!!!!!!!!!!!````!!!!!!!!!!!!!!!!!!!!!!!!!"""""""""""""""""#""#"###############$$%%%%%%%%&&&''''''''''''''''''''''((((((((((((''''''''(()))))*******************+++++,,----.--------.--...................///////0000000111001122233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>==<<<===>>============<<<<<==<<<<<<<<;;;;;;;;;;;;;;;;::::::::::::::::;;;;;::99989999999::;;;;;;;;::9988776666666666666777777788887777777777777777788777777788999998888888899998888888888899::::998888898999::;;;;;;;<<<<<;;::99887766555556665544443322222222222111222221111111222211111122223333334444433445555443333445555444444444455556666555556666667767777777778877665555555555554433221100//..--,,++++++++,,-,,++*****)))(((((((''&&%%$$###"""!!!!`````!!""""##$$%%%%$$$$$$%%&&''((((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>======<<;;::99888888777778899::::9988776655443334455555554444332211000///00000//////////000//.......------..//000//..---,,,--..//0//0000//..--,,,,,--..---------,,,--.--,,--,,,---,,,,-----,,,,,---,,,,,--..--,,,,,,,----,,,,,,+++++++++,,------,,,,,--..////..--,,,----....------..//..--,,,,,--........-------,,,,,,,,++**))((((((((((((()))**+++**+++++++++++,++**))(((((('''''''''&&&&&&&&&&&%%%%%%%%$$#####$$$##""""""""#""!!``````Ғ``!!!!!!""########$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&''(())**++,,,,,+++++++++++++++******))))))((''&&&&&&&&&&%%%%%%%%%%%$$$$$$$#####""!!!""""""""""""""""""""""""""""""!!!!!!!``!!!!!!""!!!!!!!!!!```!!!!!!``!!!!!!``ӓ`````````!!!!!!!!!!!!"""""""""!!``є`!!!!!!!""#######################"""""""#""""""""""!!!!!!"""!!!```!`!!!""#########""!!``````````````````````!``````````!```````!!!!!!!!!!!""""""""""""""###"""""""#####$$$$$$$%%%&&&''''''''''''''''''''''((((((((((''&&&&''''((()))))))))))))))))*)*******++,,,,---,-,,,------.---------....--......../////0000000001112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>==<<<<<<====<<<<<<<<<<<<<<<<<<<<<<<<;;;;;;;;;;;;;;;;;::::::::99999999:::::::9988888888999::::::::::998877665555555555666777777788776666667777777777777777777788889888777778899888777777888899::99888888888899::;;;;;;;;;;;;::99887766554455565544443322111111111111111111111111111111111111222233333344433334455443333334444443333334344555555555555556666666666677777777665555444445554433221100//..--,,+++++***++,,,++**)))))((((((((''&&%%$$##"""!!!!!`````!!""###$$%%%%%%$$%%%%&&''((((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>=============<<;;::9988888877666778899::998877665544333334455555444433221100///////00//....//////0//.......--,,,,--../////..--,,,,,,--..//////0//..--,,+++,,----,,,,,--,,,,,---,,,,,,,,,-,,,,,,---,,,,,,,-,,+++,,----,,,,,,,,,,,,,,,,,+++******++,,----,,,,,,,--......--,,,,,,---..--,,,,--....--,,,,,,,--..--------,,,,,,,,,,,++**))(((''''''''''(()))********++******+++**))((((''''''&&&&&&&&&%%%%%%%%%$$$$$$$$##########""!!!!"""""!!`Ð`````!!"""#######$#########$$$$$$$$$$$$$#$$$$$$$$$$$$$$$$$%$$$%%%%%%%%%$$$$%%&&''(())**+++++++++++**+++++++***)))))))))((''&&&&&&%%%%%%%%%%%$$$$$$$$$$######""!!!!!!!"!!!!""""""!!!!!!!"""!!!"!!!!!!!!````!!!!!!!!!!!`````!!!`ŀ`!!`````!!!`@@``````!!!!!!!"""""""!!`````!!!!""#"""####"""""####"""""""""!!"""""""!!!!!!!!!!!!!!!`````!!"""""""""""!!`˕````!!!!!!!!!!!!!!!!!"!!"!"""""""""""""""##$$$$$$$$%%%&&&&&&&&&&&&&&&&&&&&&&''''''''''''&&&&&&&&''((((()))))))))))))))))))*****++,,,,-,,,,,,,,-,,-------------------.......///////000//001112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>======<<;;;<<<==<<<<<<<<<<<<;;;;;<<;;;;;;;;::::::::::::::::9999999999999999:::::998887888888899::::::::998877665555555555555666666677776666666666666666677666666677888887777777788887777777777788999988777778788899:::::::;;;;;::99887766554444455544333322111111111110001111100000001111000000111122222233333223344443322223344443333333333444455554444455555566566666666677665544444444444433221100//..--,,++********++,++**)))))((('''''''&&%%$$##"""!!!``!``````````!!""###$$%%&&&&%%%%%%&&''(()))))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>===========<<<<<<;;::998877777766666778899998877665544332223344444443333221100///.../////..........///..-------,,,,,,--..///..--,,,+++,,--../..////..--,,+++++,,--,,,,,,,,,+++,,-,,++,,+++,,,++++,,,,,+++++,,,+++++,,--,,+++++++,,,,++++++*********++,,,,,,+++++,,--....--,,+++,,,,----,,,,,,--..--,,+++++,,--------,,,,,,,++++++++**))(('''''''''''''((())***))***********+**))((''''''&&&&&&&&&%%%%%%%%%%%$$$$$$$$##"""""###""!!!!!!!!"!!``!!""""""""###############################$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%&&''(())**+++++***************))))))((((((''&&%%%%%%%%%%$$$$$$$$$$$#######"""""!!```!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!```````````````!!`````````````€```Ї``````!!!!!!!!!!````!!"""""""""""""""""""""""!!!!!!!"!!!!!!!!!!``````!!!`̓`!!"""""""""!!`ɀ`````````!!!!!!!!!!!!!!"""!!!!!!!"""""#######$$$%%%&&&&&&&&&&&&&&&&&&&&&&''''''''''&&%%%%&&&&'''((((((((((((((((()()))))))**++++,,,+,+++,,,,,,-,,,,,,,,,----,,--------...../////////000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=================<<;;;;;;<<<<;;;;;;;;;;;;;;;;;;;;;;;;:::::::::::::::::9999999988888888999999988777777778889999999999887766554444444444555666666677665555556666666666666666666677778777666667788777666666777788998877777777778899::::::::::::99887766554433444544333322110000000000000000000000000000000000001111222222333222233443322222233333322222232334444444444444455555555555666666665544443333344433221100//..--,,++*****)))**+++**))(((((''''''''&&%%$$##""!!!````@```!``!``!!!""##$$$%%&&&&&&%%&&&&''(()))))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>================<<<<<<<<<<<<<;;::998877777766555667788998877665544332222233444443333221100//.......//..----....../..-------,,++++,,--.....--,,++++++,,--....../..--,,++***++,,,,+++++,,+++++,,,+++++++++,++++++,,,+++++++,++***++,,,,+++++++++++++++++***))))))**++,,,,+++++++,,------,,++++++,,,--,,++++,,----,,+++++++,,--,,,,,,,,+++++++++++**))(('''&&&&&&&&&&''((())))))))**))))))***))((''''&&&&&&%%%%%%%%%$$$$$$$$$########""""""""""!!````!!!!!``!!!"""""""#"""""""""#############"#################$###$$$$$$$$$####$$%%&&''(())***********))*******)))(((((((((''&&%%%%%%$$$$$$$$$$$##########""""""!!````!````!!!!!!```````!!!```!``΅``ň·͋``!!!!!!!````!!"!!!""""!!!!!""""!!!!!!!!!``!!!!!!!`````````!!!!!!!!!!!!`````````!``!`!!!!!!!!!!!!!!!""########$$$%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&%%%%%%%%&&'''''((((((((((((((((((()))))**++++,++++++++,++,,,,,,,,,,,,,,,,,,,-------.......///..//000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>=============<<<<<<;;:::;;;<<;;;;;;;;;;;;:::::;;::::::::9999999999999999888888888888888899999887776777777788999999998877665544444444444445555555666655555555555555555665555555667777766666666777766666666666778888776666676777889999999:::::998877665544333334443322221100000000000///00000///////0000//////0000111111222221122333322111122333322222222223333444433333444444554555555555665544333333333333221100//..--,,++**))))))))**+**))((((('''&&&&&&&%%$$##""!!!`@@`!!``!!``!!!!!!""##$$$%%&&''''&&&&&&''(())*****++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????>>>>>>================<<<<<<<<<<<;;;;;;::998877666666555556677888877665544332211122333333322221100//...---.....----------...--,,,,,,,++++++,,--...--,,+++***++,,--.--....--,,++*****++,,+++++++++***++,++**++***+++****+++++*****+++*****++,,++*******++++******)))))))))**++++++*****++,,----,,++***++++,,,,++++++,,--,,++*****++,,,,,,,,+++++++********))((''&&&&&&&&&&&&&'''(()))(()))))))))))*))((''&&&&&&%%%%%%%%%$$$$$$$$$$$########""!!!!!"""!!````!!``!!!!!!!!!"""""""""""""""""""""""""""""""#############################$$%%&&''(())*****)))))))))))))))((((((''''''&&%%$$$$$$$$$$###########"""""""!!!!!!````````````͏ЍȌ```````Ń`!!!!!!!!!!!!!!!!!!!!!!!`````!`````Ҕ``!!!!!!!!!!````!!!```````!!!!!"""""""###$$$%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&%%$$$$%%%%&&&'''''''''''''''''('((((((())****+++*+***++++++,+++++++++,,,,++,,,,,,,,-----.........///00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>==<<<<<<<<<<<<<<<<<;;::::::;;;;::::::::::::::::::::::::9999999999999999988888888777777778888888776666666677788888888887766554433333333334445555555665544444455555555555555555555666676665555566776665555556666778877666666666677889999999999998877665544332233343322221100////////////////////////////////////00001111112221111223322111111222222111111212233333333333333444444444445555555544333322222333221100//..--,,++**)))))((())***))(('''''&&&&&&&&%%$$##""!!``@`!!!``!!!!!"!!"""##$$%%%&&''''''&&''''(())*****++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????>>>>>>=======<<<<<<<<<<<<<<<<;;;;;;;;;;;;;::998877666666554445566778877665544332211111223333322221100//..-------..--,,,,------.--,,,,,,,++****++,,-----,,++******++,,------.--,,++**)))**++++*****++*****+++*********+******+++*******+**)))**++++*****************)))(((((())**++++*******++,,,,,,++******+++,,++****++,,,,++*******++,,++++++++***********))((''&&&%%%%%%%%%%&&'''(((((((())(((((()))((''&&&&%%%%%%$$$$$$$$$#########""""""""!!!!!!!!"!!`````````!!!!!!!"!!!!!!!!!"""""""""""""!"""""""""""""""""#"""#########""""##$$%%&&''(()))))))))))(()))))))((('''''''''&&%%$$$$$$###########""""""""""!!!!!!!!````΍ΐՕʼn`!!```!!!!`````!!!!```````ӑ```````````‰ϒό```````!!""""""""###$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%$$$$$$$$%%&&&&&'''''''''''''''''''((((())****+********+**+++++++++++++++++++,,,,,,,-------...--..///00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>???????>>>>????????????????????????>>======<<<<<<<<<<<<<;;;;;;::999:::;;::::::::::::99999::999999998888888888888888777777777777777788888776665666666677888888887766554433333333333334444444555544444444444444444554444444556666655555555666655555555555667777665555565666778888888999998877665544332222233322111100///////////.../////.......////......////0000001111100112222110000112222111111111122223333222223333334434444444445544332222222222221100//..--,,++**))(((((((())*))(('''''&&&%%%%%%%$$##""!!```!!!!``!!"!!""""""##$$%%%&&''((((''''''(())**+++++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>======<<<<<<<<<<<<<<<<;;;;;;;;;;;::::::998877665555554444455667777665544332211000112222222111100//..---,,,-----,,,,,,,,,,---,,+++++++******++,,---,,++***)))**++,,-,,----,,++**)))))**++*********)))**+**))**)))***))))*****)))))***)))))**++**)))))))****))))))((((((((())******)))))**++,,,,++**)))****++++******++,,++**)))))**++++++++*******))))))))((''&&%%%%%%%%%%%%%&&&''(((''((((((((((()((''&&%%%%%%$$$$$$$$$###########""""""""!!`````!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"""""""""""""""""""""""""""""##$$%%&&''(()))))(((((((((((((((''''''&&&&&&%%$$##########"""""""""""!!!!!!!``````Ə```````````Ƒ`!!!!!!!"""###$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%$$####$$$$%%%&&&&&&&&&&&&&&&&&'&'''''''(())))***)*)))******+*********++++**++++++++,,,,,---------...//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>?>>>>>>>>>>>>>>>>>>>>>>??>>>???>>======<<;;;;;;;;;;;;;;;;;::999999::::99999999999999999999999988888888888888888777777776666666677777776655555555666777777777766554433222222222233344444445544333333444444444444444444445555655544444556655544444455556677665555555555667788888888888877665544332211222322111100//....................................////00000011100001122110000001111110000001011222222222222223333333333344444444332222111112221100//..--,,++**))((((('''(()))((''&&&&&%%%%%%%%$$##""!!``````!!""!!!!"""""#""###$$%%&&&''((((((''(((())**+++++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>======<<<<<<<;;;;;;;;;;;;;;;;:::::::::::::998877665555554433344556677665544332211000001122222111100//..--,,,,,,,--,,++++,,,,,,-,,+++++++**))))**++,,,,,++**))))))**++,,,,,,-,,++**))((())****)))))**)))))***)))))))))*))))))***)))))))*))((())****)))))))))))))))))(((''''''(())****)))))))**++++++**))))))***++**))))**++++**)))))))**++********)))))))))))((''&&%%%$$$$$$$$$$%%&&&''''''''((''''''(((''&&%%%%$$$$$$#########"""""""""!!!!!!!!```!!!`Âƅ`!`````````!!!!!!!!!!!!!`!!!!!!!!!!!!!!!!!"!!!"""""""""!!!!""##$$%%&&''(((((((((((''((((((('''&&&&&&&&&%%$$######"""""""""""!!!!!!!!!!``ˎˆɈ`!!!!!!!!!!"""######################$$$$$$$$$$$$########$$%%%%%&&&&&&&&&&&&&&&&&&&'''''(())))*))))))))*))*******************+++++++,,,,,,,---,,--...//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===>>>>>>>====>>>>>>>>>>>>>>>>>>>>>>>>==<<<<<<;;;;;;;;;;;;;::::::99888999::99999999999988888998888888877777777777777776666666666666666777776655545555555667777777766554433222222222222233333334444333333333333333334433333334455555444444445555444444444445566665544444545556677777778888877665544332211111222110000//...........---.....-------....------....//////00000//00111100////0011110000000000111122221111122222233233333333344332211111111111100//..--,,++**))((''''''''(()((''&&&&&%%%$$$$$$$##""!!``!!!!!""""!!""#""######$$%%&&&''(())))(((((())**++,,,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>========<<<<<<;;;;;;;;;;;;;;;;:::::::::::999999887766554444443333344556666554433221100///0011111110000//..--,,,+++,,,,,++++++++++,,,++*******))))))**++,,,++**)))((())**++,++,,,,++**))((((())**)))))))))((())*))(())((()))(((()))))((((()))((((())**))((((((())))(((((('''''''''(())))))((((())**++++**))((())))****))))))**++**))((((())********)))))))((((((((''&&%%$$$$$$$$$$$$$%%%&&'''&&'''''''''''(''&&%%$$$$$$#########"""""""""""!!!!!!!!````!```````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""##$$%%&&''((((('''''''''''''''&&&&&&%%%%%%$$##""""""""""!!!!!!!!!!!``````````````!!!"""######################$$$$$$$$$$##""""####$$$%%%%%%%%%%%%%%%%%&%&&&&&&&''(((()))()((())))))*)))))))))****))********+++++,,,,,,,,,---..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=======>======================>>===>>>==<<<<<<;;:::::::::::::::::998888889999888888888888888888888888777777777777777776666666655555555666666655444444445556666666666554433221111111111222333333344332222223333333333333333333344445444333334455444333333444455665544444444445566777777777777665544332211001112110000//..------------------------------------....//////000////001100//////000000//////0/001111111111111122222222222333333332211110000011100//..--,,++**))(('''''&&&''(((''&&%%%%%$$$$$$$$$##""!!`@@`!!!""""""""#####$####$$%%&&''(())))))(())))**++,,,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????>>>>>==============<<<<<<;;;;;;;::::::::::::::::9999999999999887766554444443322233445566554433221100/////00111110000//..--,,+++++++,,++****++++++,++*******))(((())**+++++**))(((((())**++++++,++**))(('''(())))((((())((((()))((((((((()(((((()))((((((()(('''(())))((((((((((((((((('''&&&&&&''(())))((((((())******))(((((()))**))(((())****))((((((())**))))))))(((((((((((''&&%%$$$##########$$%%%&&&&&&&&''&&&&&&'''&&%%$$$$######"""""""""!!!!!!!!!``````````ƊӇ```````````!```!!!!!!!!!````!!""##$$%%&&'''''''''''&&'''''''&&&%%%%%%%%%$$##""""""!!!!!!!!!!!`````````!!!""""""""""""""""""""""############""""""""##$$$$$%%%%%%%%%%%%%%%%%%%&&&&&''(((()(((((((()(()))))))))))))))))))*******+++++++,,,++,,---..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<=======<<<<========================<<;;;;;;:::::::::::::99999988777888998888888888887777788777777776666666666666666555555555555555566666554443444444455666666665544332211111111111112222222333322222222222222222332222222334444433333333444433333333333445555443333343444556666666777776655443322110000011100////..-----------,,,-----,,,,,,,----,,,,,,----....../////..//0000//....//0000//////////0000111100000111111221222222222332211000000000000//..--,,++**))((''&&&&&&&&''(''&&%%%%%$$$#########""!!`@`!!""""""""##$##$$#####$$%%&&''(())**))))))**++,,-----..//00112233445566778899::;;<<==>>???????>>???????????????????????????????????????????????????????????????????>>>=============<<<<<<<<;;;;;;::::::::::::::::999999999998888887766554433333322222334455554433221100//...//0000000////..--,,+++***+++++**********+++**)))))))(((((())**+++**))((('''(())**+**++++**))(('''''(())((((((((('''(()((''(('''(((''''((((('''''((('''''(())(('''''''((((''''''&&&&&&&&&''(((((('''''(())****))(('''(((())))(((((())**))(('''''(())))))))(((((((''''''''&&%%$$#############$$$%%&&&%%&&&&&&&&&&&'&&%%$$######"""""""""!!!!!!!!!!!`Ԏ€```````````!!""##$$%%&&'''''&&&&&&&&&&&&&&&%%%%%%$$$$$$##""!!!!!!!!!!``````Ȇ`!!!""""""""""""""""""""""##########""!!!!""""###$$$$$$$$$$$$$$$$$%$%%%%%%%&&''''((('('''(((((()((((((((())))(())))))))*****+++++++++,,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<<<<<<=<<<<<<<<<<<<<<<<<<<<<<==<<<===<<;;;;;;::99999999999999999887777778888777777777777777777777777666666666666666665555555544444444555555544333333334445555555555443322110000000000111222222233221111112222222222222222222233334333222223344333222222333344554433333333334455666666666666554433221100//000100////..--,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,----......///....//00//......//////.....././/000000000000001111111111122222222110000/////000//..--,,++**))((''&&&&&%%%&&'''&&%%$$$$$###########""!!````@`!!!!!!!!!""##$$$$##"""##$$%%&&''(())**))****++,,-----..//00112233445566778899::;;<<==>>>>?>>>>>>>>>>>>>>>>>??????????????????????????????????????????????????????>>>>=====<<<<<<<<<<<<<<;;;;;;:::::::999999999999999988888888888887766554433333322111223344554433221100//.....//00000////..--,,++*******++**))))******+**)))))))((''''(())*****))((''''''(())******+**))((''&&&''(((('''''(('''''((('''''''''(''''''((('''''''(''&&&''(((('''''''''''''''''&&&%%%%%%&&''(((('''''''(())))))((''''''((())((''''(())))(('''''''(())(((((((('''''''''''&&%%$$###""""""""""##$$$%%%%%%%%&&%%%%%%&&&%%$$####""""""!!!!!!!!!````````͎`!!""##$$%%&&'&&&&&&&&&%%&&&&&&&%%%$$$$$$$$$##""!!!!!!`````Џ```!!!!!!!!!!!!!!!!!!!!!!""""""""""""!!!!!!!!""#####$$$$$$$$$$$$$$$$$$$%%%%%&&''''(''''''''(''((((((((((((((((((()))))))*******+++**++,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;<<<<<<<;;;;<<<<<<<<<<<<<<<<<<<<<<<<;;::::::99999999999998888887766677788777777777777666667766666666555555555555555544444444444444445555544333233333334455555555443322110000000000000111111122221111111111111111122111111122333332222222233332222222222233444433222223233344555555566666554433221100/////000//....--,,,,,,,,,,,+++,,,,,+++++++,,,,++++++,,,,------.....--..////..----..////..........////0000/////000000110111111111221100////////////..--,,++**))((''&&%%%%%%%%&&'&&%%$$$$$###""""""""""""!!`````!!!``!!!!!!!!!!!""##$$##"""""##$$%%&&''(())******++,,--.....//00112233445566778899::;;<<==>>==>>>>>>>==>>>>>>>>>>>>>>>????????????????????????????????????????????????>>>>===<<<<<<<<<<<<<;;;;;;;;::::::99999999999999998888888888877777766554433222222111112233444433221100//..---..///////....--,,++***)))*****))))))))))***))(((((((''''''(())***))(('''&&&''(())*))****))((''&&&&&''(('''''''''&&&''(''&&''&&&'''&&&&'''''&&&&&'''&&&&&''((''&&&&&&&''''&&&&&&%%%%%%%%%&&''''''&&&&&''(())))((''&&&''''((((''''''(())((''&&&&&''(((((((('''''''&&&&&&&&%%$$##"""""""""""""###$$%%%$$%%%%%%%%%%%&%%$$##""""""!!!!!!!!!```Џ`!!""##$$%%&&&&&&&%%%%%%%%%%%%%%%$$$$$$######""!!`````Д`!!!!!!!!!!!!!!!!!!!!!!""""""""""!!````!!!!"""#################$#$$$$$$$%%&&&&'''&'&&&''''''('''''''''((((''(((((((()))))*********+++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;;;;;<;;;;;;;;;;;;;;;;;;;;;;<<;;;<<<;;::::::998888888888888888877666666777766666666666666666666666655555555555555555444444443333333344444443322222222333444444444433221100//////////0001111111221100000011111111111111111111222232221111122332221111112222334433222222222233445555555555554433221100//..///0//....--,,++++++++++++++++++++++++++++++++++++,,,,------...----..//..------......------.-..//////////////000000000001111111100////.....///..--,,++**))((''&&%%%%%$$$%%&&&%%$$#####"""""""""""""""!!!!!!!!!!``!!```````!!""####""!!!""##$$%%&&''(())**++++,,--.....//00112233445566778899::;;<<========>=================>>>>>>>>??????????????????????????????????????????>>>>====<<<<<;;;;;;;;;;;;;;::::::99999998888888888888888777777777777766554433222222110001122334433221100//..-----../////....--,,++**)))))))**))(((())))))*))(((((((''&&&&''(()))))((''&&&&&&''(())))))*))((''&&%%%&&''''&&&&&''&&&&&'''&&&&&&&&&'&&&&&&'''&&&&&&&'&&%%%&&''''&&&&&&&&&&&&&&&&&%%%$$$$$$%%&&''''&&&&&&&''((((((''&&&&&&'''((''&&&&''((((''&&&&&&&''((''''''''&&&&&&&&&&&%%$$##"""!!!!!!!!!!""###$$$$$$$$%%$$$$$$%%%$$##""""!!!!!!``````ϖ`!!""##$$%%&&%%%%%%%%%$$%%%%%%%$$$#########""!!`і``````````````````````!!!!!!!!!!!!````!!"""""###################$$$$$%%&&&&'&&&&&&&&'&&'''''''''''''''''''((((((()))))))***))**+++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::;;;;;;;::::;;;;;;;;;;;;;;;;;;;;;;;;::9999998888888888888777777665556667766666666666655555665555555544444444444444443333333333333333444443322212222222334444444433221100/////////////0000000111100000000000000000110000000112222211111111222211111111111223333221111121222334444444555554433221100//.....///..----,,+++++++++++***+++++*******++++******++++,,,,,,-----,,--....--,,,,--....----------....////.....//////00/0000000001100//............--,,++**))((''&&%%$$$$$$$$%%&%%$$#####"""!!!!!!!!!!""""!!!!!"""!!```!!``!!""##""!!!!!""##$$%%&&''(())**++,,--../////00112233445566778899::;;<<======<<=======<<===============>>>>????????????????????????????????????????>>>>====<<<;;;;;;;;;;;;;::::::::999999888888888888888877777777777666666554433221111110000011223333221100//..--,,,--.......----,,++**)))((()))))(((((((((()))(('''''''&&&&&&''(()))((''&&&%%%&&''(()(())))((''&&%%%%%&&''&&&&&&&&&%%%&&'&&%%&&%%%&&&%%%%&&&&&%%%%%&&&%%%%%&&''&&%%%%%%%&&&&%%%%%%$$$$$$$$$%%&&&&&&%%%%%&&''((((''&&%%%&&&&''''&&&&&&''((''&&%%%%%&&''''''''&&&&&&&%%%%%%%%$$##""!!!!!!!!!!!!!"""##$$$##$$$$$$$$$$$%$$##""!!!!!!```Њ`!!""##$$%%%%%%%$$$$$$$$$$$$$$$######""""""!!``!!!!!!!!!!!``!!!"""""""""""""""""#"#######$$%%%%&&&%&%%%&&&&&&'&&&&&&&&&''''&&''''''''((((()))))))))***++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::::::;::::::::::::::::::::::;;:::;;;::9999998877777777777777777665555556666555555555555555555555555444444444444444443333333322222222333333322111111112223333333333221100//..........///00000001100//////000000000000000000001111211100000112211100000011112233221111111111223344444444444433221100//..--.../..----,,++************************************++++,,,,,,---,,,,--..--,,,,,,------,,,,,,-,--..............///////////00000000//....-----...--,,++**))((''&&%%$$$$$###$$%%%$$##"""""!!!!!!!!!!!!!"""""""""""!!``````!!"""""!!```!!""##$$%%&&''(())**++,,--..///00112233445566778899::;;<<====<<<<<<=<<<<<<<<<<<<<<<<<========>>??????????????????????????????????????>>====<<<<;;;;;::::::::::::::9999998888888777777777777777766666666666665544332211111100///00112233221100//..--,,,,,--.....----,,++**))((((((())((''''(((((()(('''''''&&%%%%&&''(((((''&&%%%%%%&&''(((((()((''&&%%$$$%%&&&&%%%%%&&%%%%%&&&%%%%%%%%%&%%%%%%&&&%%%%%%%&%%$$$%%&&&&%%%%%%%%%%%%%%%%%$$$######$$%%&&&&%%%%%%%&&''''''&&%%%%%%&&&''&&%%%%&&''''&&%%%%%%%&&''&&&&&&&&%%%%%%%%%%%$$##""!!!``````````!!"""########$$######$$$##""!!!!```ˌ`!!""##$$%%$$$$$$$$$##$$$$$$$###"""""""""!!!`Ò`````````!!``!!!!!"""""""""""""""""""#####$$%%%%&%%%%%%%%&%%&&&&&&&&&&&&&&&&&&&'''''''((((((()))(())***++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????>>>>>?>????????????>>==<<;;::999:::::::9999::::::::::::::::::::::::9988888877777777777776666665544455566555555555555444445544444444333333333333333322222222222222223333322111011111112233333333221100//.............///////0000/////////////////00///////0011111000000001111000000000001122221100000101112233333334444433221100//..-----...--,,,,++***********)))*****)))))))****))))))****++++++,,,,,++,,----,,++++,,----,,,,,,,,,,----....-----......//./////////00//..------------,,++**))((''&&%%$$########$$%$$##"""""!!!``````````!!"""""""!!"!!`@@`!!!!""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<===<<<<;;<<<<<<<;;<<<<<<<<<<<<<<<====>>????????????????????????????????????>>====<<<<;;;:::::::::::::9999999988888877777777777777776666666666655555544332211000000/////001122221100//..--,,+++,,-------,,,,++**))((('''(((((''''''''''(((''&&&&&&&%%%%%%&&''(((''&&%%%$$$%%&&''(''((((''&&%%$$$$$%%&&%%%%%%%%%$$$%%&%%$$%%$$$%%%$$$$%%%%%$$$$$%%%$$$$$%%&&%%$$$$$$$%%%%$$$$$$#########$$%%%%%%$$$$$%%&&''''&&%%$$$%%%%&&&&%%%%%%&&''&&%%$$$$$%%&&&&&&&&%%%%%%%$$$$$$$$##""!!```!!!""###""###########$##""!!````!!""##$$%$$$$$###############""""""!!!!!!````@``!!!!!!!!!!!!!!!!!"!"""""""##$$$$%%%$%$$$%%%%%%&%%%%%%%%%&&&&%%&&&&&&&&'''''((((((((()))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>???????>>==<<;;::9999999:9999999999999999999999::999:::9988888877666666666666666665544444455554444444444444444444444443333333333333333322222222111111112222222110000000011122222222221100//..----------...///////00//......////////////////////00001000/////0011000//////000011221100000000001122333333333333221100//..--,,---.--,,,,++**))))))))))))))))))))))))))))))))))))****++++++,,,++++,,--,,++++++,,,,,,++++++,+,,--------------...........////////..----,,,,,---,,++**))((''&&%%$$#####"""##$$$##""!!!!!```!!"""!!!!!!!`Í`!!!!!!"!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==<<;;;;;;<;;;;;;;;;;;;;;;;;<<<<<<<<==>>??????????????????????????????????>>==<<<<;;;;:::::9999999999999988888877777776666666666666666555555555555544332211000000//...//0011221100//..--,,+++++,,-----,,,,++**))(('''''''((''&&&&''''''(''&&&&&&&%%$$$$%%&&'''''&&%%$$$$$$%%&&''''''(''&&%%$$###$$%%%%$$$$$%%$$$$$%%%$$$$$$$$$%$$$$$$%%%$$$$$$$%$$###$$%%%%$$$$$$$$$$$$$$$$$###""""""##$$%%%%$$$$$$$%%&&&&&&%%$$$$$$%%%&&%%$$$$%%&&&&%%$$$$$$$%%&&%%%%%%%%$$$$$$$$$$$##""!!`ƍ`!!!!""""""""##""""""###""!!`Г``!!""##$$$$$#########""#######"""!!!!!!!!!`͒Ў```!!!!!!!!!!!!!!!!!!!"""""##$$$$%$$$$$$$$%$$%%%%%%%%%%%%%%%%%%%&&&&&&&'''''''(((''(()))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????>>>>>=====>=>>>>>>????>>==<<;;::99888999999988889999999999999999999999998877777766666666666665555554433344455444444444444333334433333333222222222222222211111111111111112222211000/000000011222222221100//..-------------.......////.................//.......//00000////////0000///////////00111100/////0/00011222222233333221100//..--,,,,,---,,++++**)))))))))))((()))))((((((())))(((((())))******+++++**++,,,,++****++,,,,++++++++++,,,,----,,,,,------..-.........//..--,,,,,,,,,,,,++**))((''&&%%$$##""""""""##$##""!!!!!`Д``!!"!!!!``!!``!!````!!"!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==<<;;;;::;;;;;;;::;;;;;;;;;;;;;;;<<<<==>>????????????????????????????????>>==<<<<;;;;:::99999999999998888888877777766666666666666665555555555544444433221100//////.....//00111100//..--,,++***++,,,,,,,++++**))(('''&&&'''''&&&&&&&&&&'''&&%%%%%%%$$$$$$%%&&'''&&%%$$$###$$%%&&'&&''''&&%%$$#####$$%%$$$$$$$$$###$$%$$##$$###$$$####$$$$$#####$$$#####$$%%$$#######$$$$######"""""""""##$$$$$$#####$$%%&&&&%%$$###$$$$%%%%$$$$$$%%&&%%$$#####$$%%%%%%%%$$$$$$$#########""!!`ō````!!"""!!"""""""""""#""!!``!!""##$$##$#####"""""""""""""""!!!!!!```````````````````!`!!!!!!!""####$$$#$###$$$$$$%$$$$$$$$$%%%%$$%%%%%%%%&&&&&'''''''''((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????>>>==============>>>>>>>==<<;;::9988888889888888888888888888888899888999887777776655555555555555555443333334444333333333333333333333333222222222222222221111111100000000111111100////////000111111111100//..--,,,,,,,,,,---.......//..------....................////0///.....//00///......////001100//////////00112222222222221100//..--,,++,,,-,,++++**))(((((((((((((((((((((((((((((((((((())))******+++****++,,++******++++++******+*++,,,,,,,,,,,,,,-----------........--,,,,+++++,,,++**))((''&&%%$$##"""""!!!""###""!!`````!!!``````````!!"!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<<;;::::::;:::::::::::::::::;;;;;;;;<<==>>??????????????????????????????>>==<<;;;;::::999998888888888888877777766666665555555555555555444444444444433221100//////..---..//001100//..--,,++*****++,,,,,++++**))((''&&&&&&&''&&%%%%&&&&&&'&&%%%%%%%$$####$$%%&&&&&%%$$######$$%%&&&&&&'&&%%$$##"""##$$$$#####$$#####$$$#########$######$$$#######$##"""##$$$$#################"""!!!!!!""##$$$$#######$$%%%%%%$$######$$$%%$$####$$%%%%$$#######$$%%$$$$$$$$#############""!!``!!!!!!!!""!!!!!!""""!!``!!""##$#####"""""""""!!"""""""!!!````````!!!!!""####$########$##$$$$$$$$$$$$$$$$$$$%%%%%%%&&&&&&&'''&&''((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????>>=====<<<<<=<======>>>>==<<;;::9988777888888877778888888888888888888888887766666655555555555554444443322233344333333333333222223322222222111111111111111100000000000000001111100///.///////001111111100//..--,,,,,,,,,,,,,-------....-----------------..-------../////........////...........//0000//....././//001111111222221100//..--,,+++++,,,++****))((((((((((('''((((('''''''((((''''''(((())))))*****))**++++**))))**++++**********++++,,,,+++++,,,,,,--,---------..--,,++++++++++++**))((''&&%%$$##""!!!!!!!!""#""!!``!`ŁĀ`!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<<;;::::99:::::::99:::::::::::::::;;;;<<==>>????????????????????????????>>==<<;;;;::::999888888888888877777777666666555555555555555544444444444333333221100//......-----..//0000//..--,,++**)))**+++++++****))((''&&&%%%&&&&&%%%%%%%%%%&&&%%$$$$$$$######$$%%&&&%%$$###"""##$$%%&%%&&&&%%$$##"""""##$$#########"""##$##""##"""###""""#####"""""###"""""##$$##"""""""####""""""!!!!!!!!!""######"""""##$$%%%%$$##"""####$$$$######$$%%$$##"""""##$$$$$$$$#######""""""""""""!!``!!!``!!!!!!!!!!!""!!!``!!""####""#"""""!!!!!!!!!!!!!!!``Ї````!!""""###"#"""######$#########$$$$##$$$$$$$$%%%%%&&&&&&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????>>===<<<<<<<<<<<<<<=======<<;;::9988777777787777777777777777777777887778887766666655444444444444444443322222233332222222222222222222222221111111111111111100000000////////0000000//........///0000000000//..--,,++++++++++,,,-------..--,,,,,,--------------------..../...-----..//...------....//00//..........//0011111111111100//..--,,++**+++,++****))((''''''''''''''''''''''''''''''''''''(((())))))***))))**++**))))))******))))))*)**++++++++++++++,,,,,,,,,,,--------,,++++*****+++**))((''&&%%$$##""!!!!!```!!""""!!````!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;;::999999:99999999999999999::::::::;;<<==>>??????????????????????????>>==<<;;::::99998888877777777777777666666555555544444444444444443333333333333221100//......--,,,--..//00//..--,,++**)))))**+++++****))((''&&%%%%%%%&&%%$$$$%%%%%%&%%$$$$$$$##""""##$$%%%%%$$##""""""##$$%%%%%%&%%$$##""!!!""####"""""##"""""###"""""""""#""""""###"""""""#""!!!""####"""""""""""""""""!!!``````!!""####"""""""##$$$$$$##""""""###$$##""""##$$$$##"""""""##$$########"""""""""""""""""!!````````!!``````!!!!```!!""####"""""!!!!!!!!!``!!!!!!!`͇`!!""""#""""""""#""###################$$$$$$$%%%%%%%&&&%%&&'''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????>>==<<<<<;;;;;<;<<<<<<====<<;;::9988776667777777666677777777777777777777777766555555444444444444433333322111222332222222222221111122111111110000000000000000////////////////00000//...-.......//00000000//..--,,+++++++++++++,,,,,,,----,,,,,,,,,,,,,,,,,--,,,,,,,--.....--------....-----------..////..-----.-...//00000001111100//..--,,++*****+++**))))(('''''''''''&&&'''''&&&&&&&''''&&&&&&''''(((((()))))(())****))(((())****))))))))))****++++*****++++++,,+,,,,,,,,,--,,++************))((''&&%%$$##""!!`````!!"""!!`Á``````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<;;;::999988999999988999999999999999::::;;<<==>>????????????????????????>>==<<;;::::99998887777777777777666666665555554444444444444444333333333332222221100//..------,,,,,--..////..--,,++**))((())*******))))((''&&%%%$$$%%%%%$$$$$$$$$$%%%$$#######""""""##$$%%%$$##"""!!!""##$$%$$%%%%$$##""!!!!!""##"""""""""!!!""#""!!""!!!"""!!!!"""""!!!!!"""!!!!!""##""!!!!!!!""""!!!!!!```!!""""""!!!!!""##$$$$##""!!!""""####""""""##$$##""!!!!!""########"""""""!!!!!!!!!!!!!!!`ǁ```!!``!!""####""!!"!!!!!`````````````!!!!"""!"!!!""""""#"""""""""####""########$$$$$%%%%%%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<<;;;;;;;;;;;;;;<<<<<<<;;::9988776666666766666666666666666666667766677766555555443333333333333333322111111222211111111111111111111111100000000000000000////////........///////..--------...//////////..--,,++**********+++,,,,,,,--,,++++++,,,,,,,,,,,,,,,,,,,,----.---,,,,,--..---,,,,,,----..//..----------..//000000000000//..--,,++**))***+**))))((''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&''''(((((()))(((())**))(((((())))))(((((()())**************+++++++++++,,,,,,,,++****)))))***))((''&&%%$$##""!!``!!"""!!``!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<;;:::9988888898888888888888888899999999::;;<<==>>??????????????????????>>==<<;;::9999888877777666666666666665555554444444333333333333333322222222222221100//..------,,+++,,--..//..--,,++**))((((())*****))))((''&&%%$$$$$$$%%$$####$$$$$$%$$#######""!!!!""##$$$$$##""!!!!!!""##$$$$$$%$$##""!!```!!""""!!!!!""!!!!!"""!!!!!!!!!"!!!!!!"""!!!!!!!"!!```!!""""!!!!!!!!!!!!!!!!!``!!"""""!!!!!!!""######""!!!!!!"""##""!!!!""####""!!!!!!!""##""""""""!!!!!!!!!!!!!!!!!!!``````!!""####""!!!!!````Ĉ`!!!!"!!!!!!!!"!!"""""""""""""""""""#######$$$$$$$%%%$$%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????>>==<<;;;;;:::::;:;;;;;;<<<<;;::99887766555666666655556666666666666666666666665544444433333333333332222221100011122111111111111000001100000000////////////////................/////..---,-------..////////..--,,++*************+++++++,,,,+++++++++++++++++,,+++++++,,-----,,,,,,,,----,,,,,,,,,,,--....--,,,,,-,---..///////00000//..--,,++**)))))***))((((''&&&&&&&&&&&%%%&&&&&%%%%%%%&&&&%%%%%%&&&&''''''(((((''(())))((''''(())))(((((((((())))****)))))******++*+++++++++,,++**)))))))))))))((''&&%%$$##""!!``!!"""!!````````!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;:::998888778888888778888888888888889999::;;<<==>>????????????????????>>==<<;;::9999888877766666666666665555555544444433333333333333332222222222211111100//..--,,,,,,+++++,,--....--,,++**))(('''(()))))))((((''&&%%$$$###$$$$$##########$$$##"""""""!!!!!!""##$$$##""!!!```!!""##$##$$$$##""!!``!!""!!!!!!!!!```!!"!!``!!```!!!````!!!!!`````!!!``!!""!!```````!!!!```````!!!!!!!!`````!!""####""!!```!!!!""""!!!!!!""##""!!`````!!""""""""!!!!!!!```````````````˔‚`!!""####""!!``!````!!!`!```!!!!!!"!!!!!!!!!""""!!""""""""#####$$$$$$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????>>==<<;;;::::::::::::::;;;;;;;::9988776655555556555555555555555555555566555666554444443322222222222222222110000001111000000000000000000000000/////////////////........--------.......--,,,,,,,,---..........--,,++**))))))))))***+++++++,,++******++++++++++++++++++++,,,,-,,,+++++,,--,,,++++++,,,,--..--,,,,,,,,,,--..////////////..--,,++**))(()))*))((((''&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&&&''''''(((''''(())((''''''((((((''''''('(())))))))))))))***********++++++++**))))((((()))))((''&&%%$$##""!!``!!!!!""!!!!!`@````!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;::999887777778777777777777777778888888899::;;<<==>>??????????????????>>==<<;;::9988887777666665555555555555544444433333332222222222222222111111111111100//..--,,,,,,++***++,,--..--,,++**))(('''''(()))))((((''&&%%$$#######$$##""""######$##"""""""!!````!!""#####""!!```!!""######$##""!!``!!!!`````!!``!!!````!``!!!``!!``!!!!`````````!!!!!!!``!!""""""!!```!!!""!!````!!""""!!``!!""!!!!!!!!````ϒ@@@@@`!!""###""!!````!````!``!!!!!!!!!!!!!!!!!!!"""""""#######$$$##$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????>>==<<;;:::::99999:9::::::;;;;::99887766554445555555444455555555555555555555555544333333222222222222211111100///00011000000000000/////00////////................----------------.....--,,,+,,,,,,,--........--,,++**)))))))))))))*******++++*****************++*******++,,,,,++++++++,,,,+++++++++++,,----,,+++++,+,,,--......./////..--,,++**))((((()))((''''&&%%%%%%%%%%%$$$%%%%%$$$$$$$%%%%$$$$$$%%%%&&&&&&'''''&&''((((''&&&&''((((''''''''''(((())))((((())))))**)*********++**))(((((((((((()((''&&%%$$##""!!!`````````!!!""!!!!`@```!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::::99988777766777777766777777777777777888899::;;<<==>>????????????????>>==<<;;::9988887777666555555555555544444444333333222222222222222211111111111000000//..--,,++++++*****++,,----,,++**))((''&&&''(((((((''''&&%%$$###"""#####""""""""""###""!!!!!!!``!!""###""!!``!!!""#""#####""!!``!!!!``!``!!```````````````!!!!``€ʀ````````!!""""!!````!!!!``!!""!!``!!!!!!!!```@@`!!""##""!!``````!`````````!!!!``!!!!!!!!"""""#########$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????>>==<<;;:::99999999999999:::::::99887766554444444544444444444444444444445544455544333333221111111111111111100//////0000////////////////////////.................--------,,,,,,,,-------,,++++++++,,,----------,,++**))(((((((((()))*******++**))))))********************++++,+++*****++,,+++******++++,,--,,++++++++++,,--............--,,++**))((''((()((''''&&%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%&&&&&&'''&&&&''((''&&&&&&''''''&&&&&&'&''(((((((((((((()))))))))))********))(((('''''((((((''&&%%$$##""!!!!!!!`````!!"""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::9988877666666766666666666666666777777778899::;;<<==>>??????????????>>==<<;;::9988777766665555544444444444444333333222222211111111111111110000000000000//..--,,++++++**)))**++,,--,,++**))((''&&&&&''(((((''''&&%%$$##"""""""##""!!!!""""""#""!!!!!!!!``!!""""""!!``!!!!""""""####""!!```!`````````````„````!!`Å`!!!!!!!``!!``!!!!!``!!!``````!!""##""!!`Ê````Ǐ````````!!!!!!!"""""""###""##$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????>>==<<;;::999998888898999999::::99887766554433344444443333444444444444444444444444332222221111111111111000000//...///00////////////.....//........----------------,,,,,,,,,,,,,,,,-----,,+++*+++++++,,--------,,++**))((((((((((((()))))))****)))))))))))))))))**)))))))**+++++********++++***********++,,,,++*****+*+++,,-------.....--,,++**))(('''''(((''&&&&%%$$$$$$$$$$$###$$$$$#######$$$$######$$$$%%%%%%&&&&&%%&&''''&&%%%%&&''''&&&&&&&&&&''''(((('''''(((((())()))))))))**))((''''''''''''(''&&%%$$##""!!````````!!!!!!!``````!!""##$$%%&&''(())**++,,--..//00112233445566778899:998887766665566666665566666666666666677778899::;;<<==>>????????????>>==<<;;::998877776666555444444444444433333333222222111111111111111100000000000//////..--,,++******)))))**++,,,,++**))((''&&%%%&&'''''''&&&&%%$$##"""!!!"""""!!!!!!!!!!"""!!`````````!!"""""!!````!!"!!"""##"""!!!!`!``````ƆÃ````!!!!!!!``````!!!!!!````````````!!""##""!!`Š``ɖЄ``````!!!!!"""""""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????>>==<<;;::999888888888888889999999887766554433333334333333333333333333333344333444332222221100000000000000000//......////........................-----------------,,,,,,,,++++++++,,,,,,,++********+++,,,,,,,,,,++**))((''''''''''((()))))))**))(((((())))))))))))))))))))****+***)))))**++***))))))****++,,++**********++,,------------,,++**))((''&&'''(''&&&&%%$$####################################$$$$%%%%%%&&&%%%%&&''&&%%%%%%&&&&&&%%%%%%&%&&''''''''''''''((((((((((())))))))((''''&&&&&''''''&&%%$$##""!!`Ɏ`!!!!!!!!`````!!""##$$%%&&''(())**++,,--..//0011223344556677889999887776655555565555555555555555566666666778899::;;<<==>>??????????>>==<<;;::99887766665555444443333333333333322222211111110000000000000000/////////////..--,,++******))((())**++,,++**))((''&&%%%%%&&'''''&&&&%%$$##""!!!!!!!""!!````!!!!!!"!!``!!!!!!!!``!!!!!!""""!!!!!!!!!```È΍```````````````!`````ˉ`!!""##""!!``ō`!!!!!!!"""!!""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????>>==<<;;::99888887777787888888999988776655443322233333332222333333333333333333333333221111110000000000000//////..---...//............-----..--------,,,,,,,,,,,,,,,,++++++++++++++++,,,,,++***)*******++,,,,,,,,++**))(('''''''''''''((((((())))((((((((((((((((())((((((())*****))))))))****)))))))))))**++++**)))))*)***++,,,,,,,-----,,++**))((''&&&&&'''&&%%%%$$###########"""#####"""""""####""""""####$$$$$$%%%%%$$%%&&&&%%$$$$%%&&&&%%%%%%%%%%&&&&''''&&&&&''''''(('((((((((())((''&&&&&&&&&&&&'&&%%$$##""!!``!`````````````!!""##$$%%&&''(())**++,,--..//001122334455667788999988777665555445555555445555555555555556666778899::;;<<==>>????????>>==<<;;::998877666655554443333333333333222222221111110000000000000000///////////......--,,++**))))))((((())**++++**))((''&&%%$$$%%&&&&&&&%%%%$$##""!!!```!!!!!``````!!!!``!!!!!!!``!!``!!!""!!!```````ʍ͍`À`!!""#"""!!``````!!!!!!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>==<<;;::998887777777777777788888887766554433222222232222222222222222222222332223332211111100/////////////////..------....------------------------,,,,,,,,,,,,,,,,,++++++++********+++++++**))))))))***++++++++++**))((''&&&&&&&&&&'''((((((())((''''''(((((((((((((((((((())))*)))((((())**)))(((((())))**++**))))))))))**++,,,,,,,,,,,,++**))((''&&%%&&&'&&%%%%$$##""""""""""""""""""""""""""""""""""""####$$$$$$%%%$$$$%%&&%%$$$$$$%%%%%%$$$$$$%$%%&&&&&&&&&&&&&&'''''''''''((((((((''&&&&%%%%%&&&&&&&%%$$##""!!``````````!``!!""##$$%%&&''(())**++,,--..//0011223344556677889998877666554444445444444444444444445555555566778899::;;<<==>>??????>>==<<;;::998877665555444433333222222222222221111110000000////////////////.............--,,++**))))))(('''(())**++**))((''&&%%$$$$$%%&&&&&%%%%$$##""!!````!!``!!!`````````````!!```!!!!``Ǐʋ`!!""""""!!````!!!``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::998877777666667677777788887766554433221112222222111122222222222222222222222211000000/////////////......--,,,---..------------,,,,,--,,,,,,,,++++++++++++++++****************+++++**)))()))))))**++++++++**))((''&&&&&&&&&&&&&'''''''(((('''''''''''''''''(('''''''(()))))(((((((())))((((((((((())****))((((()()))**+++++++,,,,,++**))((''&&%%%%%&&&%%$$$$##"""""""""""!!!"""""!!!!!!!""""!!!!!!""""######$$$$$##$$%%%%$$####$$%%%%$$$$$$$$$$%%%%&&&&%%%%%&&&&&&''&'''''''''((''&&%%%%%%%%%%%%&&&&%%$$##""!!````````````̀`!```!!""##$$%%&&''(())**++,,--..//001122334455667788999887766655444433444444433444444444444444555566778899::;;<<==>>????>>==<<;;::9988776655554444333222222222222211111111000000////////////////...........------,,++**))(((((('''''(())****))((''&&%%$$###$$%%%%%%%$$$$##""!!````!!!!`````!!`À``!!"""""!!!!`````!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????>>==<<;;::998877766666666666666777777766554433221111111211111111111111111111112211122211000000//.................--,,,,,,----,,,,,,,,,,,,,,,,,,,,,,,,+++++++++++++++++********))))))))*******))(((((((()))**********))((''&&%%%%%%%%%%&&&'''''''((''&&&&&&''''''''''''''''''''(((()((('''''(())(((''''''(((())**))(((((((((())**++++++++++++**))((''&&%%$$%%%&%%$$$$##""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""######$$$####$$%%$$######$$$$$$######$#$$%%%%%%%%%%%%%%&&&&&&&&&&&''''''''&&%%%%$$$$$%%%%%%%&&%%$$##""!!!!!!!```!`’`!!""##$$%%&&''(())**++,,--..//00112233445566778899988776655544333333433333333333333333444444445566778899::;;<<==>>??>>==<<;;::9988776655444433332222211111111111111000000///////................-------------,,++**))((((((''&&&''(())**))((''&&%%$$#####$$%%%%%$$$$$##""!!`````À`````!!!""!!!!!!!``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????>>==<<;;::99887766666555556566666677776655443322110001111111000011111111111111111111111100//////.............------,,+++,,,--,,,,,,,,,,,,+++++,,++++++++****************))))))))))))))))*****))((('((((((())********))((''&&%%%%%%%%%%%%%&&&&&&&''''&&&&&&&&&&&&&&&&&''&&&&&&&''(((((''''''''(((('''''''''''(())))(('''''('((())*******+++++**))((''&&%%$$$$$%%%$$####""!!!!!!!!!!!```!!!!!```````!!!!``````!!!!""""""#####""##$$$$##""""##$$$$##########$$$$%%%%$$$$$%%%%%%&&%&&&&&&&&&''&&%%$$$$$$$$$$$$%%%%&%%%$$##""!!!!!````!!""##$$%%&&''(())**++,,--..//00112233445566778898877665554433332233333332233333333333333344445566778899::;;<<==>>>>==<<;;::998877665544443333222111111111111100000000//////................-----------,,,,,,++**))((''''''&&&&&''(())))((''&&%%$$##"""##$$$$$$$#####""!!!!`ĀNj`!!!!""!!!!!``````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????>>==<<;;::99887766655555555555555666666655443322110000000100000000000000000000001100011100//////..-----------------,,++++++,,,,++++++++++++++++++++++++*****************))))))))(((((((()))))))((''''''''((())))))))))((''&&%%$$$$$$$$$$%%%&&&&&&&''&&%%%%%%&&&&&&&&&&&&&&&&&&&&''''('''&&&&&''(('''&&&&&&''''(())((''''''''''(())************))((''&&%%$$##$$$%$$####""!!````````````````````!!!!""""""###""""##$$##""""""######""""""#"##$$$$$$$$$$$$$$%%%%%%%%%%%&&&&&&&&%%$$$$#####$$$$$$$%%%%%%$$##""""!!``!``!!!""##$$%%&&''(())**++,,--..//00112233445566778887766554443322222232222222222222222233333333445566778899::;;<<==>>==<<;;::998877665544333322221111100000000000000//////.......----------------,,,,,,,,,,,,,++**))((''''''&&%%%&&''(())((''&&%%$$##"""""##$$$$$#####""!!``!``!!!!!!!!````‡`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::998877665555544444545555556666554433221100///0000000////000000000000000000000000//......-------------,,,,,,++***+++,,++++++++++++*****++********))))))))))))))))(((((((((((((((()))))(('''&'''''''(())))))))((''&&%%$$$$$$$$$$$$$%%%%%%%&&&&%%%%%%%%%%%%%%%%%&&%%%%%%%&&'''''&&&&&&&&''''&&&&&&&&&&&''((((''&&&&&'&'''(()))))))*****))((''&&%%$$#####$$$##""""!!`ʌ````!!!!!!"""""!!""####""!!!!""####""""""""""####$$$$#####$$$$$$%%$%%%%%%%%%&&%%$$############$$$$%$$$$$$$##"""!!`‰@@`!!!```!`!!""##$$%%&&''(())**++,,--..//00112233445566778776655444332222112222222112222222222222223333445566778899::;;<<====<<;;::998877665544333322221110000000000000////////......----------------,,,,,,,,,,,++++++**))((''&&&&&&%%%%%&&''((((''&&%%$$##""!!!""#######"""""!!````````!!````!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::998877665554444444444444455555554433221100///////0//////////////////////00///000//......--,,,,,,,,,,,,,,,,,++******++++************************)))))))))))))))))((((((((''''''''(((((((''&&&&&&&&'''((((((((((''&&%%$$##########$$$%%%%%%%&&%%$$$$$$%%%%%%%%%%%%%%%%%%%%&&&&'&&&%%%%%&&''&&&%%%%%%&&&&''((''&&&&&&&&&&''(())))))))))))((''&&%%$$##""###$##""""!!``!!!!!!"""!!!!""##""!!!!!!""""""!!!!!!"!""##############$$$$$$$$$$$%%%%%%%%$$####"""""#######$$$$$$$$$$###""!!``@@@@`!!!!``ō``!!""##$$%%&&''(())**++,,--..//00112233445566777665544333221111112111111111111111112222222233445566778899::;;<<==<<;;::998877665544332222111100000//////////////......-------,,,,,,,,,,,,,,,,+++++++++++++**))((''&&&&&&%%$$$%%&&''((''&&%%$$##""!!!!!""#####"""""!!``!!!``!!````Æ````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::998877665544444333334344444455554433221100//...///////....////////////////////////..------,,,,,,,,,,,,,++++++**)))***++************)))))**))))))))((((((((((((((((''''''''''''''''(((((''&&&%&&&&&&&''((((((((''&&%%$$#############$$$$$$$%%%%$$$$$$$$$$$$$$$$$%%$$$$$$$%%&&&&&%%%%%%%%&&&&%%%%%%%%%%%&&''''&&%%%%%&%&&&''((((((()))))((''&&%%$$##"""""###""!!!!!!``!````!!!!!``!!""""!!````!!""""!!!!!!!!!!""""####"""""######$$#$$$$$$$$$%%$$##""""""""""""####$###########"""!!!````````ǀȀ`!!!``!!""##$$%%&&''(())**++,,--..//00112233445566766554433322111100111111100111111111111111222233445566778899::;;<<<<;;::9988776655443322221111000/////////////........------,,,,,,,,,,,,,,,,+++++++++++******))((''&&%%%%%%$$$$$%%&&''''&&%%$$##""!!```!!"""""""!!!!!!!``````!!!``!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>==<<;;::998877665544433333333333333444444433221100//......./......................//...///..------,,+++++++++++++++++**))))))****))))))))))))))))))))))))(((((((((((((((((''''''''&&&&&&&&'''''''&&%%%%%%%%&&&''''''''''&&%%$$##""""""""""###$$$$$$$%%$$######$$$$$$$$$$$$$$$$$$$$%%%%&%%%$$$$$%%&&%%%$$$$$$%%%%&&''&&%%%%%%%%%%&&''((((((((((((''&&%%$$##""!!"""#""!!!!`!!!````````````!!!``!!""!!``!!!!!!``````!`!!""""""""""""""###########$$$$$$$$##""""!!!!!"""""""############"""!!!!!!!!!```!````!!!````!!""##$$%%&&''(())**++,,--..//0011223344556676655443322211000000100000000000000000111111112233445566778899::;;<<;;::998877665544332211110000/////..............------,,,,,,,++++++++++++++++*************))((''&&%%%%%%$$###$$%%&&''&&%%$$##""!!``!!"""""!!!!!!!!!```ƀ`!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????==<<;;::998877665544333332222232333333444433221100//..---.......----........................--,,,,,,+++++++++++++******))((()))**))))))))))))((((())((((((((''''''''''''''''&&&&&&&&&&&&&&&&'''''&&%%%$%%%%%%%&&''''''''&&%%$$##"""""""""""""#######$$$$#################$$#######$$%%%%%$$$$$$$$%%%%$$$$$$$$$$$%%&&&&%%$$$$$%$%%%&&'''''''(((((''&&%%$$##""!!!!!"""!!````````!!!!!!!!`````@`````!!!!!`Ä`!!!!```!!!!""""!!!!!""""""##"#########$$##""!!!!!!!!!!!!""""#"""""""""""!!!!```!!!!!!!!!``!!!!!!``!!!!""##$$%%&&''(())**++,,--..//0011223344556666554433222110000//0000000//00000000000000011112233445566778899::;;;;::998877665544332211110000///.............--------,,,,,,++++++++++++++++***********))))))((''&&%%$$$$$$#####$$%%&&'&&%%$$##""!!``!!!!!!!````````ǂ``ʏ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????=<<;;::998877665544333222222222222223333333221100//..-------.----------------------..---...--,,,,,,++*****************))(((((())))(((((((((((((((((((((((('''''''''''''''''&&&&&&&&%%%%%%%%&&&&&&&%%$$$$$$$$%%%&&&&&&&&&&%%$$##""!!!!!!!!!!"""#######$$##""""""####################$$$$%$$$#####$$%%$$$######$$$$%%&&%%$$$$$$$$$$%%&&''''''''''''&&%%$$##""!!``!!!"!!`Ў`!!`````!!!!!``````@@@@@@@````!!!!!````````Ƀ`!!!!!!!!!!!!!!"""""""""""########""!!!!`````!!!!!!!""""""""""""!!!```````!!!!!```!!!````````!!""##$$%%&&''(())**++,,--..//001122334455665544332211100//////0/////////////////00000000112233445566778899::;;::9988776655443322110000////.....--------------,,,,,,+++++++****************)))))))))))))((''&&%%$$$$$$##"""##$$%%&&&&%%$$##""!!``!!!!!!``!`Ċ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????<<;;::998877665544332222211111212222223333221100//..--,,,-------,,,,------------------------,,++++++*************))))))(('''((())(((((((((((('''''((''''''''&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%&&&&&%%$$$#$$$$$$$%%&&&&&&&&%%$$##""!!!!!!!!!!!!!"""""""####"""""""""""""""""##"""""""##$$$$$########$$$$###########$$%%%%$$#####$#$$$%%&&&&&&&'''''&&%%$$##""!!```!!!!````````````````@@@@@@@@@@@@@@@@@```````````Ā````!!!!`````!!!!!!""!"""""""""##""!!```````!!!!"!!!!!!!!!!!``````!!``````````````````````````Ώ`!!""##$$%%&&''(())**++,,--..//0011223344555544332211100////..///////..///////////////0000112233445566778899::::9988776655443322110000////...-------------,,,,,,,,++++++****************)))))))))))((((((''&&%%$$######"""""##$$%%&&&&%%$$##""!!````````````!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????<;;::998877665544332221111111111111122222221100//..--,,,,,,,-,,,,,,,,,,,,,,,,,,,,,,--,,,---,,++++++**)))))))))))))))))((''''''((((''''''''''''''''''''''''&&&&&&&&&&&&&&&&&%%%%%%%%$$$$$$$$%%%%%%%$$########$$$%%%%%%%%%%$$##""!!``````````!!!"""""""##""!!!!!!""""""""""""""""""""####$###"""""##$$###""""""####$$%%$$##########$$%%&&&&&&&&&&&&&%%$$##""!!``!!!!`Α΋@@@@@@@@```````!!!!!!!!!!!""""""""!!````!!!!!!!!!!!!``!!!!`````````̒`!!""##$$%%&&''(())**++,,--..//001122334455544332211000//....../.................////////00112233445566778899::99887766554433221100////....-----,,,,,,,,,,,,,,++++++*******))))))))))))))))(((((((((((((''&&%%$$######""!!!""##$$%%&&&%%$$###""!!```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????;;::998877665544332211111000001011111122221100//..--,,+++,,,,,,,++++,,,,,,,,,,,,,,,,,,,,,,,,++******)))))))))))))((((((''&&&'''((''''''''''''&&&&&''&&&&&&&&%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$%%%%%$$###"#######$$%%%%%%%%$$##""!!```!!!!!!!""""!!!!!!!!!!!!!!!!!""!!!!!!!""#####""""""""####"""""""""""##$$$$##"""""#"###$$%%%%%%%&&&&&&&&%%$$##""!!``!!!!`ʆ````!!`!!!!!!!!!""!!``!`````````!``````π`!!""##$$%%&&''(())**++,,--..//00112233445544332211000//....--.......--...............////0011223344556677889999887766554433221100////....---,,,,,,,,,,,,,++++++++******))))))))))))))))(((((((((((''''''&&%%$$##""""""!!!!!""##$$%%&%%$$###""!!``@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????;::998877665544332211100000000000000111111100//..--,,+++++++,++++++++++++++++++++++,,+++,,,++******))(((((((((((((((((''&&&&&&''''&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%$$$$$$$$########$$$$$$$##""""""""###$$$$$$$$$$##""!!``!!!!!!!""!!``````!!!!!!!!!!!!!!!!!!!!""""#"""!!!!!""##"""!!!!!!""""##$$##""""""""""##$$%%%%%%%%%%%%%%%%%$$##""!!```!!""!!````````!!!!!!!!!````!`À``Ȁ`!!""##$$%%&&''(())**++,,--..//001122334454433221100///..------.-----------------........//00112233445566778899887766554433221100//....----,,,,,++++++++++++++******)))))))(((((((((((((((('''''''''''''&&%%$$##""""""!!```!!""##$$%%%$$##"""!!````!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????::99887766554433221100000/////0/000000111100//..--,,++***+++++++****++++++++++++++++++++++++**))))))(((((((((((((''''''&&%%%&&&''&&&&&&&&&&&&%%%%%&&%%%%%%%%$$$$$$$$$$$$$$$$################$$$$$##"""!"""""""##$$$$$$$$$##""!!```````!!!!```````````!!```````!!"""""!!!!!!!!""""!!!!!!!!!!!""####""!!!!!"!"""##$$$$$$$%%%%%%%%%%%%$$##""!!!!!""""!!`@@@@@@@@ǂ`````!!!``ъ`````@@ˉ`````!!""##$$%%&&''(())**++,,--..//001122334454433221100///..----,,-------,,---------------....//001122334455667788887766554433221100//....----,,,+++++++++++++********))))))(((((((((((((((('''''''''''&&&&&&%%$$##""!!!!!!``!!""##$$%$$##"""!!``!!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????:998877665544332211000//////////////0000000//..--,,++*******+**********************++***+++**))))))(('''''''''''''''''&&%%%%%%&&&&%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$########""""""""#######""!!!!!!!!"""############""!!```!!````!!!!"!!!`````!!""!!!``````!!!!""##""!!!!!!!!!!""##$$$$$$$$$$$$$$$$$$$$$##""!!!""#""!!`ɍ```ɉ̊`!!!!!""##$$%%&&''(())**++,,--..//001122334454433221100//...--,,,,,,-,,,,,,,,,,,,,,,,,--------..//0011223344556677887766554433221100//..----,,,,+++++**************))))))(((((((''''''''''''''''&&&&&&&&&&&&&%%$$##""!!!!!!``!!""##$$$##""!!!!`@Ŏ`````!!!!"!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????99887766554433221100/////....././/////0000//..--,,++**)))*******))))************************))(((((('''''''''''''&&&&&&%%$$$%%%&&%%%%%%%%%%%%$$$$$%%$$$$$$$$################""""""""""""""""#####""!!!`!!!!!!!""##########""!!!!```````!!!!!!```!!!!`````!!""""!!`````!`!!!""#######$$$$$$$$$$$$$$$###"""""##""!!`Ƅ͏`!!!!""##$$%%&&''(())**++,,--..//001122334454433221100//...--,,,,++,,,,,,,++,,,,,,,,,,,,,,,----..//00112233445566777766554433221100//..----,,,,+++*************))))))))((((((''''''''''''''''&&&&&&&&&&&%%%%%%$$##""!!``````!!""##$#$##""!!!!!!`Å`!``!!!!!"""""!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????9887766554433221100///..............///////..--,,++**)))))))*))))))))))))))))))))))**)))***))((((((''&&&&&&&&&&&&&&&&&%%$$$$$$%%%%$$$$$$$$$$$$$$$$$$$$$$$$#################""""""""!!!!!!!!"""""""!!```````!!!""""""""""""!!````!```!``````````!```!!`œ`!!""!!````!!""#########################"""####""!!```!!"""##$$%%&&''(())**++,,--..//001122334454433221100//..---,,++++++,+++++++++++++++++,,,,,,,,--..//001122334455667766554433221100//..--,,,,++++*****))))))))))))))(((((('''''''&&&&&&&&&&&&&&&&%%%%%%%%%%%%%$$##""!!``!!""######""!!``````````@@````!!!!!!!!""""#"""!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????887766554433221100//.....-----.-......////..--,,++**))((()))))))(((())))))))))))))))))))))))((''''''&&&&&&&&&&&&&%%%%%%$$###$$$%%$$$$$$$$$$$$#####$$########""""""""""""""""!!!!!!!!!!!!!!!!"""""!!````!!""""""""""!!```!!!!```````!```````````````!!"!!``!!"""""""###############"""""""""""#""!!```!````!!""##$$%%&&''(())**++,,--..//00112233444433221100//..---,,++++**+++++++**+++++++++++++++,,,,--..//0011223344556666554433221100//..--,,,,++++***)))))))))))))((((((((''''''&&&&&&&&&&&&&&&&%%%%%%%%%%%$$$$$$$##""!!````!!""##"#""!!`@@```!!!!!"!!"""""#####"""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????87766554433221100//...--------------.......--,,++**))((((((()(((((((((((((((((((((())((()))((''''''&&%%%%%%%%%%%%%%%%%$$######$$$$########################"""""""""""""""""!!!!!!!!````````!!!!!!!`@`!!!!!!!!!!!!```!!!!!!!!```````!!`À`!````````@@`!!!!``!!""""""""""""""""""""""""""""""""""""!!!!!!!``!!""##$$%%&&''(())**++,,--..//0011223344433221100//..--,,,++******+*****************++++++++,,--..//00112233445566554433221100//..--,,++++****)))))((((((((((((((''''''&&&&&&&%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$##""!!``!!````!!""#""""!!``ǀ`!!!!""""""""####$###"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????7766554433221100//..-----,,,,,-,------....--,,++**))(('''(((((((''''((((((((((((((((((((((((''&&&&&&%%%%%%%%%%%%%$$$$$$##"""###$$############"""""##""""""""!!!!!!!!!!!!!!!!````````!!!!!``@`!!!!!!!!!!!`````````````````````````@```````đ˄`!!!!``!!!!!!!"""""""""""""""!!!!!!!!!!!"!!!!!!!!!!```!!""##$$%%&&''(())**++,,--..//0011223344433221100//..--,,,++****))*******))***************++++,,--..//001122334455554433221100//..--,,++++****)))(((((((((((((''''''''&&&&&&%%%%%%%%%%%%%%%%$$$$$$$$$$$###########""!!!!!!!``!!""""!"!!``!!"""#""#####$$$$$###"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????766554433221100//..---,,,,,,,,,,,,,,-------,,++**))(('''''''(''''''''''''''''''''''(('''(((''&&&&&&%%$$$$$$$$$$$$$$$$$##""""""####""""""""""""""""""""""""!!!!!!!!!!!!!!!!!`ć`````````````````̋````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``````````!!!""##$$%%&&''(())**++,,--..//0011223344433221100//..--,,+++**))))))*)))))))))))))))))********++,,--..//0011223344554433221100//..--,,++****))))(((((''''''''''''''&&&&&&%%%%%%%$$$$$$$$$$$$$$$$###################"""!!""!!!````!!""""!!!!````!!""########$$$$%$$$#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????66554433221100//..--,,,,,+++++,+,,,,,,----,,++**))((''&&&'''''''&&&&''''''''''''''''''''''''&&%%%%%%$$$$$$$$$$$$$######""!!!"""##""""""""""""!!!!!""!!!!!!!!``````````````!`ˋӑ@„`````````!!!!!!!!!!!!!!!```````````!````!``````!!!```Ƈ`!`!!!!""##$$%%&&''(())**++,,--..//0011223344433221100//..--,,+++**))))(()))))))(()))))))))))))))****++,,--..//00112233444433221100//..--,,++****))))((('''''''''''''&&&&&&&&%%%%%%$$$$$$$$$$$$$$$$###########""""""""""""""""""""!!!!!!!"""!!`!````````````!!""##$##$$$$$%%%%%$$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????6554433221100//..--,,,++++++++++++++,,,,,,,++**))((''&&&&&&&'&&&&&&&&&&&&&&&&&&&&&&''&&&'''&&%%%%%%$$#################""!!!!!!""""!!!!!!!!!!!!!!!!!!!!!!!!```ѓ```````````````````!!!`@````!!!!"""##$$%%&&''(())**++,,--..//0011223344433221100//..--,,++***))(((((()((((((((((((((((())))))))**++,,--..//001122334433221100//..--,,++**))))(((('''''&&&&&&&&&&&&&&%%%%%%$$$$$$$################"""""""""""""""""""!!!""""""!!!!!!!!!!!```!!``!!!!!!!!""##$$$$$$$$%%%%&%%%$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????554433221100//..--,,+++++*****+*++++++,,,,++**))((''&&%%%&&&&&&&%%%%&&&&&&&&&&&&&&&&&&&&&&&&%%$$$$$$#############""""""!!```!!!""!!!!!!!!!!!!`````!!``````ˇŀɎʈ````!```!`!!!""""##$$%%&&''(())**++,,--..//0011223344433221100//..--,,++***))((((''(((((((''((((((((((((((())))**++,,--..//0011223333221100//..--,,++**))))(((('''&&&&&&&&&&&&&%%%%%%%%$$$$$$################"""""""""""!!!!!!!!!!!!!!!!!!!!!!`````!!!```!!!```!!!!!!!!""##$$%$$%%%%%&&&&&%%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????54433221100//..--,,+++**************+++++++**))((''&&%%%%%%%&%%%%%%%%%%%%%%%%%%%%%%&&%%%&&&%%$$$$$$##"""""""""""""""""!!```!!!!`````````````€̀`!!!!!!!""""###$$%%&&''(())**++,,--..//0011223344433221100//..--,,++**)))((''''''('''''''''''''''''(((((((())**++,,--..//00112233221100//..--,,++**))((((''''&&&&&%%%%%%%%%%%%%%$$$$$$#######""""""""""""""""!!!!!!!!!!!!!!!!!!!```!!!!!!```````!!!!!!!""""""""##$$%%%%%%%%&&&&&&&&%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????4433221100//..--,,++*****)))))*)******++++**))((''&&%%$$$%%%%%%%$$$$%%%%%%%%%%%%%%%%%%%%%%%%$$######"""""""""""""!!!!!!``!!`ˊ``!!!!"!"""####$$%%&&''(())**++,,--..//0011223344433221100//..--,,++**)))((''''&&'''''''&&'''''''''''''''(((())**++,,--..//001122221100//..--,,++**))((((''''&&&%%%%%%%%%%%%%$$$$$$$$######""""""""""""""""!!!!!!!!!!!`````````````````̄`!!!!!""""""""##$$%%$$$%%%%%%%%%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????433221100//..--,,++***))))))))))))))*******))((''&&%%$$$$$$$%$$$$$$$$$$$$$$$$$$$$$$%%$$$%%%$$######""!!!!!!!!!!!!!!!!!!`````````!!""""""####$$$%%&&''(())**++,,--..//0011223344433221100//..--,,++**))(((''&&&&&&'&&&&&&&&&&&&&&&&&''''''''(())**++,,--..//0011221100//..--,,++**))((''''&&&&%%%%%$$$$$$$$$$$$$$######"""""""!!!!!!!!!!!!!!!!````````͍̊`!!""""########$$%$$$$$$%%%%%%%%%%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????33221100//..--,,++**)))))((((()())))))****))((''&&%%$$###$$$$$$$####$$$$$$$$$$$$$$$$$$$$$$$$##""""""!!!!!!!!!!!!!````!!`ѐ````!!!!!""""#"###$$$$%%&&''(())**++,,--..//0011223344433221100//..--,,++**))(((''&&&&%%&&&&&&&%%&&&&&&&&&&&&&&&''''(())**++,,--..//00111100//..--,,++**))((''''&&&&%%%$$$$$$$$$$$$$########""""""!!!!!!!!!!!!!!!!```ϑ`!!"""########$$%$$$###$$$$$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????3221100//..--,,++**)))(((((((((((((()))))))((''&&%%$$#######$######################$$###$$$##""""""!!```````````````````!!!!!!!!""######$$$$%%%&&''(())**++,,--..//0011223344433221100//..--,,++**))(('''&&%%%%%%&%%%%%%%%%%%%%%%%%&&&&&&&&''(())**++,,--..//001100//..--,,++**))((''&&&&%%%%$$$$$##############""""""!!!!!!!`````````````ɐ`!!""##$$$$$$$$%$$######$$$$$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????221100//..--,,++**))((((('''''('(((((())))((''&&%%$$##"""#######""""########################""!!!!!!`Ł`````````!!!!!!!!!"""""####$#$$$%%%%&&''(())**++,,--..//0011223344433221100//..--,,++**))(('''&&%%%%$$%%%%%%%$$%%%%%%%%%%%%%%%&&&&''(())**++,,--..//0000//..--,,++**))((''&&&&%%%%$$$#############""""""""!!!!!!```Г`!!""##$$$$$$$$%$$###"""#############$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????21100//..--,,++**))(((''''''''''''''(((((((''&&%%$$##"""""""#""""""""""""""""""""""##"""###""!!!!!!!```````!!!!!!!!!!!!!!""""""""##$$$$$$%%%%&&&''(())**++,,--..//0011223344433221100//..--,,++**))((''&&&%%$$$$$$%$$$$$$$$$$$$$$$$$%%%%%%%%&&''(())**++,,--..//00//..--,,++**))((''&&%%%%$$$$#####""""""""""""""!!!!!!````ǁ`!!""##$$$%%%%$$##""""""#############$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????1100//..--,,++**))(('''''&&&&&'&''''''((((''&&%%$$##""!!!"""""""!!!!""""""""""""""""""""""""!!````````````````!!!!!!!!!!!!!!!"""""""""#####$$$$%$%%%&&&&''(())**++,,--..//0011223344433221100//..--,,++**))((''&&&%%$$$$##$$$$$$$##$$$$$$$$$$$$$$$%%%%&&''(())**++,,--..////..--,,++**))((''&&%%%%$$$$###"""""""""""""!!!!!!!!``Ɔ`!!""##$$$$%%$$##"""!!!"""""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????100//..--,,++**))(('''&&&&&&&&&&&&&&'''''''&&%%$$##""!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!""!!!"""!!```@`!!!!!!!!!!!!!!""""""""""""""########$$%%%%%%&&&&'''(())**++,,--..//0011223344433221100//..--,,++**))((''&&%%%$$######$#################$$$$$$$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$$$####"""""!!!!!!!!!!!!!!`````!!"""####$$$$##""!!!!!!"""""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????00//..--,,++**))((''&&&&&%%%%%&%&&&&&&''''&&%%$$##""!!```!!!!!!!````!!!!!!!!!!!!!!!!!!!!!!!!!!`@@````````````!!!!!!!!!"""""""""""""""#########$$$$$%%%%&%&&&''''((()))**++,,--..//00112233433221100//..--,,++**))((''&&%%%$$####""#######""###############$$$$%%&&''(())**++,,--....--,,++**))((''&&%%$$$$####"""!!!!!!!!!!!!!````Ǎ``!!!""####$$##""!!!```!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????0//..--,,++**))((''&&&%%%%%%%%%%%%%%&&&&&&&%%$$##""!!````!``````````````````!!```!!!```@@@````!`!!!!!!``````````````````````````!!""""""""""""""##############$$$$$$$$%%&&&&&&''''((((((())**++,,--..//001122333221100//..--,,++**))((''&&%%$$$##""""""#"""""""""""""""""########$$%%&&''(())**++,,--..--,,++**))((''&&%%$$####""""!!!!!``````````є`!!!""""####""!!```!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????//..--,,++**))((''&&%%%%%$$$$$%$%%%%%%&&&&%%$$##""!!``ƍ`````ɇ@@``!`````!`!!!!!!!!!!!!!!!!!!!!!!!!!"""""""""###############$$$$$$$$$%%%%%&&&&'&'''(((('''((())**++,,--..//0011223221100//..--,,++**))((''&&%%$$$##""""!!"""""""!!"""""""""""""""####$$%%&&''(())**++,,----,,++**))((''&&%%$$####""""!!!`````!!""""##""!!``````````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????/..--,,++**))((''&&%%%$$$$$$$$$$$$$$%%%%%%%%$$##""!!`@@@``````````!!!!!!!!!!!!!!!!""############""""##$$$$$$$$$$%%%%%%%%&&'''''''''''''''''(())**++,,--..//00112221100//..--,,++**))((''&&%%$$###""!!!!!!"!!!!!!!!!!!!!!!!!""""""""##$$%%&&''(())**++,,--,,++**))((''&&%%$$##""""!!!!``À`!!!!"""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????..--,,++**))((''&&%%$$$$$#####$#$$$$$$%%%%%%$$##""!!`@@@‚`!!""""""""""""""#########"""""""""##$$$$%%%%%%%%%&&&&&''''(''''''''&&&'''(())**++,,--..//001121100//..--,,++**))((''&&%%$$###""!!!!``!!!!!!!``!!!!!!!!!!!!!!!""""##$$%%&&''(())**++,,,,++**))((''&&%%$$##""""!!!!```!!!!""!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????.--,,++**))((''&&%%$$$##############$$$$$$$$$##""!!`@@`!!"""""""""""""####""""""""""!!!!""##$$%%%%%%&&&&&&&&''((((''&&&&&&&&&&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##"""!!````!```````````````!!!!!!!!""##$$%%&&''(())**++,,++**))((''&&%%$$##""!!!!```````!!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????--,,++**))((''&&%%$$#####"""""#"######$$$$$$##""!!`ˇĆ`!!""###########""""""""""!!!!!!!!!""##$$%%&&&&&&&'''''((((''&&&&&&&%%%&&&''(())**++,,--..//00100//..--,,++**))((''&&%%$$##"""!!```ʌ`````!!!!""##$$%%&&''(())**++++**))((''&&%%$$##""!!!!`Ą`!!``!!```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????-,,++**))((''&&%%$$###""""""""""""""##########""!!`Å`!!""#######"""""""""!!!!!!!!!!````!!""##$$%%&&''''''''((((''&&%%%%%%%%%%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$##""!!!!`ʌ```!!""##$$%%&&''(())**++**))((''&&%%$$##""!!```````````@``````!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????,,++**))((''&&%%$$##"""""!!!!!"!""""""#########""!!```À`````````````!!""#####""""""""!!!!!!!!!!`````!!""##$$%%&&'''(((((((''&&%%%%%%%$$$%%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!!```!!""##$$%%&&''(())****))((''&&%%$$##""!!``Ä`!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????,++**))((''&&%%$$##"""!!!!!!!!!!!!!!""""""""####""!!!!````@@`!!!!``````````````!!!!!""###""""""!!!!!!!!!``````€`!!""##$$%%&&''((((((''&&%%$$$$$$$$$$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**))((''&&%%$$##""!!``!!!!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????++**))((''&&%%$$##""!!!!!`````!`!!!!!!"""""""""##""!!!!!!!`````Ώ`!!!!!!!!`!``!!!!!!!!!!!""###""""!!!!!!!!````ǀ`!!""##$$%%&&''(()((''&&%%$$$$$$$###$$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())*))((''&&%%$$##""!!```!!""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????+**))((''&&%%$$##""!!!````````!!!!!!!!"""""#""""!!!!!!!`@`!!"!!!!``!!!!!!!!!"""""###""!!!!!!`````Ʌ```!!""##$$%%&&''(()((''&&%%$$###########$$%%&&''(())**++,,--...--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())*))((''&&%%$$##""!!`Ā`!!""""#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????**))((''&&%%$$##""!!``Ȉ``!!!!!!!!!"""#"""""""!!!`€@@@@`!!!!!!!``!!"""""""""""###""!!!!```Ç`!!!!"""##$$%%&&''((((''&&%%$$#######"""###$$%%&&''(())**++,,--.--,,++**))((''&&%%$$###""!!``!!""##$$%%&&''(())))((''&&%%$$##""!!````````````!!""#######$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????*))((''&&%%$$##""!!```````!!!!!""###""""""!!```@@@@@```````!!!!!``!!"""""""######""!!```ċ````!!!"""""##$$%%&&''((''&&%%$$##"""""""""""##$$%%&&''(())**++,,---,,++**))((''&&%%$$###""!!``!!""##$$%%&&''(())((''&&%%$$##""!!````````!!!!!!!!!!``````!!""####$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????))((''&&%%$$##""!!````!!!""######"""!!!!```````@@````!!`!!""###########""!!`Ë`!!!!!!""##$$%%&&''''&&%%$$##"""""""!!!"""##$$%%&&''(())**++,,-,,++**))((''&&%%$$##""""!!``!!""##$$%%&&''((((''&&%%$$##""!!````````!``!!!!!!!!!!!!!!!!!!!!!""##$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????))((''&&%%$$##""!!```!!""#######""!!!!!!!!!!````````````@@@`!!!""#######$$##""!!```!!!!!!!""##$$%%&&''&&%%$$##""!!!!!!!!!!!""##$$%%&&''(())**++,,,++**))((''&&%%$$##""""!!!``!!""##$$%%&&''((''&&%%$$##""!!`‚@@@@@@``````!!!!!!!!!!!!""""""""""!!!!!!""##$$$$%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????*))((''&&%%$$##""!!``!!""##$$###""""!!!!!!!!!!!!!!!!!!`!````!!""##$$$$$$$##""!!```````````!!""##$$%%&&&&%%$$##""!!!!!!!```!!!""##$$%%&&''(())**++,++**))((''&&%%$$##""!!!!!!````!!""##$$%%&&''(((''&&%%$$##""!!`````````````@@@@@`!!!!!!!!!!"!!"""""""""""""""""""""##$$%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????**))((''&&%%$$##""!!````!!""##$$$##""!!```````!!!!!!!!!!!!!!!``````À`!!""##$$$$$$$##""!!``!!!``!!""##$$%%&&%%$$##""!!````````!!""##$$%%&&''(())**+++**))((''&&%%$$##""!!!!```…`!!""##$$%%&&''((((''&&%%$$##""!!!!!``!```````````!!!!!!`@@`!!!!!""""""""""""##########""""""##$$%%%%&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????+**))((''&&%%$$##""!!!!```!!""##$##""!!```````!!""!"!!!!!!!!!````````!!""##$$%%%%%$$##""!!``!!!!!`````!!""##$$%%%%$$##""!!`Ƃ`!!""##$$%%&&''(())**+**))((''&&%%$$##""!!```†`!!""##$$%%&&''(()((''&&%%$$##""!!!!!!!!!!!!!!!!!!!!!!!!`````!!"""""""#""#####################$$%%&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????++**))((''&&%%$$##""!!!!`@@@@@@`!!""##$$$##""!!``!!""""""!!!!!!!!!!!!`!```!!""##$$%%%%%%%$$##""!!````````````!!"""!!!!!`````!!""##$$%%$$##""!!``!!""##$$%%&&''(())****))((''&&%%$$##""!!``!!""##$$%%&&''(())((''&&%%$$##"""""!!"!!!!!!!!!!!"""""!!```@@@@@@@@@@@@@@@@@@@@@@`!!""###########$$$$$$$$$$######$$%%&&&&'''''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????? \ No newline at end of file diff --git a/tests/testdata/maps/world/map16x.bin b/tests/testdata/maps/world/map16x.bin new file mode 100644 index 000000000..a064ee73e --- /dev/null +++ b/tests/testdata/maps/world/map16x.bin @@ -0,0 +1 @@ +-,,++++********)))*******************+++++++++++++*****))((''&&%%%%%%%%$%%%$$$$$$$%%%%$$#####$$$$##"""""""""!!!!!!!!!!!!!!```````````````````!`!!!!""!!!!!!!!!!!!!!!!!!!!````````````````!!!""!!!!!!!!!!""##$$%%&&''(())****))((''&&%%$$###########"""""#"#""""##$$%%&&''(())***))((''&&%%$$##"""###"""""!!"""""##$$%%%%%%&&''(())())((()((((('''&&%%$$##"""""""""###$#####$$%%%%%%%%%%&&''(((((((((((''(((((())*)))((''&&&&&&&&&&&&''(()))))****)))))***++++++++++*++++*******++++++++,,,,-------..,,++++****))))))))))))))))))**************++**********))((''&&%%%%%$$$$$$%$$#$###$$%%$$########$##"""!!!!!"!!!!!!`````````````aaa!!!!````````!!``````Ϗ``a!!!!!!!!!!!!!""##$$%%&&''(())**))((''&&%%$$##"""""""""""""""""""""""##$$%%&&''(())*))((''&&%%$$##""!""#""!!"!!!!"!!""##$$%%$$%%&&''(((((((((((''''''&&%%$$##"""!!!!!!"""########$$$%%%%%%%%%&&'''''''((((''''''''(()))(((''&&%%%%%%%%%%&&''((())))))))))))))*************++*************++++++,,,,,,,--.,++****))))))))((()))))))))))))))))))*************)))))((''&&%%$$$$$$$$#$$$#######$$$$##"""""####""!!!!!!!!!`````Ԗ`aa``````ҍ@@`a!``````````!!""##$$%%&&''(())))((''&&%%$$##"""""""""""!!!!!"!"!!!!""##$$%%&&''(()))((''&&%%$$##""!!!"""!!!!!``a!!!!""##$$$$$$%%&&''(('(('''('''''&&&%%$$##""!!!!!!!!!"""#"""""##$$$$$$$$$$%%&&'''''''''''&&''''''(()(((''&&%%%%%%%%%%%%&&''((((())))((((()))**********)****)))))))********++++,,,,,,,--++****))))(((((((((((((((((())))))))))))))**))))))))))((''&&%%$$$$$######$##"#"""##$$##""""""""#""!!!`````a`ˌ```````ӗ֕˅```a!""##$$%%&&''(())((''&&%%$$##""!!!!!!!!!!!!!!!!!!!!!!!""##$$%%&&''(()((''&&%%$$##""!!`a!"!!``a``a``aabbcc$$##$$%%&&'''''''''''&&&&&&%%$$##"ba!!``````!!!""""""""###$$$$$$$$$%%&&&&&&&''''&&&&&&&&''((('''&&%%$$$$$$$$$$%%&&'''(((((((((((((()))))))))))))**)))))))))))))******+++++++,,-+**))))(((((((('''((((((((((((((((((()))))))))))))(((((''&&%%$$########"###"""""""####""!!!!!""""!!`````@@@@@`````a`ғ̈́`````a!""##$$%%&&''(())((''&&%%$$##""!!!!!!!!!!!`````!`!````!!""##$$%%&&''(((''&&%%$$#cbbaa``a!!`````aabbcc####$$%%&&''&''&&fgf&&&&%%%$$##""aa```a!!"!!!!!""##########$$%%&&&&&&&&&&&%%&&&&&&''('''&&%%$$$$$$$$$$$$%%&&'''''(((('''''((())))))))))())))((((((())))))))****+++++++,,**))))((((''''''''''''''''''(((((((((((((())((((((((((''&&%%$$#####""""""#""!"!!!""##""!!!!!!!aba!`ōҍ@@@Ȁ``a!aaa`Ĉ@``a!!!!!""##$$%%&&''(())((''&&%%$$##""!!`````````````!!""##$$%%&&''(((''&&%%$$ccbbaa`aabaa``a```aa``a!""####""##$$%%&&&&&&&&&&&%%%%%%$$##""!!````a!!!!!!!"""#########$$%%%%%%%&&&&%%%%%%%%&&'''&&&%%$$##########$$%%&&&''''''''''''''((((((((((((())((((((((((((())))))*******++,*))((((''''''''&&&'''''''''''''''''''((((((((((((('''''&&%%$$##""""""""!"""!!!!!!!""""!a`````!!ab!!````@͏`````!!!`````͑``a!!!!!!""##$$%%&&''(())((''&&%%$$##""!!`@```````a!""##$$%%&&''(()((''&&%%$$##""!!ab""!!!!!!!aa!!!""""""""""##$$%%&&%ffe%%&%%%%%$$$$###""!a````a`````!!""""""""""##$$%%%%%%%%%%%$$%%%%%%&&'&&&%%$$############$$%%&&&&&''''&&&&&'''(((((((((('(((('''''''(((((((())))*******++))((((''''&&&&&&&&&&&&&&&&&&''''''''''''''((''''''''''&&%%$$##"""""!!!!!!"!!`a```a!""!!```!!a```aa``ȇ͓`!!`````ؘ```aaa!""""""##$$%%&&''(()))((''&&%%$$##""!!`ʀ````a!!!!""##$$%%&&''(((((((''&&%%$$##""!""#""!!"!!!""!!""""""""!!""##$$%%%%%%%%%%%$$$$$$$#####""!!`a!```````a``a!!"""""""""##$$$$$$$%%%%$$$$$$$$%%&&&%%%$$##""""""""""##$$%%%&&&&&&&&&&&&&&'''''''''''''(('''''''''''''(((((()))))))**+)((''''&&&&&&&&%%%&&&&&&&&&&&&&&&&&&&'''''''''''''&&&&&%%$$##""!!!!!!!!`!!a```!!""!!``````a``!!````````@̋``!!`ɑ```aa"""""""##$$%%&&''(())*))((''&&%%$$##""!!````ŀ`````!!!!""##$$%%&&''''''(((((''&&%%$$##"""###"""""""""""!"!!!!!!!!!""##$$%%$%%$$$%$$$$$####"""""""!!!a!!!!!!!aa`````a`aaa!!!!!!!""##$$$$$$$$$$$##$$$$$$%%&%%%$$##""""""""""""##$$%%%%%&&&&%%%%%&&&''''''''''&''''&&&&&&&''''''''(((()))))))**((''''&&&&%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&&&''&&&&&&&&&&%%$$##""!!!!!`````!aa`a```a!!!!baa!!aa``a!!```aaa!``!``@Γ````a!!!!`ą`aa""#####$$%%&&''(())***))((''&&%%$$##""!!!!!`ɋ`a!!!```a!"""##$$%%&&&&&&''''''(((''&&%%$$##"##$##""""""!!!!!!!!!!!!``!!""##$$$$$$$$$$$#######"""""b""aa!!!!!!!!!aa``````a!!!!!!!!""#######$$$$########$$%%%$$$##""!!!!!!!!!!""##$$$%%%%%%%%%%%%%%&&&&&&&&&&&&&''&&&&&&&&&&&&&''''''((((((())*(''&&&&%%%%%%%%$$$%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&&%%%%%$$##""!!````````!!!!!``!!!!aa``!``````!``a!``````a!!!!""!!``ΏΐΎ`````!!""###$$%%&&''(())**+**))((''&&%%$$##""!!!!!```a!!!!!!`a!"""##$$%%%%&&&&&&&&''''((''&&&%%$$###$$##"""!!!!!!!`!```````!!""##$$#$$###$#####""""!!!aa!!!!!!````a!```ȃʈ````````!!""###########""######$$%$$$##""!!!!!!!!!!!!""##dd$$$%%%%$$$d$%%%&&&&&&&&&&%&&&&%%%%%%%&&&&&&&&''''((((((())''&&&&%%%%$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%&&%%%%%%%%%%$$##""!!``````````!````a!```!``aa````````````````aa!!"""""!!!``````````Ɠ``a!""##$$$%%&&''(())**+++**))((''&&%%$$##"""""!!!`a!""""!!!!"b###$$$$%%%%%%%%&&&&&&''''&&&&&%%$$#$$##"""!!!!````````a!""#############"bbb"""!!!!!!!!``````lj`!!"""""""####""""""""##$$$###""!!``````````!!""#cc$$$$d$$$$$$$$$%%%%%%%%%%%%%&&%%%%%%%%%%%%%&&&&&&'''''''(()'&&%%%%$$$$$$$$###$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%$$$$$$##""!!!````aaa````aa``a```a```a`NJ```````aa!"""""##""!!!!!``a`!!!!!!```Ɏ`a!""##$$%%&&''(())**++,++**))((''&&%%$$##"""""!!!!"""""""!""###$#$$$$$$%%%%%%%%&&&&''&&%%&&&%%$$$##""!!!````a`````a!!!"""""###"##"""#""bbb!!!!```````ʈȋ`!!"""""""""""!!""""""##$###""aa``!abbcc###$$$$#####$$$%%%%%%%%%%$%%%%$$$$$$$%%%%%%%%&&&&'''''''((&&%%%%$$$$##################$$$$$$$$$$$$$$%%$$$$$$$$$$$##""!!``````!!!a`````a`````a!aa!!!!````a``!```a!!!""""##"""!!!!!!!!!!!!!!!!```aab"##$$%%&&''(())**++,,,++**))((''&&%%$$#####"""!""####""""#########$$$$$$$$%%%%%%&&&&%%%%&%%$$$##""!!!```a!!!!!!!!!""!!"""""""""""""!aa!!!a`lj``!!!!!!!!!""""!!!!!!!!""###"##""!a``````````a!bbbbbccc###########$$$$$$$$$$$$$%%$$$$$$$$$$$$$%%%%%%&&&&&&&''(&%%$$$$########"""###################$$$$$$$$$$$$$######""!!``````!!!````a!!!!!``!!!!!!`````a!`````````````````a`````!!!!!!""""""""""!!"!""""""!!!!a``aab"##$$%%&&''(())**++,,-,,++**))((''&&%%$$#####""""#######"###"##"######$$$$$$$$%%%%&&%%$$%%%$$$##""!!``Ʌ``a!!"!!!!!""""!!!!!"""!""!!!b!!!aa````````a!!`a!!!!!!!!!!``!!!!!!""#"""""b"!!!a```!!!!!!!!"""""####"""""###$$$$$$$$$$#$$$$#######$$$$$$$$%%%%&&&&&&&''%%$$$$####""""""""""""""""""##############$$###########"""!!`lj```!!!!!!!!```a!!```a``a`````````a``!!!!"""""""""""""""""""""!!!`Ȑ`a!""##$$%%&&''(())**++++,,-,,++**))((''&&%%$$$$$###"########"""""""""""########$$$$$$%%%%$$$$%$$###""!!```!!!!""""""""""!!``a!!!!!aa!!!!!````Å@@@`````````!!!!``````!!"""!""""b"!!!a``a!!!!!!!!""""""""""""""#############$$#############$$$$$$%%%%%%%&&'%$$####""""""""!!!"""""""""""""""""""#############"""""""!!`Lj````````````Lj`a!```Ń``````!```͐@@```!!!!!!""""""#"######""""!!```a!""##$$%%&&''(())**++++++,,-,,++**))((''&&%%$$$$$#####""""""""""!""!""""""########$$$$%%$$##$$$###""!!`ό``a!!!"""#""""""!!!```!!a`!a```a`ȆÄƄ````ɇ`a!"!!!!!!!!!!!````````````!!!!!""""!!!!!"""##########"####"""""""########$$$$%%%%%%%&&$$####""""!!!!!!!!!!!!!!!!!!""""""""""""""##"""""""""""!!!`ˋ```͋``ň`!!!`a`ł```!!!!`ɉ``Ȋ@φ``!!!!!!!!""##########""!!`ď`a!""##$$$%%&&''(())**+++**++,,,++**))((''''&&%%%$$##"#""""""""!!!!!!!!!!!""""""""######$$$$####$##"""!!`ˌ`!!!!""""""""""!!!`ă`````````ƅ@`!!!`!!!!!!!!```a!!!!!!!!!!!!!"""""""""""""##"""""""""""""######$$$$$$$%%&$##""""!!!!!!!!```!!!!!!!!!!!!!!!!!!!"""""""""""""!!!!!!!!a````a!`Ć`!!!!!````a``!!!!`lj````!!!!!""#####$$###""!!```ʈ`!!""##$$$%%&&''(())**+****++,++**))((''''&&&%%$$##"""""!!!!!!!!!!`!!`!!!!!!""""""""####$$##""###""""!a`Ĉ`!!!!!"!!"""""!!``Ą``````!!``````````Ã```!!!!`````!!!""""""""""!""""!!!!!!!""""bbbbc###$$$$$$$%%##""""!!!!```````````````!!!!!!!!!!!!!!""!!!!!!!!!!!`!!!!!!```a!!!`Ç```!!!!!`a!`э``!!!`LJɋˍ````!!"""####$$$##""!!````˃```!!""##$#$$%%&&''(())***))**+++**))((''&&&&&%%$$##""!"!!!!!!!!`````````!!!!!!!!""""""####""""#""!"""!a```a!`!!!!!!!!!!`Ä``Ã``ńŅ``````!a!!!!!!!!!!!""!!!!!!!!!!!aabbbb""#######$$%#""!!!!```Ņ`````````!!!!!!!!!!!!!``````!!!a!!``!!!!!``@@@@ˈLj`aaa!!`!`DŽ`!!!````````͌`!!"""""##$$##""!!`@ٝ````a!""#####$$%%&&''(())*))))**+**))((''&&&&%%%$$##""!!!!!``````яˊ```!!!!!!!!""""##""!!"""!!!""!!!!```aa``a``!!!!!!`ă``ăƆÅ`!!!!!!!!!!`!!!a```````!!!!!!!!""""#######$$""!!!!`Ό`````!!``````ċ``````````!a`Ƈ`ą`a!!``````‡``!`!!```````````a``!!!""""##$##""!!```ϑޕ`a`!!""####"##$$%%&&''(()))(())***))((''&&%%%%%$$##""!!`!``͍`````!!!!!!""""!!!!"!!`a!!!!!!!!!!!!`a``````!a``ă``Ą````````````aa``````!!!!!!"""""""##$"!a```͏``ɊА``````````````aa``!`É``a!!``!aaaa``ƌ``a!!!!!""##$##""!!`````ՔՌ``a!!!"""""""""##$$%%&&''(()(((())*))((''&&%%%%$$$##""!!``ΐ```!!!!""!!``!!!``a!````a``````a`Æ```a`Ä`aa``@ăϐ```Ĉ```!!!!"""""""##!a`ȊӒ`a``````a``````a``!``a``Ɍ``!``̌`a!!aa!`````Ƈ```!!!!""##$##""!!`Ë```````!!!"!""""""""!""##$$%%&&''(((''(()))((''&&%%$$$$$###""aa`Б```!!!!``a!!``````Lj`Ą`a`Ã@ÄɊ```!!!!!!!""#"!!```ʇ````````Ć``ɉ͎``Ɋ`!!!!```a`Ņ```!!""###""!!`ω``a``a!!!!!!!""!!"!!!!!!!!""##$$%%&&''(''''(()((''&&%%$$$$####""aa`Ė`!!!``aaa`ăȇƇŃ`a!`ÃÄ`a!!!!!!""!!!`````‚Ϗ˃ȉLjƌÆNj`a!""!!```a!``Äɐ`!!""##""!!``a!!!!!!!!!!"""!!!!!!!!!!`!!""##$$%%&&'''&&''(((''&&%%$$#####"""!!`ӑʉ```a````Ň`a``Ņ``````!!"!`````ʊ@``a!""""!!!!!`Ƅ``a!""##""!!`ё``a!!"!!""""""""!a``!```````a!""##$$%%&&'&&&&''(''&&%%$$####""""!!`ϓLJ``````````Ąƅ``Ņˆ`a!`ŇȈ```aa!!"""!!`````ʼn`````a!""####""!!``̓`````a!!""""""""""""!a``Ϗ`a!""##$$%%&&&%%&&'''&&%%$$##"""""!!!`җ````Ɔ`!!!````ƉăÃ```Ō`aa"a```ō```!!"!!`ȇ````a!!""##$$##""!!`͊``!!!!!!!"""#""#####""!a`ņђ`a!""##$$%%&%%%%&&'&&%%$$##""""!!!!`̒``a!!`ƈ`aaaa```ć`aa``a``a!""!!````````Ȋ`a`Ą`!!"!a``````ˍ`!a!""##$$$##""!!``!!!!!!"""###########""aa`Ȕ``a!""##$$%%&%%$$%%&&&%%$$##""!!!!!``ȓ`!!``LJ```a`Ƅ``a!!!!!!`````a!""#"!!!!`!```Ѕ````aaa``````a!!aaa!!!!``͊`!!""##$$$$##""!!`Ԕ`!!""""""###$##$$$$$##""!a``````a!!""##$$%%&%%$$$$%%&%%$$##""!!!!``ˎ``a``Ɉ`ń`!!"!!"!!!!!!!bbc#""!!``Â`!!!!"!a`a`aa`a!!a``a!!`!!a`@`a!""##$$%%$$##""!!``ԙ`a!"""""###$$$$$$$$$$$##""!!!a```!!!!!""##$$%%&%%$$##$$%%%$$##""!!```ј``a!`NJɈDž`!!""""!!!!!"bccd"!!`ÄŃ``a!!!"""!!``a!!aa``````!!`````aa""##$$%%%%$$##""!!a`ɖ`!!""######$$$%$$%%%%%$$##""!!!!!!!!!"""##$$%%&%%d$####$$%$$##""!!`֑`a!!`ƇŎ`ȇ````a!"""#"""""""##$$!!`DŽ``a!!""""#""!!`a!!"ba!`̎`!!!!```aaa""##$$%%%&%%$$##""!!`Ґ`a!""#####$$$%%%%%%%%%%%$$##""""!!!"""""##$$%%&%%dd##""##$$$##""!!`̐`a!!!!`ņ````````Ï````!!!!!""####"""""##$$%"!!`@ьΏ`a!!!""""###""!!!""""!!`lj```!!!!!!a!""##$$%%%&%%$$##""!!``׉`!!""##$$$$$%%%&%%&&&&&%%$$##"""""""""###$$%%&%%$$c#""""##$$##""!!`я`!!!!!`Ɔă`a!!!``a``͊Δ``a!!!!!!!""###$#######$$%%"baa`Î``ɘ````ώ`!!"""####$##""!"""""!a`Ň`aa!!!`a!""##$$$%%%%%$$##""!!!`````a!""##$$$$%%%&&&&&&&&&&&%%$$####"""#####$$%%&%%$$##""!!""cc$##""!!```!a````̏``!!!!!a`````````a!!!!!"""""##$$$$####c$$%%&#bba!````ˇ`a````aa!!```````χ`!!"""""######"""##"b!!`ņ`!a!!``!!""##$$$%%%%%$$##""!!!!!!``aa""##$$%%%%%&&&'&&'''''&&%%$$#########$$$%%&%%$$##""!!!!"bc###""!!`ƎLj`aa```````````Dž``Ɖ`a!!"!!!```````a!!!`a!!!""""""""##$$$%$$$$$$$%%&&##""!!!!``a!a``!!!!!a!!!!!!!!````!!""""""#####"##""!!`ƈ``!!`ϓ`!!""###$$$%%%%$$##"""!!!!!!!""##$$%%%%&&&'''''''''''&&%%$$$$###$$$$$%%&%%$$##""!!``aa""####""!a`ϐ`Ȇ`a!!!`a`Ć``````````a!````aaa"!!!`Љ`a!!!!!!!!!!""""""#####$$%%%%$$$$$%%&&'$##""!!!a``````Ɋ``aa!!!!!""""!!!!!!!!!````!!!!!"""""""###""!!`lj``ʏ`!!""###$$$%%%%$$##""""""!!""##$$%%&&&&&'''(''(((((''&&%%$$$$$$$$$%%%&%%$$##""aa``a!""####""!a````!`ƈ``a!!!```†``a!!!!!!!!!!!aa`a!a""!!``ʒ``aa!!!""""!""""########$$%%%&%%%%%%%&&''$$##""""!!!!!``````a!!""""""""""""""!!!!`ƒ‘`!!!!!!!"""""""##""!!``ɋˍ`!!"""###$$%%%%$$###"""""""##$$%%&&&&'''(((((((((((''&&%%%%$$$%%%%%&%%$$##""aa```a!""##$##""!!``a!`a`Ɖ`!ab"!!`a!`ņ`a!!!!!!!!!!!""!!!!!""!!`Ŏ`a!"""""""""""######$$$$$%%&&&&%%%%%&&''(%$$##""!"!!!``a``aa"""""####"""""""""!!!```„`````!!!!!!!"""##"b!!`ʊ`!!"""###$$%%%%$$######""##$$%%&&'''''((()(()))))((''&&%%%%%%%%%&&%%$$##""!a`ΐ`a!""##$##""!!!```a`Ȉ`a!bb!!````Ɖ`a!!""""""""""""""!"""!!`nj`!!"""####"####$$$$$$$$%%&&&'&&&&&&&''h($$##""!!!!````!!!`a!"""##############""""!!``Ā``!!!!!!!"""baaa`NJ`!!!!"""##$$%%%%$$$#######$$%%&&''''((()))))))))))((''&&&&%%%&&&&%%$$##"""!a``!!""##$##""!!``!`ń`a!b!!`ƆĆ``!!""""""""""""##"""""!!`Ǝ`!!""#######$$$$$$%%%%%&&''''&&&&&''(()$##""!!`a````aa!b!!!""#####$$$$#########"""!!a`΂ɐ`````!!!""aaaa`̌`!!!!"""##$$%%%%$$$$$$##$$%%&&''((((()))*))*****))((''&&&&&&&&&%%$$##""!!!`!``!!"""####""!!``aaa````a!!!!!`ň`a!!!"""""###########"""!!`̗``a!""##$$$#$$$$%%%%%%%%&&'''('''''''(())##""!!``a`a!!!!"""!""###$$$$$$$$$$$$$$####""!!a``ȑ``a!!!```Ȍ```!!!""##$$%%%%%$$$$$$$%%&&''(((()))***********))((''''&&&&&%%$$##""!!!`````!!"""##""!!!!``aaaa`aa!!!`!!!`Ą``aa!!!!"!!""######$$##""!!`Ȑ`!!""cc$$$$$$$%%%%%%&&&&&''(((('''''(())*$##"baa`a!!aa!"""#"""##$$$$$%%%%$$$$$$$$$###"""!a`a`Ɍ`!!`ɉ`a!!""##$$%%%%%%%%$$%%&&''(()))))***+**+++++**))(('''''&&%%$$##""!!``Ȇ```Ō`!!!""""!!!!!``a```!```````ň``aaa``!!!a!""##$$$$$$##""!!`Ԗ``a!""##$$%%%$%%%%&&&&&&&&''((()((((((())**$dc#b"!a!"!"""""###"##$$$%%%%%%%%%%%%%%$$$##""!!```ā`!!!`Ɉ``!!""##$$%%&%%%%%%%&&''(())))***+++++++++++**))(((''&&%%$$##""!!`ņ`a```̈́`!!!""!!```````ȆɈ````!``!!""##$$%$$##""!!`҆`!!!""##$$%%%%%%%&&&&&&'''''(())))((((())**+edd##""!""""""###$###$$%%%%%&&&&%%%%%%%%$$##""!!``!`ʐ`a!a`Ɖ`!!""##$$%%&&&&%%&&''(())*****+++,++,,,,,++**))((''&&%%$$##""!!`Ƈ``LJ``!!!!`ąÄƆƄ``!!""##$$$$##""!!`ŏ`a!!""##$$%%&&&%&&&&''''''''(()))*)))))))**++%%$$##"""#"#####$$$#$$%%%&&&&&&&&&&&&&&%%$$##""!!`a!!``Ʉ`a!`ʼn`!!""##$$%%&&&&&&&''(())****+++,,,,,,,,,,++**))((''&&%%$$##""!!`ˉ`!`ˇ`!!`…``!!""##$$$$##""!!`Ő`a!"""##$$%%&&&&&&&''''''((((())****)))))**++,&%%$$##"######$$$%$$$%%&&&&&''''&&&&&&&&%%$$##""!!!b!!`Ä`!`Ɖ`!!""##$$%%&&''&&''(())**+++++,,,-,,---,,++**))((''&&%%$$##""!!````a``a!``Ã``!!""##$$%$$##""!!``a!"""##$$%%&&'''&''''(((((((())***+*******++,,&&%%$$###$#$$$$$%%%$%%&&&''''''''''''''&&%%$$##""!"""!!`Ƅ`Ɗ````!!""##$$%%&&'''''(())**++++,,,---------,,++**))((''&&%%$$##""!a``a!!!!````Ä`a``!!""##$$%%$$##""!a`a!""###$$%%&&'''''''(((((()))))**++++*****++,,-'&&%%$$#$$$$$$%%%&%%%&&'''''((((''''''''&&%%$$##"""""!a`ɑˌ``a``a!!!""##$$%%&&'''(())**++,,,,,---.--...--,,++**))((''&&%%$$##""!!!!!!!````````Ĉ`!``!!""##$$%%%$$##"baa!""###$$%%&&''((('(((())))))))**+++,+++++++,,--''&&%%$$$%$%%%%%&&&%&&'''((((((((((((((''&&%%$$##"##""!a`ˎφ``````````a!!````!!""##$$%%&&''(())**++,,,---.........--,,++**))((''&&%%$$##""!!"""aa``!!!!!``Dž`!``!!""##$$%%%$$#cb"!""##$$$%%&&''((((((())))))*****++,,,,+++++,,--.(''&&%%$%%%%%%&&&'&&&''((((())))((((((((''&&%%$$#####""!!`@Ñ͍`````a``!!!!`Ί`!!""##$$%%&&''(())**++,,--.../..///..--,,++**))((''&&%%$$##"""""""!!!!aa``ƅ`!``a!""##$$%%&%%$$c#"""##$$$%%&&''(()))())))********++,,,-,,,,,,,--..((''&&%%%&%&&&&&'''&''((())))))))))))))((''&&%%$$#$$##""!!``@@@@ό```!`a!!!`ύ`!!""##$$%%&&''(())**++,,--..////////..--,,++**))((''&&%%$$##""##""!a````Ɗ`a!a`!!b"##$$%%&&&%%d$##"##$$%%%&&''(()))))))******+++++,,----,,,,,--../)((''&&%&&&&&&'''('''(()))))****))))))))((''&&%%$$$$$##""!!!`ր@@A@ώ̋`a!!!!!!`ƀ`!!""##$$%%&&''(())**++,,--..///000//..--,,++**))((''&&%%$$####""!!`Ƅ`a!!`a!""##$$%%&&'&&e%$$###$$%%%&&''(())***)****++++++++,,---.-------..//))((''&&&'&'''''((('(()))**************))((''&&%%$%%$$##""!!`Ń@@A@@A@ώ`!!!aa!!a``````!!""##$$%%&&''(())**++,,--..//00000//..--,,++**))((''&&%%$$####""!!```҄‚`!!``!!""##$$%%&&'&&%%$$#$$%%&&&''(())*******++++++,,,,,--....-----..//0*))((''&''''''((()((())*****++++********))((''&&%%%%$$##""!!`ϋ@@@@@@@@@ˊ``aaa``!!!!!a`a``a!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##"""""!!!```Ã````Ą@@@@@@‚`!!!``a!""##$$%%&fg'&&%%$$$%%&&&''(())**+++*++++,,,,,,,,--.../.......//00**))(('''('((((()))())***++++++++++++++**))((''&&%%%$$##""!!`ЄϏ@@@ʌ````!!!!!!!!!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##"""""""!!!`ņ̓`a```a!!`Å@A@`a!"!!`aa"""##$$%ef&'''&&%%$%%&&'''(())**+++++++,,,,,,-----..////.....//001+**))(('(((((()))*)))**+++++,,,,++++++++**))((''&&%%$$##""!!`Ɗ@@@@AA@@@ʍ```a!""""!"!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!!!!"!!!`†```!!!``aa`Ã@@@@`a!""!a`!!!!""#cdde%&&'''&&%%%&&'''(())**++,,,+,,,,--------..///0///////0011++**))((()()))))***)**+++,,,,,,,,,,,,,++**))((''&&%%$$##""!!`Ȓ@@@@@ʋLJ````````!!""""""""""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!!!!!!!!!`ŅЍ`!`Ð`a!"!!``aaaa`Ύ@A@Å`a!""!!```!!!"bcc$$%%&&'''&&%&&''((())**++,,,,,,,------.....//0000/////00112,++**))())))))***+***++,,,,,----,,,,,,++**))((''&&%%$$##""!!`Β@@̉@A@@@Ǝ``a!```a!!!!""####"#""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!`````!`!!`Ɖˏ```ē`!!`ʅ`!!"""!aa!""!!`֗@@ɉ`a!"""!!```aab"##$$%%&&'''&&&''((())**++,,---,----........//000100000001122,,++**)))*)*****+++*++,,,-----------,,++**))((''&&%%$$##""!!`ˑ@@ʉ@@@@@@@Nj``a!!!!`a!!!!!""##########$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!`````ԓ`````a!`ώ`!!`ϑ`a!"""!!!!!!""!!``ф@@Lj`a!"""!!``˂`aa""##$$%%&&'''&''(()))**++,,-------....../////0011110000011223-,,++**)******+++,+++,,-----....----,,++**))((''&&%%$$##""!!`̒@@̋@@@͍`!!!""!!!!"""""##$$$$#$##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!`ӍїБ`!!``a!!`a`Ȇ`!!```҂`!!!!!!!!!!!!!!!!!``Œ@@@È`````a!"""!!````a!""##$$%%&&''('''(()))**++,,--...-....////////00111211111112233--,,++***+*+++++,,,+,,---.........--,,++**))((''&&%%$$##""!!`ǎ@@@@@@@A@@ё`a!""""!""""""##$$$$$$$$$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!`А`!!!!!!``a`ʓ``!!!``͗`!!!!!``````!!!!!!!`܋@@@ɉ``a!!!!!""#""aa````a!!!""##$$%%&&''((('(())***++,,--.......//////000001122221111122334.--,,++*++++++,,,-,,,--.....////..--,,++**))((''&&%%$$##""!!`ԏʊ@@@@͏`aa""##""""#####$$%%%%$%$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!`ˌ``a!"!!"!!`!!!````!!`͏ʉ`!```````````Ӟ@A@ȈÆ`!!!!!!""##""!a`a!!!!!""##$$%%&&''(()((())***++,,--..///.////0000000011222322222223344..--,,+++,+,,,,,---,--...///////..--,,++**))((''&&%%$$##""!!`Ռ͍``aab"####"######$$%%%%%%%%%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$##""!!`ѓ`a!!""""!!``!!!!```!`͑```````ِԙ@@@ʈ``э`a!""""""##""!!``!!""""##$$%%&&''(()))())**+++,,--..///////000000111112233332222233445/..--,,+,,,,,,---.---../////00//..--,,++**))((''&&%%$$##""!!`с``!!!""##$$####$$$$$%%&&&&%&%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$##""!!`̇``!!!"b#""!!``!!!!!!```aa`Џ``aaa```ϐ@A@ȃ``!`ƈ`a!""""""###""!!``!!""##$$%%&&''(())*)))**+++,,--..//000/00001111111122333433333334455//..--,,,-,-----...-..///000000//..--,,++**))((''&&%%$$##""!!`ȃ`!!!""##$$$$#$$$$$$%%&&&&&&&&&&''(())**++,,--..//00112221100//..--,,++**))((''&&%%$$##""!!`ȉ`!!"bbb"""!!``!!""!!!``!a!``!aa!`Ӎ@@ō`a!`````ŏ`a!""#######"""!!``!!""##$$%%&&''(())**)**++,,,--..//00000001111112222233444433333445560//..--,------.......//00000100//..--,,++**))((''&&%%$$##""!!`ɂ`a!"""##$$%%$$$$%%%%%&&''''&'&&''(())**++,,--..//001122221100//..--,,++**))((''&&%%$$##""!!`lj`aab"b"""""!a`a!""!!!!!`a!"!!`Ȉ`aa!`Ȇ@A@Ǝ``a!!a`aa!`ˌ`a!""######"""!!``a!""##$$%%&&''(())*****++,,,--..//0011101111222222223344454444444556600//..---.-.........//0001111100//..--,,++**))((''&&%%$$##""!!`̃`!!""##$$%%%%$%%%%%%&&''''''''''(())**++,,--..//00112233221100//..--,,++**))((''&&%%$$##""!!`ǒ`a!!!!!!!!!!!!!!!"!a```aa!""!!`׍`aa`ɀ@@Ċ`a!`a!!!!`Ï`!!""#"""""!!!a``!!""##$$%%&&''(())**+*++,,---..//001111111222222333334455554444455667100//..-....../..-..//0011111100//..--,,++**))((''&&%%$$##""!!`Ɋ``a!""##$$%%&&%%%%&&&&&''(((('(''(())**++,,--..//001122333221100//..--,,++**))((''&&%%$$##""!!`Ç`a!!!!!!!!!!!!!``!!!``a!"""!a``a`aa`ؔїć@@@Ø```aa"!a``ȏ`!!""""""!!a!`և`!!""##$$%%&&''(())**+++,,---..//00112221222233333333445556555555566771100//..././//..---..//0011221100//..--,,++**))((''&&%%$$##""!!`͊`!!""##$$%%&&&%&&&&&&''(((((((((())**++,,--..//00112233433221100//..--,,++**))((''&&%%$$##""!a```````a!!!````````````a!!```a!""#""!a``a````````@@@@@ڎ`aa"!!`Ņ`!!"!!!!!```ƀ`a!""##$$%%&&''(())**+++,,--...//0011222222233333344444556666555556677821100//./////..--,--..//0011221100//..--,,++**))((''&&%%$$##""!!`τ`!!""##$$%%&&&&&&'''''(())))()(())**++,,--..//0011223344433221100//..--,,++**))((''&&%%$$##""!!!!``a!!a!!``Ւ`a!!!!!!""###""!!aa!`aa``a``a!```a!`̎є`a!"""!!`Ґ`!!!!a!!`ԏ`!!""##$$%%&&''(())**++,,--...//001122333233334444444455666766666667788221100///0//..--,,,--..//0011221100//..--,,++**))((''&&%%$$##""!!`φ`!!""##$$%%&&'&''''''(())))))))))**++,,--..//001122334454433221100//..--,,++**))((''&&%%$$##""!!!````````ו`!a!!a""##$##""!!"aaa!aa!!a!!!`aa!`ϑ`a!""""!!`ʄ`a!!!``````!!""##$$%%&&''(())**++,,--..//00112233333334444445555566777766666778893221100/0//..--,,+,,--..//001121100//..--,,++**))((''&&%%$$##""!!`ӑ`a!""##$$%%&&'''''((((())****)*))**++,,--..//0011223344554433221100//..--,,++**))((''&&%%$$##""!!`՗`!!""""#####"""""bbabba!"!!!!``a!`֌``!!"""!!``a!!`````a!""##$$%%&&''(())**++,,--..//0011223344434444555555556677787777777889933221100//..--,,+++,,--..//001121100//..--,,++**))((''&&%%$$##""!!``ǎ``a!""##$$%%&&''('(((((())**********++,,--..//0011223344554433221100//..--,,++**))((''&&%%$$##""!!!`ѓ``a!!!!!""###""!!!!"""""""""""!!`a!!`͓`!!"""!a```aaa``````aa!!""##$$%%&&''(())**++,,--..//00112233444444455555566666778888777778899:3221100//..--,,++*++,,--..//001121100//..--,,++**))((''&&%%$$##""!aa``Ԁ``a!!""##$$%%&&''((((()))))**++++*+**++,,--..//0011223344554433221100//..--,,++**))((''&&%%$$##""!!``ԓ``!!!!!!"""""!!!!!!!""""""""""!!!!`ɒ`!!""""!!aa!!```aa`a!!!!a""##$$%%&&''(())**++,,--..//00112233445554555566666666778889888888899::221100//..--,,++***++,,--..//001121100//..--,,++**))((''&&%%$$##""!a!a`Ѓ`a!!!""##$$%%&&''(()())))))**++++++++++,,--..//0011223344554433221100//..--,,++**))((''&fe%$$##""!!`͍`````!!"""!!````!!!!!!!""!!!"!!!`Ӕ`!!""""aa!!```a!!!!!""""##$$%%&&''(())**++,,--..//00112233445555555666666777778899998888899::;21100//..--,,++**)**++,,--..//001121100//..--,,++**))((''&&%%$$##"""!!`цʐ`a!!"""##$$%%&&''(()))))*****++,,,,+,++,,--..//0011223344554433221100//..--,,++**))((''&&e%$$##""!!`ϓ`!!!!!```!!!!!!!!!!!!!``!!""#""""!a```!!"!""""""##$$%%&&''(())**++,,--..//001122334455666566667777777788999:9999999::;;1100//..--,,++**)))**++,,--..//001121100//..--,,++**))((''&&%%$$##"""!!```ϒ`a!""""##$$%%&&''(())*)******++,,,,,,,,,,--..//0011223344554433221100//..--,,++**))((''&&%%$$##""!!`ؗ``!!!!`ć`````!!```a````!!""#"""!!``!!!""""""####$$%%&&''(())**++,,--..//00112233445566666667777778888899::::99999::;;<100//..--,,++**))())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!```̌ą`!!""###$$%%&&''(())*****+++++,,----,-,,--..//00112233445554433221100//..--,,++**))((''&&%%$$##""!!`ȁ```!`ą```֊`a!""####""!!`a!!""#"######$$%%&&''(())**++,,--..//00112233445566777677778888888899:::;:::::::;;<<00//..--,,++**))((())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!``!`ӑÃ`````Ä`!!""##$$%%&&''(())**+*++++++,,----------..//001122334455554433221100//..--,,++**))((''&&%%$$##""!!`ۘ`ÂɈ`͏ə`!a""#####""!aa"""######$$$$%%&&''(())**++,,--..//00112233445566777777788888899999::;;;;:::::;;<<=0//..--,,++**))(('(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!````Ȏ`````aa!!`````!!""##$$%%&&''((())**+++,,,,,--....-.--..//001122334455554433221100//..--,,++**))((''&&%%$$##""!!!`Ԍȅ``ؐ```Ǐ`a!""##$##"b!"""##$#$$$$$$%%&&''(())**++,,--..//00112233445566778887888899999999::;;;<;;;;;;;<<==//..--,,++**))(('''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!```ǎ`a!!!```aa!!!!!!!``!!""##$$%%&&'''(())**++,,,,--..........//001122334455554433221100//..--,,++**))((''&&%%$$##"ba!!`ˇ```ғ`!!`ӑ`!!""##$$##"""###$$$$$$%%%%&&''(())**++,,--..//00112233445566778888888999999:::::;;<<<<;;;;;<<==>/..--,,++**))((''&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!a````ɉ``!!!!!!!!!""""!!!!``!!""##$$%%&&''''(())**++,,--..////./..//001122334455554433221100//..--,,++**))((''&&%%ddccb"a!``Ѝ``a`Ֆ`!!`Β`a!""##$$$$##"###$$%$%%%%%%&&''(())**++,,--..//00112233445566778899989999::::::::;;<<<=<<<<<<<==>>..--,,++**))((''&&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!a``a`ȍ`a!!""""!!!"""""""!!``!!""##$$%%&&&&&''(())**++,,--..////////001122334455554433221100//..--,,++**))((''&&%%$dccbbaa`ʏ`a`̘``!!``ΑƏ`!!""##$$%$$###$$$%%%%%%&&&&''(())**++,,--..//0011223344556677889999999::::::;;;;;<<====<<<<<==>>?.--,,++**))((''&&%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!a``!`ʍ`!!"""""""""####""!!`Ã`!!""##$$%%&&&&&''(())**++,,--..///0//001122334455554433221100//..--,,++**))((''&&%%$$##""!!`ʌ`!`Β`!!!``ݑ`a!""##$$%%%$$#$$$%%&%&&&&&&''(())**++,,--..//00112233445566778899:::9::::;;;;;;;;<<===>=======>>??--,,++**))((''&&%%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!``!!`ǒ`!!""###"""######""!!``!a""##$$%%%%%%&&''(())**++,,--..//00001122334455554433221100//..--,,++**))((''&&%%$$##""!!`ȋ`!!`Β`!!!!`````ň`a!""##$$%%&%%$$$%%%&&&&&&''''(())**++,,--..//00112233445566778899:::::::;;;;;;<<<<<==>>>>=====>>???-,,++**))((''&&%%$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!``!`Ž`!!""##########$##""!!``!!""##$$%%%%%%%&&''(())**++,,--..///000112233445554433221100//..--,,++**))((''&&%%$$##""!!`ɋ`!!`я`a!!!a!`a``̊`!!!""##$$%%&%%$%%%&&'&''''''(())**++,,--..//00112233445566778899::;;;:;;;;<<<<<<<<==>>>?>>>>>>>????,,++**))((''&&%%$$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!`Ó`!!""##$##########"""!a`a!""###$$%%$$$$%%&&''(())**++,,--..////001122334454433221100//..--,,++**))((''&&%%$$##""!!`ʊ`!!`ʐ`!!!!``!!````````````ƒ`a!`a!""##$$%%&%%%&&&''''''(((())**++,,--..//00112233445566778899::;;;;;;;<<<<<<=====>>????>>>>>?????,++**))((''&&%%$$#$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!a``!!`Ə`!!""##$$##""""##""!"baa!!"""###$$$$$$$$%%&&''(())**++,,--...///00112233444433221100//..--,,++**))((''&&%%$$##""!!`̋`!!`Ċ``````!!!!!!!!!!!!!`Ã`a!``!ab"c#$$%%&%&&&''('(((((())**++,,--..//00112233445566778899::;;<<<;<<<<========>>???????????????++**))((''&&%%$$###$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!`ɓ`a!""##$$##""""""""!!!!!!!!!""""##$$####$$%%&&''(())**++,,--....//001122334433221100//..--,,++**))((''&&%%$$##""!!`̋`!!`ҋLj```!!!!!!!!!!!``ń`a!``!!b"##$$%%&&&'''(((((())))**++,,--..//00112233445566778899::;;<<<<<<<======>>>>>????????????????+**))((''&&%%$$##"##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!`a!!!`ʔ`!!""##$##""!!!!""!!`aa````!!!"""########$$%%&&''(())**++,,---...//0011223333221100//..--,,++**))((''&&%%$$##""!!`ɋ`!!!`Ց`!!"""""""!!!`ŋ``a!!``!!""##$$%%&&&'''(()())))))**++,,--..//00112233445566778899::;;<<===<====>>>>>>>>?????????????????**))((''&&%%$$##"""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!a""!!`̜`!!""####""aa!!!!!!````a!!!""##""""##$$%%&&''(())**++,,----..//001122333221100//..--,,++**))((''&&%%$$##""!!`Ȋ`!!`ϑ`!!"""""""!!!`ɈÂ``Γ…``a!!"!!`aa""##$$%%&&'''((())))))****++,,--..//00112233445566778899::;;<<=======>>>>>>??>??????????????????*))((''&&%%dd##""!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!"""!a`Ԗ`!!""##""!!````!!aa```````!a!""""""""##$$%%&&''(())**++,,,---..//0011223221100//..--,,++**))((''&&%%$$##""!!`Ƈ`!`˝`a!""#####""!!`˅```a`Ζ```!!!!"""!aab"##$$%%&&'''((())*)******++,,--..//001122334455667788899::;;<<==>>=>>>>?????>>>?????????????????))((''&&%%$$#cbb!!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##"""""!a`Ӗ`!!"""""!!``!!!!`!a!!````!!""!!a!""##$$%%&&''(())**++,,,,--..//001122221100//..--,,++**))((''&&%%$$##""!!`Ć`!`ƒ`a!""#######""!!```ʒ`a``!!!`Č``````a`!!!!"""#""!""##$$%%&&''((()))******++++,,--..//00112233445566778878899::;;<<==>>>>??????>>=>>????????????????)((''&&%%$$##""aa`!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##"#""!!`ӓ`!!""""!!`Ƅ`!!"!!!!!!aa``aa!!!!!!""##$$%%&&''(())**+++,,,--..//001122221100//..--,,++**))((''&&%%$$##""!!`Ň`!!`ď`!!""##$$$$##""!!`a`я`a!!!!!!`ȇ`a!!aa!!!!!""""###"""b##$$%%&&''(()))**+*++++++,,--..//0011223333445566777778899::;;<<==>>??????>>===>>???????????????((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$###""!!`Е`!!!!!!!`Ȇ`!!"""!""""!!a```aa!a````!!""##$$%%&&''(())**++++,,--..//00111111100//..--,,++**))((''&&%%$$##""!!`Ņ`!!!`ǘ`a!""##$$$$$$##""!!!`ɏ`a!!!"""!!`҇`a!!``aa"!""""####""!!b"##$$%%&&''(())**+++++,,,,--..//001122333233445566776778899::;;<<==>>????>>==<==>>??????????????)((''&&%%$$##""!a`a!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$###""!!``ג`!!!!```ˆ`!!""""""""""!!!!!`!``!!""##$$%%&&''(())***+++,,--..//0011111100//..--,,++**))((''&&%%$$##""!!`„`!!!!`ϙ`!!""##$$%%%$$##""!!`֐``!!""""""!!`Ȅ`!!``a!"""#####""!!aa""##$$%%&&''(())**++,,,,,--..//00112233322233445566666778899::;;<<==>>??>>==<<<==>>?????????????))((''&&%%$$##""!a!""##$$%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$$##""!!!`ϓ````Ǎ`a!"""#"####""ba!!```aa"bcc$$%%&&''(())******++,,--..//000000000//..--,,++**))((''&&%%$$##""!!`Ã`!!!`Γ``a!""##$$%%%%$$##""!!`̎`!!""""##""!!``!!``!!""#####""!!``a!""##$$%%&&''(())**++,,---..//0011222222212233445566566778899::;;<<==>>>>==<<;<<==>>????????????*))((''&&%%$$##""!""##$$%%&&''(())**++,,--..//001122221100//..--,,++**))((g'&&%%$$$##""!!!``֐Dž`!!""""#######bbb!a`a````a!bbccd$%%&&&''(())))))***++,,--..//00000000//..--,,++**))((''&&%%$$##""!!`ą`!!!`ʝ``a!!""##$$%%&&%%$$##""!!`я``!!""#####""!!``!!``!!""##$##""!!``a!""##$$%%&&''(())**++,,--..//00112222221112233445555566778899::;;<<==>>==<<;;;<<==>>???????????**))((''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233221100//..--,,++**))((''&&%%%$$##"""!!!``ɏ`!!!!!""##$$###b""!!!!!a!!""##$$%%%&&&&''(()))))))**++,,--..///////00//..--,,++**))((''&&%%$$##""!!`Ã`!!!`ך`a!!""##$$%%&&&%%$$##""!!`Ϗ`a!!""######""!!`ÃÌ`!!!!!""##$$##""!!`܄`!!""##$$%%&&''(())**++,,--..//00112111110112233445545566778899::;;<<====<<;;:;;<<==>>??????????+**))((''&&%%$$##"##$$%%&&''(())**++,,--..//0011223333221100//..--,,++**))((''&&%%%$$##"""!!!!```גϒ`a!aa!!!""##$$$###""!"!!!!""##$$%%%%%%%&&''(((((()))**++,,--..//////////..--,,++**))((''&&%%$$##""!!`Ä`!!!`Қ```a!"""##$$%%&&&&%%$$##""!!`ҏ`!!""##$$$##""!!````Ʌ`!!!""##$$$##""!!`Ќ`!!""##$$%%&&''(())**++,,--..//001111111000112233444445566778899::;;<<==<<;;:::;;<<==>>?????????++**))((''&&%%$$###$$%%&&''(())**++,,--..//001122334433221100//..--,,++**))((''&&&%%$$###"""!!!!!``````Ҟ```````!!""##$$$###""""""""##$$$$%$$%%%%&&''((((((())**++,,--.......////..--,,++**))((''&&%%$$##""!!`Ą`a!!`Κ`!!!!"""##$$%%&&'&&%%$$##""!!`ϒ```!!""##$$$$$##""!a``a!`҂`!!""##$$$##""!!``a!""##$$%%&&''(())**++,,--..///0011100000/00112233443445566778899::;;<<<<;;::9::;;<<==>>????????,++**))((''&&%%$$#$$%%&&''(())**++,,--..//00112233444433221100//..--,,++**))((''&&&%%$$###""""!!!!!`!!!!`Й`!!""##$$$$##"#""""###$$$$$$$$$$%%&&''''''((())**++,,--........//..--,,++**))((''&&%%$$##""!!`Ą`a!`ˏ`a!!!""###$$%%&&'''&&%%$$##""!!`Ў`a!!""##$$%%%$$##""!!a!!`͋`!!""##$$##""!!``a!!""##$$%%&&''(())**++,,--....//00000000///00112233333445566778899::;;<<;;::999::;;<<==>>???????,,++**))((''&&%%$$$%%&&''(())**++,,--..//0011223344554433221100//..--,,++**))(('''&&%%$$$###"""""!!!!!!!!`ˌ`!!""##$$$####"""#""#####$##$$$$%%&&'''''''(())**++,,-------.....--,,++**))((''&&%%$$##""!!`Ä`a!`Ș```!!""""###$$%%&&''''&&%%$$##""!!`Ґ`!!""##$$%%%%%$$##"b!!!!`̆`!!""##$$##""!!```!!""##$$%%&&''(())**++,,--....//000/////.//00112233233445566778899::;;;;::99899::;;<<==>>??????-,,++**))((''&&%%$%%&&''(())**++,,--..//001122334455554433221100//..--,,++**))(('''&&%%$$$####"""""!""""!!``ō`a!""##$$$##""""!"""""##########$$%%&&&&&&'''(())**++,,--------....--,,++**))((''&&%%$$##""!!`Ą`!`ӑ``a!!!""""##$$$%%&&''((''&&%%$$##""!!`Ԓ`!!""##$$%%&&%%$$##b""!!`ψÄ`!!""##$$$##""!!```a!""##$$%%&&''(())**++,,----..////////...//00112222233445566778899::;;::9988899::;;<<==>>?????--,,++**))((''&&%%%&&''(())**++,,--..//00112233445566554433221100//..--,,++**))(((''&&%%%$$$#####""""""""!!!````ǎ`!!b"###$##""""!!!"!!"""""#""####$$%%&&&&&&&''(())**++,,,,,,,---...--,,++**))((''&&%%$$##""!!`Ą`!````!!!!!""####$$$%%&&''(((''&&%%$$##""!!`ђ`!!""##$$%%&&&%%$$c#b""!!``Ѕ`!!""##$$$##""!aa```a!""##$$%%&&''(())**++,,----..///.....-..//00112212233445566778899::::998878899::;;<<==>>????.--,,++**))((''&&%&&''(())**++,,--..//0011223344556666554433221100//..--,,++**))(((''&&%%%$$$$#####"####""!!!!!`Ņ`!!b"#####""!!!!`a!!!!""""""""""##$$%%%%%%&&&''(())**++,,,,,,,,--.--,,++**))((''&&%%$$##""!!`Ã`!``!!!!!!!!!""cc$$%%%&&''((((''&&%%$$##""!!`Ց`!!""##$$%%&&&&%%dd##""!a````҅`!!""##$$$$##""aaa```!!""##$$%%&&''(())**++,,,,--........---..//00111112233445566778899::99887778899::;;<<==>>???..--,,++**))((''&&&''(())**++,,--..//001122334455667766554433221100//..--,,++**)))((''&&&%%%$$$$$########"""!!!!`Ą`a!""##"#""!!!!``!``!!!!!"!!""""##$$%%%%%%%&&''(())**+++++++,,,-----,,++**))((''&&%%$$##""!!``a!!!!!!!!``!abbc#$$%%&&''(()((''&&%%$$##""!!`֗`!!""##$$%%&&&%%$dcc""!!``a!!`ͅ`a!""##$$%$$$##bbaa````!!""##$$%%&&''(())**++,,,,--...-----,--..//001101122334455667788999988776778899::;;<<==>>??/..--,,++**))((''&''(())**++,,--..//00112233445566777766554433221100//..--,,++**)))((''&&&%%%%$$$$$#$$$$##"""""!!`˅`!!"""""""!!```````!!!!!!!!!!""##$$$$$$%%%&&''(())**++++++++,,----,,++**))((''&&%%$$##""!!`‡`!!!!`````!!""##$$%%&&''((((''&&%%$$##""!!`Ȍ`!!""##$$%%&&&&%%dd##""!!``!!!``!!""##$$$$###"b!!````!!""##$$%%&&''(())**+++++,,--------,,,--..//000001122334455667788998877666778899::;;<<==>>?//..--,,++**))(('''(())**++,,--..//0011223344556677887766554433221100//..--,,++***))(('''&&&%%%%%$$$$$$$$###""""!!``!!"!""!"!!`Ӂϐ`````!``aaaa""##$$$$$$$%%&&''(())*******+++,,,---,,++**))((''&&%%$$##""!!``Ɍ`````̉`!!""##$$%%&&''(()((''&&%%$$#c""!!`׍`!!""##$$%%&&&&%%d$##""!!``!!!!`Ã``a!""##$$$$####bb!a```!!""##$$%%&&''(())****++++,,---,,,,,+,,--..//00/001122334455667788887766566778899::;;<<==>>0//..--,,++**))(('(())**++,,--..//001122334455667788887766554433221100//..--,,++***))(('''&&&&%%%%%$%%%%$$####""!!``!!!!!!!!!`Ƅ@@֙````a!""######$$$%%&&''(())********++,,,---,,++**))((''&&%%$$##""!!!``Ljԑ`a!""##$$%%&&''(())((''&&%%$$##"b!!`؅``!!""##$$%%&&&&%%$$##""!!``!!"!!```a!a""##$$$d##"##cb"!!```aa""##$$%%&&''(())))******++,,,,,,,,+++,,--../////001122334455667788776655566778899::;;<<==>00//..--,,++**))((())**++,,--..//00112233445566778899887766554433221100//..--,,+++**))((('''&&&&&%%%%%%%%$$$###""!!```!`aa`!!`Ń@@Æ͈`!!""#######$$%%&&''(()))))))***+++,,---,,++**))((''&&%%$$##""!!!`ņ`!!""##$$%%&&''(())((''&&%%$$##""!!`͆```!!""##$$%%&&&%%$$##""!!``a!""!!``a!!""##$$$$##"""cc#"b!a`aa`a!""##$$%%&&''((()))))****++,,,+++++*++,,--..//.//001122334455667777665545566778899::;;<<==100//..--,,++**))())**++,,--..//0011223344556677889999887766554433221100//..--,,+++**))(((''''&&&&&%&&&&%%$$$$##""!!``````ă``!!""""""###$$%%&&''(())))))))**+++,,---,,++**))((''&&%%$$##""!!`ą`a!""##$$%%&&''(())))((''&&%%$$##""!!``a``!!""##$$%%&&&%%$$##""!!``!!""!a`!a"""##$$$$##""!bb##""!!````!!""##$$%%&&''(((())))))**++++++++***++,,--.....//001122334455667766554445566778899::;;<<=1100//..--,,++**)))**++,,--..//00112233445566778899::99887766554433221100//..--,,,++**)))((('''''&&&&&&&&%%%$$$##""!!````aa`ć`!!"""""""##$$%%&&''((((((()))***++,,---,,++**))((''&&%%$$##""!!`ĉ`!!""##$$%%&&''(())*))((''&&%%$$c#""!!`a!``!!""##$$%%&%%$$cc"""!!``!!"""!!!"""##$$$$##""!aa""""!!``!!""##$$%%&&''('((((())))**+++*****)**++,,--..-..//001122334455666655443445566778899::;;<<21100//..--,,++**)**++,,--..//00112233445566778899::::99887766554433221100//..--,,,++**)))(((('''''&''''&&%%%%$$##""!!!a``!`Lj`!!!!!!"""##$$%%&&''(((((((())***++,,---,,++**))((''&&%%$$##""!a`Ċ`a!""##$$%%&&''(())***))((''&&%%$$##""!!!!``!!""##$$%%%%$$##b"!""!!``!!!"""!""###$$$$##""!!`!!""""aa```!!""##$$%%&&'''''(((((())********)))**++,,-----..//001122334455665544333445566778899::;;<221100//..--,,++***++,,--..//00112233445566778899::;;::99887766554433221100//..---,,++***)))(((((''''''''&&&%%%$$##""!!!!`!!!`ȏ``!!!!!!!""##$$%%&&'''''''((()))**++,,---,,++**))((''&&%%$$##""!!`ȌƇ`!!""##$$%%&&''(())****))((''&&%%$$##""!!!``!!""##$$%%%$$##"b!!!!!!```!!""""###$$$$##""!!``a!"""ba!```a!""##$$%%&&'''&'''''(((())***)))))())**++,,--,--..//001122334455554433233445566778899::;;3221100//..--,,++*++,,--..//00112233445566778899::;;;;::99887766554433221100//..---,,++***))))((((('((((''&&&&%%$$##""""!!!!!`ą`````!!!""##$$%%&&''''''''(()))**++,,---,,++**))((''&&%%$$##""!!``Ɗ``````Ã`!!""##$$%%&&''(())**+**))((''&&%%$$##"""!!``a!""##$$%%%$$##""!!`!!!!!``!!""##$$$####""!!!```!!bbb"!a`aa!""##$$%%%&&''&&&&''''''(())))))))((())**++,,,,,--..//001122334455443322233445566778899::;33221100//..--,,+++,,--..//00112233445566778899::;;<<;;::99887766554433221100//...--,,+++***)))))(((((((('''&&&%e$$##""""!"!!`Ɠ``!!""##$$%%&&&&&&&'''((())**++,,---,,++**))((''&&%%$$##""!!!`Ƈ```a!!!!`Ã`!!""##$$%%&&''(())**+++**))((''&&%%$$##"""!!!!""##$$%%%$$##""!!````!!`ș`!!""##$####""!!!`ΐ`!!b"""!aa!""##$$%%%%%&&&&%&&&&&''''(()))((((('(())**++,,+,,--..//001122334444332212233445566778899::433221100//..--,,+,,--..//00112233445566778899::;;<<<<;;::99887766554433221100//...--,,+++****)))))())))((''''&&%%$$####"""!!`Ȓ`!!""##$$%%&&&&&&&&''((())**++,,---,,++**))((''&&%%$$##""!!!`````````a!!!!!!!!`ċ`a!""##$$%%&&''(())**++,++**))((''&&%%$$###""!!""##$$%%&%%$$##""!!``!!`ϋ`!!""####""""!!``Ԏ`aa""#""!""b"##$$$$$$%%&&%%%%&&&&&&''(((((((('''(())**+++++,,--..//001122334433221112233445566778899:4433221100//..--,,,--..//00112233445566778899::;;<<==<<;;::99887766554433221100///..--,,,+++*****))))))))((('''&&%%$$####""!!`۞`!!""##$$%%%%%%%&&&'''(())**++,,---,,++**))((''&&%%$$##"""!!``a!!!!!!!!!!"""""!!`````Ȓ`!!""##$$%%&&''(())**++,,++**))((''&&%%$$###""""##$$%%&&&%%$$##""!!``!!`ʄ`!!""##c""""!!`ّ``a!"""##""""b""###$$$$$%%%%$%%%%%&&&&''((('''''&''(())**++*++,,--..//00112233332211011223344556677889954433221100/o..--,--..//00112233445566778899::;;<<====<<;;::99887766554433221100///..--,,,++++*****)****))((((''&&%%$$$##""!!`ƙ`!!""##$$$%%%%%%%%&&'''(())**++,,---,,++**))((''&&%%$$##"""!!!!!!!!!!!"""""""""!!!!aa`Ԓ`!!""##$$%%&&''(())**++,,,,++**))((''&&%%$$$##""##$$%%&&'&&%%$$##""!!```!``!!""##b"!!!!``Ï`!!"""""##"c"b!""######$$%%$$$$%%%%%%&&''''''''&&&''(())*****++,,--..//00112233221100011223344556677889554433221100//..---..//00112233445566778899::;;<<==>>==<<;;::998877665544332211000//..---,,,+++++********)))((''&&%%$$##""!!``ׇ`!!""###$$$$$$$%%%&&&''(())**++,,---,,++**))((''&&%%$$###""!!"""""""""""#####""!!!!!`Б`!!""##$$%%&&''(())**++,,--,,++**))((''&&%%$$$####$$%%&&'''&&%%$$##""a!````!!bb#""a!!!`ϑ`!!"!!!""##b"!!!"""cc###$$$$#$$$$$%%%%&&'''&&&&&%&&''(())**)**++,,--..//001122221100/0011223344556677886554433221100//..-..//00112233445566778899::;;<<==>>>>==<<;;::998877665544332211000//..---,,,,+++++*+++**))((''&&%%$$##""!!`՞`!!"""###$$$$$$$$%%&&&''(())**++,,---,,++**))((''&&%%$$###"""""""""""#########"""!!`͓`a!""##$$%%&&''(())**++,,----,,++**))((''&&%%%$$##$$%%&&''(''&&%%$$##"baa``````!!"""!a```ȋ`a!!!!!"""b!!`aa""""""##$$####$$$$$$%%&&&&&&&&%%%&&''(()))))**++,,--..//0011221100///0011223344556677866554433221100//...//00112233445566778899::;;<<==>>??>>==<<;;::998877665544332211100//...---,,,,,++++++**))((''&&%%$$##""!!`ڜ`!!""""#######$$$%%%&&''(())**++,,---,,++**))((''&&%%$$$##""###########$$$$$##""a!`ϑ``!!""##$$%%&&''(())**++,,--..--,,++**))((''&&%%%$$$$%%&&''((''&&%%$$##""aa`͇```!!"!!`Ć`!!```!!"ba!``a!!"""""####"#####$$$$%%&&&%%%%%$%%&&''(())())**++,,--..//00111100//.//0011223344556677766554433221100//.//00112233445566778899::;;<<==>>????>>==<<;;::998877665544332211100//...----,,,,,+++**))((''&&%%$$##""!!`ܔ`!!!!"""########$$%%%&&''(())**++,,---,,++**))((''&&%%$$$###########$$$$$$$$##""!!`Ѝ`a!!""##$$%%&&''(())**++,,--....--,,++**))((''&&&%%$$%%&&''((((''&&%%$$##""aa`Å``a!"!a`Ɔ`aa``aab!!``a!!a!!!""##""""######$$%%%%%%%%$$$%%&&''((((())**++,,--..//001100//...//0011223344556677766554433221100///00112233445566778899::;;<<==>>??????>>==<<;;::998877665544332221100///...-----,,++**))((''&&%%$$##""!!`ɝ``!!!!!"""""""###$$$%%&&''(())**++,,---,,++**))((''&&%%%$$##$$$$$$$$$$$%%%$$##""!!`Ƈ`a!!""##$$%%&&''(())**++,,--..//..--,,++**))((''&&&%%%%&&''(()((''&&%%$$##""!a`Ɔ`a!""!!`Ą`!!````aabb"!!`aa!`!!!!!""""!"""""####$$%%%$$$$$#$$%%&&''(('(())**++,,--..//0000//..-..//0011223344556687766554433221100/00112233445566778899::;;<<==>>????????>>==<<;;::998877665544332221100///....---,,++**))((''&&%%$$##""!!`Ş```!!!""""""""##$$$%%&&''(())**++,,---,,++**))((''&&%%%$$$$$$$$$$$%%%%%%$$##""!!`ő`a!"""##$$%%&&''(())**++,,--..////..--,,++**))(('''&&%%&&''(()))((''&&%%$$##""aa`͆`aaa""!!`ć`!``!``a!"!!``!`````!!b"!!!!""""""##$$$$$$$$###$$%%&&'''''(())**++,,--..//00//..---..//00112233445568877665544332211000112233445566778899::;;<<==>>??????????>>==<<;;::9988776655443332211000///..--,,++**))((''&f%%$$##""!!`ǃ``!!!!!!!"""###$$%%&&''(())**++,,---,,++**))((''&&&%%$$%%%%%%%%%%%%%$$##""!!`ć`!!""##$$%%&&''(())**++,,--..//00//..--,,++**))(('''&&&&''(())*))((''&&%%$$##""a!`˄`a!!""!!`Ɋ`a!````!!"!!`a!!``aaa!`!!!!!""""##$$$#####"##$$%%&&''&''(())**++,,--..////..--,--..//001122334455988776655443322110112233445566778899::;;<<==>>????????????>>==<<;;::9988776655443332211000//..--,,++**))((''&&%%$$##""!!`Ƀ`!!!!!!!!""###$$%%&&''(())**++,,---,,++**))((''&&&%%%%%%%%%%%&&&&%%$$##""!!`Ȋ`a!""##$$%%&&''(())**++,,--..//0000//..--,,++**))(((''&&''(())**))((''&&%%$$##""aa`˅``a!"!a`Ä`!!```aabbb!aa!aa```!aa```!!!!!!""########"""##$$%%&&&&&''(())**++,,--..//..--,,,--..//0011223344599887766554433221112233445566778899::;;<<==>>??????????????>>==<<;;::9988776655444332211100//..--,,++**))((''&&%%$$##""!!`ё``````!!!"""##$$%%&&''(())**++,,---,,++**))(('''&&%%&&&&&&&&&&&&%%$$##""!!`ˊ`a!""##$$%%&&''(())**++,,--..//001100//..--,,++**))(((''''(())***))((''&&%%$$##""!a`̊`a!a!`Ã`a!!``!!bbbb!!``aa!a``!`ʆ```!!!!""###"""""!""##$$%%&&%&&''(())**++,,--....--,,+,,--..//0011223344:998877665544332212233445566778899::;;<<==>>????????????????>>==<<;;::998877665544433221100//..--,,++**))((''&&%%$$##""!!`ғ``!!"""##$$%%&&''(())**++,,---,,++**))(('''&&&&&&&&&&&'''&&%%$$##""!!``Ȇ`a!""##$$%%&&''(())**++,,--..//00111100//..--,,++**)))((''(())**+**))((''&&%%$$##""!a`̇`aab!!````!!```!!""aa``a!``````!!"""""""baaa""##$$%%%%%&&''(())**++,,--..--,,+++,,--..//001122334::9988776655443322233445566778899::;;<<==>>??????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`׏`!!!""##$$%%&&''(())**++,,---,,++**))(((''&&''''''''''''&&%%$$##""!!`ŏ`!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**)))(((())**+++**))((''&&%%$$##""a!`ё`!!b"!!!a````a!!!````a!""baa``aaa!``Б`a!"""!!!!!`aa"b##$$%%$%%&&''(())**++,,----,,++*++,,--..//00112233;::99887766554433233445566778899::;;<<==>>??????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`͙`!!!""##$$%%&&''(())**++,,---,,++**))((('''''''''''(((''&&%%$$##""!!`Ɍ`a!""##$$%%&&'&''(())**++,,--..//001121100//..--,,++***))(())**++,++**))((''&&%%$$##""!!`Ό`!!"""!!!!!!`aa"!!````!!""b!!!a"b!!a```„`a!!!!!!!``aa""##$$$$$%%&&''(())**++,,--,,++***++,,--..//0011223;;::998877665544333445566778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʔ``a!""##$$%%&&''(())**++,,---,,++**)))((''((((((((((((''&&%%$$##""!!`̉`a!""##$$%%&&&&&''(())**++,,--..//001121100//..--,,++***))))**++,,,++**))((''&&%%$$##""!!`̈`!!!!""!!!!!!!b"!!````!!""""!!b""b!!!!!``Ã`a!!````a`a!b"##$$$$#$$%%&&''(())**++,,,,++**)**++,,--..//001122<;;::9988776655443445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ĕ`!!""##$$%%&&''(())**++,,---,,++**)))((((((((((())((''&&%%$$##""!!`ƌ`aa""##$$%%&&&&%&&''(())**++,,--..//001121100//..--,,+++**))**++,,-,,++**))((''&&%%$$##""a!````!!!!!!!!""!""""!!`a!``aa""##""""#"baa`a!!!`Ä````a!""c#$$$$###$$%%&&''(())**++,,++**)))**++,,--..//00112<<;;::99887766554445566778899::;;<<==>>??????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʚ`!!""##$$%%&&''(())**++,,---,,++***))(())))))))))((''&&%%$$##""!!`Ȏ`a!""##$$%%&&%%%&&''(())**++,,--..//001121100//..--,,+++****++,,---,,++**))((''&&%%$$##""!!`````!!``!!!!"""!"!!a!!!!b"""##""#""!a``!!!!`Ą`````a!""#cd$$$##"##$$%%&&''(())**++++**))())**++,,--..//0011=<<;;::998877665545566778899::;;<<==>>????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`א`!!""##$$%%&&''(())**++,,----,,++***)))))))))))*))((''&&%%$$##""!!`ϐ`!!""##$$%%&%%$%%&&''(())**++,,--..//001121100//..--,,,++**++,,--.--,,++**))((''&&%%$$##""!!a````aa!a"!!!"!""!!"""!""###c#"b!!`a!"!!`Äȓ`a!!!!!""##$ddd##"""##$$%%&&''(())**++**))((())**++,,--..//001==<<;;::9988776655566778899::;;<<==>>?????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ξ`!!""##$$%%&&''(())**++,,--.--,,+++**))*********))((''&&%%$$##""!!`Γ`a!""##$$%%%%$$$%%&&''(())**++,,--..//001121100//..--,,,++++,,--...--,,++**))((''&&%%$$##""!!!```````!!!`!!!"bb""!!!abb##cccb"!!!"!!`ă```!!!!""##$$d$ccb"!""##$$%%&&''(())****))(('(())**++,,--..//00>==<<;;::99887766566778899::;;<<==>>???????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`є`!!""##$$%%&&''(())**++,,--..--,,+++************))((''&&%%$$##""!!`ȕ`a!""##$$%%%$$#$$%%&&''(())**++,,--..//001121100//..---,,++,,--../..--,,++**))((''&&%%$$##"""!!!aa``````a``aaabbbaaa`aabbcc"c#""!"""!a```Ä`a!`Ά`!!""##$$$$ccb"aaa""c#$$%%&&''(())**))(('''(())**++,,--..//0>>==<<;;::998877666778899::;;<<==>>?????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`٘`a!""##$$%%&&''(())**++,,--....--,,,++**+++++++**))((''&&%%$$##""!!`Ō`!!""##$$%%$$###$$%%&&''(())**++,,--..//001121100//..---,,,,--..///..--,,++**))((''&&%%$$##"""!!!!!!!!!```aaa`aa`aabaa```a!"""""""""""""!!!!``a!!!``a!!b"c#$$##bbaa`a!""##$$%%&&''(())))((''&''(())**++,,--..//?>>==<<;;::9988776778899::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ޞ`!!""##$$%%&&''(())**++,,--../..--,,,++++++++++**))((''&&%%$$##""!!`ȑ`!!""##$$$$##"##$$%%&&''(())**++,,--..//001121100//...--,,--..//0//..--,,++**))((''&&%%$$###"""""!!!!!!!!!"!!!``!!!```!!""""!""!"""""""!!!!``a!""!!```a!"b####""!!``a!""##$$%%&&''(())((''&&&''(())**++,,--../??>>==<<;;::99887778899::;;<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ҟ`!!""##$$%%&&''(())**++,,--..///..---,,++,,,,,,++**))((''&&%%$$##""!!`ؖ`!!""##$$$##"""##$$%%&&''(())**++,,--..//001121100//...----..//000//..--,,++**))((''&&%%$$###"""""""""!!!"""!!!`aab!a`a!!""""!!!!!!!!!!"""""!!a!""""!!````a!""####""!!`aab"##$$%%&&''(())((''&&%&&''(())**++,,--..???>>==<<;;::998878899::;;<<==>>?????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ҟ`a!""##$$%%&&''(())**++,,--..//0//..---,,,,,,,,,++**))((''&&%%$$##""!!`ؗ`!!""##$##""!""##$$%%&&''(())**++,,--..//001121100///..--..//00100//..--,,++**))((''&&%%$$$#####"""""""""#"""!!!"bba!!!""""!!`!!`!!!!!!"""""!aa!""""!!!!`aa"b##$$##""!!!bb##$$%%&&''(())((''&&%%%&&''(())**++,,--.????>>==<<;;::9988899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!a`ޜ`a!""##$$%%&&''(())**++,,--..//000//...--,,----,,++**))((''&&%%$$##""!!`ӕ`!!""####""!!!""##$$%%&&''(())**++,,--..//001121100///....//0011100//..--,,++**))((''&&%%$$$#########"""###"""!""#""!"""""!!````````a!"""!!``!!""""!!!!!""#cd$$$##""a""##$$%%&&''(())((''&&%%$%%&&''(())**++,,--?????>>==<<;;::99899::;;<<==>>????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ڞ`!!""##$$%%&&''(())**++,,--..//0000//...-------,,++**))((''&&%%$$##""!!`ٔ`!!""###""!!`!!""##$$%%&&''(())**++,,--..//0011211000//..//001121100//..--,,++**))((''&&%%%$$$$$#########$###"""###""""!!""!!````!!"!!``!!""""""!""##$$%%$$##""b##$$%%&&''(())((''&&%%$$$%%&&''(())**++,,-??????>>==<<;;::999::;;<<==>>?????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`՞`a!""##$$%%&&''(())**++,,--..//001100///..--.--,,++**))((''&&%%$$##""!!`ה`!!""##""!!``!!""##$$%%&&''(())**++,,--..//0011211000////00112221100//..--,,++**))((''&&%%%$$$$$$$$$###$$$###"##$##""!!!!!!`ŏ`a!""!!``!!""#"""""##$$%%%%$$##"##$$%%&&''(())((''&&%%$$#$$%%&&''(())**++,,???????>>==<<;;::9::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ܞ`a!""##$$%%&&''(())**++,,--..//00111100///...--,,++**))((''&&%%$$##""!!`є`!!""#""!!``!!""##$$%%&&''(())**++,,--..//00112211100//0011223221100//..--,,++**))((''&&&%%%%%$$$$$$$$$%$$$###$##""!!``!!!`Ċ`!!""!!``!!""####"##$$%%&&%%$$###$$%%&&''(())((''&&%%$$###$$%%&&''(())**++,????????>>==<<;;:::;;<<==>>????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`˞`!!""##$$%%&&''(())**++,,--..//0011211000//..--,,++**))((''&&%%$$##""!!`К`!!""""!!!``!!""##$$%%&&''(())**++,,--..//001122211100001122333221100//..--,,++**))((''&&&%%%%%%%%%$$$%%%$$$#$##""!!``!`ˍ`aa"""!!```!!""#####$$%%&&&&%%$$#$$%%&&''(())((''&&%%$$##"##$$%%&&''(())**++?????????>>==<<;;:;;<<==>>??????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ה`!!""##$$%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$##""!!`Ӕ`!!"""!!!`̔`!!""##$$%%&&''(())**++,,--..//0011222221100112233433221100//..--,,++**))(('''&&&&&%%%%%%%%%%$%$$$##""!!`͋``ʍ`!!!""!!`ň`!!""###$$%%&&''&&%%$$$%%&&''(hi)((''&&%%$$##"""##$$%%&&''(())**+??????????>>==<<;;;<<==>>????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ł`!!""##$$%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$##""!!`Ж`!!""!!``Ŏ`!!""##$$%%&&''(())**++,,--..//0011222221111223344433221100//..--,,++**))(('''&&&&&&&&&%%%%$$$$$##""!!`Ϗȉ`a!!!!!`ć`!!""##$$%%&&'''&&%%$%%&&''((iih(''&&%%$$##""!""##$$%%&&''(())**???????????>>==<<;<<==>>??????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``ԛ`!!""##$$%%&&''(())**++,,--..//001121100//..--ll++**))((''&&%%$$##""!!`Г`!!""!!`Ñ`!!""##$$%%&&''(())**++,,--..//001122333221122334454433221100//..--,,++**))((('''''&&&&&%%$$$#$###""!!!`͑``!!!!`ņ`!!""##$$%%&&''''&&%%%&&''(())hhg'&&%%$$##""!!!bb##$$%%&&''(())*????????????>>==<<<==>>????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`О`!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!`ԕ`a!""!!`ҏ`!!""##$$%%&&''(())**++,,--..//0011223333222233445554433221100//..--,,++**))(((''''''&&%%$$$#####""!!``ƍ``a`Ć`!!""##$$%%&&''(''&&%&&''(())((g'&&%%$$##""!a`aab"##$$%%&&''(())?????????????>>==<==>>??????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``О`!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!`֒``a!""!a`ˏ`a!""##$$%%&&''(())**++,,--..//001122334433223344556554433221100//..--,,++**)))((((''&&%%$$###"#"""!!`ń``Ň`!!""##$$%%&&''(''&&&''(())((''&&%%$$##""!!``aab"##$$%%&&''(()??????????????>>===>>????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!`ޚ`a!""##$$%%&&''(())**++,,--..//00112221100//..--,,++**))((''&&%%$$##""!!`՛`!!!"""!!`͖`!!""##$$%%&&''(())**++,,--..//0011223344433334455666554433221100//..--,,++**)))((''&&%%$$###"""""!!!`ɇÅ`!!""##$$%%&&''((''&''(())))((''&&%%$$##""!a`a!""##$$%%&&''(())???????????????>>=>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!`ޞ`!!""##$$%%&&''(())**++,,--..//00112221100//..--,,++**))((''&&%%$$##""!!`ԑ`!!!""""!!`Ȕ`!!""##$$%%&&''(())**++,,--..//0011223344443344556666554433221100//..--,,++**))((''&&%%$$##"""!"!!!!`ȉ``!!""##$$%%&&''(('''(())**))((''&&%%$$##""!a!""##$$%%&&''(())*????????????????>>>????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ݞ`!!""##$$%%&&''(())**++,,--..//001122221100//..--,,++**))((''&&%%$$##""!!`ғ``a!"""##""!!`ǒ`a!""##$$%%&&''(())**++,,--..//0011223344554444556666554433221100//..--,,++**))((''&&%%$$##"""!!!!!```ƈ`!!""##$$%%&&''((g(())****))((''&&%%$$##""!""##$$%%&&''(())**?????????????????>?????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ԟ`a!""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%$$##""!!`Ք`!!"""###""!!`ʕ`!!""##$$%%&&''(())**++,,--..//001122334455544556666554433221100//..--,,++**))((''&&%%$$##""!!!`!``ʊ`a!""##$$%%&&''((())*jk+**))((''&&%%$$##"""##$$%%&&''(())**+???????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ў`!!""##$$%%&&''(h))**++,,--..//00112233221100//..--,,++**))((''&&%%$$##""!!`՘`!!""###""!!`̔`!!""##$$%%&&''(())**++,,--..//00112233445555556666554433221100//..--,,++**))((''&&%%$$##""!!a``ˌ`!!""##$$%%&&''(())**kk+**))((''&&%%$$##"##$$%%&&''(())**++???????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ԟ`a!""##$$%%&&''(())**++,,--..//001122333221100//..--,,++**))((''&&%%$$##""!!`Ι`!!""###""!!`ȑ`!!""##$$%%&&''(())**++,,--..//0011223344556556666554433221100//..--,,++**))((''&&%%$$##""!!``̌ϋ`!!""##$$%%&&''(())**+kk+**))((''&&%%$$###$$%%&&''(())**++,???????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ג`!!""##$$%%&&''(())**++,,--..//0011223333221100//..--,,++**))((''&&%%$$##""!!`Ґ`!!""#""!!`ו`a!""##$$%%&&''(())**++,,--..//0011223344556666666554433221100//..--,,++**))((''&&%%$$##""!!`ɏ``a!""##$$%%&&''(())**+kk+**))((''&&%%$$#$$%%&&''(())**++,,???????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`מ`!!""##$$%%&&''(())**++,,--..//00112233433221100//..--,,++**))((''&&%%$$##""!!`Ւ`!!""#""!!`̐`!!""##$$%%&&''(())**++,,--..//001122334455666666554433221100//..--,,++**))((''&&%%$$##""!!`ʼn`!!""##$$%%&&''(())**++++**))((''&&%%$$$%%&&''(())**++,,-???????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`۞````a!""##$$%%&&''(())**++,,--..//001122334433221100//..--,,++**))((''&&%%$$##""!!`Ӛ`!!""##""!!`ʒ`!!""##$$%%&&''(())**++,,--..//001122334455667766554433221100//..--,,++**))((''&&%%$$##""!!`Ɗ`!!""##$$%%&&''(())**++,++**))((''&&%%$%%&&''(())**++,,--???????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ޙ```!!!!!""##$$%%&&''(())**++,,--..//0011223344433221100//..--,,++**))((''&&%%$$##""!!`՚`!!""##""!!`̎`a!""##$$%%&&''(())**++,,--..//0011223344556677766554433221100//..--,,++**))((''&&%%$$##""!!`ƍ`!!""##$$%%&&''(())**++,++**))((''&&%%%&&''(())**++,,--.???????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ޞ`a!!!!!!""##$$%%&&''(())**++,,--..//00112233444433221100//..--,,++**))((''&&%%$$##""!!`Ԗ`a!""###""!!``!!""##$$%%&&''(())**++,,--..//0011223344556677766554433221100//..--,,++**))((''&&%%$$##""!!`ņ`!a""##$$%%&&''(())**++,++**))((''&&%&&''(())**++,,--..???????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ޞ`a!!!"""""##$$%%&&''(())**++,,--..//001122334454433221100//..--,,++**))((''&&%%$$##""!!`ԑ```!!""##$##""!!````a!""##$$%%&&''(())**++,,--..//00112233445566777766554433221100//..--,,++**))((''&&%%$$##""!!`Ŋ`a!""##$$%%&&''(())**++,++**))((''&&&''(())**++,,--../??????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ԟ`!!""""""##$$%%&&''(())**++,,--..//00112233445554433221100//..--,,++**))((''&&%%$$##""!!`җ`!!!""##$$$##""!!!a!!""##$$%%&&''(())**++,,--..//001122334455667787766554433221100//..--,,++**))((''&&%%$$##""!!`Ŋ`!!""##$$%%&&''(())**++++**))((((''&''(())**++,,--..//???????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ܞ`!!""#####$$%%&&''(())**++,,--..//001122334455554433221100//..--,,++**))((''&&%%$$##""!!`Ԗ`!!""##$$%$$##""!!!!""##$$%%&&''(())**++,,--..//0011223344556677887766554433221100//..--,,++**))((''&&%%$$##""!!`ɋ`!!""##$$%%&&''(())**+++**))(('((('''(())**++,,--..//0??????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ך`!!""####$$%%&&''(())**++,,--..//0011223344556554433221100//..--,,++**))((''&&%%$$##""!!`̙`!!""##$$%%$$##""""""##$$%%&&''(())**++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##""!!`ˋ`!!""##$$%%&&''(())**+**))(('''((('(())**++,,--..//00??????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ޞ`!!""##$$$%%&&''(())**++,,--..//001122334455666554433221100//..--,,++**))((''&&%%$$##""!!`nj`!!""##$$%%%$$##""""##$$%%&&''(())**++,,--..//0011223344556677889887766554433221100//..--,,++**))((''&&%%$$##""!!`ˌ`!!""##$$%%&&''(())****))((''&''(('(())**++,,--..//00??????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`՞`a!""##$$$%%&&''(())**++,,--..//00112233445566766554433221100//..--,,++**))((''&&%%$$##""!!`ҍ`a!""##$$%%&%%$$######$$%%&&''(())**++,,--..//00112233445566778899887766554433221100//..--,,++**))((''&&%%$$##""!!`̍`!!""##$$%%&&''(())***))((''&&&'''''(())**++,,--..//0??????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ܞ`a!""##$$%%%&&''(())**++,,--..//001122334455667766554433221100//..--,,++**))((''&&%%$$##""!!`˔`a!""##$$%%&&&%%$$####$$%%&&''(())**++,,--..//0011223344556677889999887766554433221100//..--,,++**))((''&&%%$$##""!!`ʌ`!!""##$$%%&&''(())*j))((''&&%&&''&''(())**++,,--..//??????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`݀`!!""##$$%%&&''(())**++,,--..//00112233445566777766554433221100//..--,,++**))((''&&%%$$##""!!`Ւ`a!""##$$%%&&'&&%%$$$$$$%%&&''(())**++,,--..//00112233445566778899:99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʌ`!!""##$$%%&&''(())*))((''&&%%%&&&&&''(())**++,,--../?????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ԟ``a!""##$$%%&&''(())**++,,--..//001122334455667787766554433221100//..--,,++**))((''&&%%$$##""!!`͋`!!""##$$%%&&''&&%%$$$$%%&&''(())**++,,--..//00112233445566778899::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɋ`a!""##$$%%&&''(())*))((''&&%%$%%&&%&&''(())**++,,--..?????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ԗ`a!""##$$%%&&''(())**++,,--..//00112233445566778887766554433221100//..--,,++**))((''&&%%$$##""!!`ʖ`a!""##$$%%&&''''&&%%%%%%&&''(())**++,,--..//00112233445566778899::::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʋLJ`!!""##$$%%&&''(())))((''&&%%$$$%%%%%&&''(())**++,,--.?????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ќ`a!""##$$%%&&''(())**++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##""!!`ˍ`a!""##$$%%&&''((''&&%%%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ˉ```````†`!!""##$$e%&&''(()))((''&&%%$$#$$%%$%%&&''(())**++,,--?????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʔ`!!""##$$%%&&''(())**++,,--..//001122334455667788887766554433221100//..--,,++**))((''&&%%$$##""!!`ǒ`a!""##$$%%&&''((((''&&&&&&''(())**++,,--..//00112233445566778899::;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ˎ````!!!!!!!`Ň͐`a!""##$$%%&&''(()))((''&&%%$$###$$$$$%%&&''(())**++,,-?????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ș`!!""##$$%%&&''(())**++,,--..//0011223344556677889887766554433221100//..--,,++**))((''&&%%$$##""!!`ȒҒ`a!""##$$%%&&''(())((''&&&&''(())**++,,--..//00112233445566778899::;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ˋ``!!!!!!!!!!!!`Ň`҆`a!""##$$%%&&''(()))((''&&%%$$##"##$$#$$%%&&''(())**++,,??????????????????????????????????????????????????????????>??????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ЗŅ`a!""##$$%%&&''(())**++,,--..//00112233445566778899887766554433221100//..--,,++**))((''&&%%$$##""!!`Lj````!!""##$$%%&&''(())))((''''''(())**++,,--..//00112233445566778899::;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̋``````a!!!!!"""""""!!````΄`!!""##$$%%&&''(())((''&&%%$$##"""#####$$%%&&''(())**++,??????????????????????????????????????????????????>??????>>>????????>????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ҕ````a!""##$$%%&&''(())**++,,--..//0011223344556677889999887766554433221100//..--,,++**))((''&&%%$$##""!!`````!```a!!!""##$$%%&&''(())**))((''''(())**++,,--..//00112233445566778899::;;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``aa!!aa!!"""""""""""!!``!a`ą`a!""##$$%%&&''(())((''&&%%$$##b"!""##"##$$%%&&''(())**++???????????????????????????????????????????>>>>>>>>>>>>>>>=>>>>>>>>>>>>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ś`a```a!""##$$%%&&''(())**++,,--..//00112233445566778899::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`!!!!!!!!!!""##$$%%&&''(())****))(((((())**++,,--..//00112233445566778899::;;;::::9999887766554433221100//..--,,++**))((''&&%%$$##""!!````!!!!!!!""""""######""!!`a``Å`!!""##$$%%&&''(()((''&&%%$$##"baa!"""""##$$%%&&''(())**+??????????????????????????????>??>>>?>>>>>>>>>>>>>=>>>>>>===>>>>>>>>=>>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ˏ`!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!"!!!""""##$$%%&&''(())**++**))(((())**++,,--..//00112233445566778899:::::::::999998887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!""""""""###########""!!````ć`a!""##$$%%&&''(()((''&&%%$$##""!a`!!""!""##$$%%&&''(())**??????????????????????????>?>>>>>>>>>>>>>>>===============<================<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ř`!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!""""""""""##$$%%&&''(())**++++**))))))**++,,--..//001122334455667788899::::::9999888888887766554433221100//..--,,++**))((''&&%%$$##""!!!!"""""""######$$$$$$##""!!`a!`Ç`!!""##$$%%&&''((((''&&%%$$##""!!``a!!!!""##$$%%&&''(())*?????????????????????????>>>>>=>>===>=============<======<<<========<=====<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȓ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""""""#"""####$$%%&&''(())**++,,++**))))**++,,--..//00112233445566778888899:999999988888777777766554433221100//..--,,++**))((''&&%%$$##""""""########$$$$$$$$$$$##""!!!!`Æ`!!""##$$%%&&''(()((''&&%%$$##""!!``!!`!!""##$$%%&&''(())??????????????>>>>>>>>>>>>=>===============<<<<<<<<<<<<<<<;<<<<<<<<<<<<<<<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ζ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<;;::99887766554433221100//..--,,++**))((''&&%%$$###"##########$$%%&&''(())**++,,,,++******++,,--..//00112233445566777777788999999888877777777766666554433221100//..--,,++**))((''&&%%$$##""""#######$$$$$$%%%%%%$$##""!"!!`džņ``a!""##$$%%&&''(())((''&&%%$$##""!!````!!""##$$%%&&''(()?????????????>>>>>>>>>>>>=====<==<<<=<<<<<<<<<<<<<;<<<<<<;;;<<<<<<<<;<<<<<;<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɒ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<;;;;::99887766554433221100//..--,,++**))((''&&%%$$######$###$$$$%%&&''(())**++,,--,,++****++,,--..//0011223344556666677777788988888887777766666666666554433221100//..--,,++**))((''&&%%$$######$$$$$$$$%%%%%%%%%%%$$##""""!!````````!!!""##$$%%&&''(()))((''&&%%$$##""!!`֓`a!""##$$%%&&''(())??????>>>???>>============<=<<<<<<<<<<<<<<<;;;;;;;;;;;;;;;:;;;;;;;;;;;;;;;;;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̑`````a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<;;;;;:::99887766554433221100//..--,,++**))((''&&%%$$$#$$$$$$$$$$%%&&''(())**++,,----,,++++++,,--..//001122334455666666666667788888877776666666665555555554433221100//..--,,++**))((''&&%%$$####$$$$$$$%%%%%%&&&&&&%%$$##"#""!!!!!`a!``a!!!""##$$%%&&''(()))((''&&%%$$##""!!!`ӏ`a!""##$$%%&&''(())*?????>>>>>>>>============<<<<<;<<;;;<;;;;;;;;;;;;;:;;;;;;:::;;;;;;;;:;;;;;:;;;:::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Җ`!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;;;::;::99998887766554433221100//..--,,++**))((''&&%%$$$$$$%$$$%%%%&&''(())**++,,--..--,,++++,,--..//00112233445555555556666667787777777666665555555555555554433221100//..--,,++**))((''&&%%$$$$$$%%%%%%%%&&&&&&&&&&&%%$$####""!!!!!a!!!!!!""##$$%%&&''(()))((''&&%%$$##""!!!a`˄`a!""##$$%%&&''(())*????>>===>>>==<<<<<<<<<<<<;<;;;;;;;;;;;;;;;:::::::::::::::9:::::::::::::::::::::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ō`!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;;;:::::9999887887766554433221100//..--,,++**))((''&&%%%$%%%%%%%%%%&&''(())**++,,--....--,,,,,,--..//0011223344555555555555555667777776666555555555444444444444433221100//..--,,++**))((''&&%%$$$$%%%%%%%&&&&&&''''''&&%%$$#$##"""""!a`!!!`a!""##$$%%&&''(()((''&&%%$$##""!!`a!!``a!""##$$%%&&''(())**???>>========<<<<<<<<<<<<;;;;;:;;:::;:::::::::::::9::::::999::::::::9:::::9:::9999887766554433221100//..--,,++**))((''&&%%$$##""!!`Ŋ````a!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;::::99:998888777777766554433221100//..--,,++**))((''&&%%%%%%&%%%&&&&''(())**++,,--..//..--,,,,--..//001122334444444444444555555667666666655555444444444444444444433221100//..--,,++**))((''&&%%%%%%&&&&&&&&'''''''''''&&%%$$$$##"""!!`````!!""##$$%%&&''(((''&&%%$$##""!!`````a!""##$$%%&&''(())**+??>>==<<<===<<;;;;;;;;;;;;:;:::::::::::::::999999999999999899999999999999999999999887766554433221100//..--,,++**))((''&&%%$$##""!!`̋``!!!""""##$$%%&&''(())**++,,--..//00112233445566778899::::::::::99999888877677766666554433221100//..--,,++**))((''&&&%&&&&&&&&&&''(())**++,,--..////..------..//00112233334444444444444444455666666555544444444433333333333333333221100//..--,,++**))((''&&%%%%&&&&&&&''''''((((((''&&%%$%$$###""!!``!!""##$$%%&&''((''&&%%$$##"""!!```a!""##$$%%&&''(())**++?>>==<<<<<<<<;;;;;;;;;;;;:::::9::999:9999999999999899999988899999999899999899988999887766554433221100//..--,,++**))((''&&%%$$##""!a``ю`!!""###$$%%&&''(())**++,,--..//00112233445566778899::::::::999988988777766666666666554433221100//..--,,++**))((''&&&&&&'&&&''''(())**++,,--..//00//..----..//0011222222333333333333344444455655555554444433333333333333333333333221100//..--,,++**))((''&&&&&&''''''''(((((((((((''&&%%%%$$##""!!`Ή`!!""##$$%%&&''(''&&%%$$##""!!!`Ԍ`a!!""##$$%%&&''(())**++,>>==<<;;;<<<;;::::::::::::9:9999999999999998888888888888887888888888888888888888899887766554433221100//..--,,++**))((''&&%%$$##""!a`Ǒ``a!""###$$%%&&''(())**++,,--..//001122334455667788999999999999998888877776656665556655554433221100//..--,,++**))(('''&''''''''''(())**++,,--..//0000//......//001122222222333333333333333334455555544443333333332222222222222222222221100//..--,,++**))((''&&&&'''''''(((((())))))((''&&%&%%$$##""!!``a!""##$$%%&&''(''&&%%$$##""!!!```a!!""##$$%%&&''(())**++,,>==<<;;;;;;;;::::::::::::999998998889888888888888878888887778888888878888878887788887766554433221100//..--,,++**))((''&&%%$$##""!a``ē`!!""##$$$%%&&''(())**++,,--..//00112233445566778899999999999988887787766665555555555545554433221100//..--,,++**))((''''''('''(((())**++,,--..//001100//....//00111111111122222222222223333334454444444333332222222222222222222222212211100//..--,,++**))((''''''(((((((()))))))))))((''&&&&%%$$##""!!``a!""##$$%%&&''(''&&%%$$##""!!```!!""##$$%%&&''(())**++,,-==<<;;:::;;;::9999999999998988888888888888877777777777777767777777777777777777777887766554433221100//..--,,++**))((''&&%%$$##""!!`ˍ`!!""##$$%%&&''(())**++,,--..//0011223344556677889988888888888888777776666554555444554445554433221100//..--,,++**))((('(((((((((())**++,,--..//00111100//////0011111111111122222222222222222334444443333222222222111111111111111111111111100//..--,,++**))((''''((((((())))))******))((''&'&&%%$$##""!!!!""##$$%%&&''(''&&%%$$##""!!`Ќ``a!""##$$%%&&''(())**++,,--=<<;;::::::::99999999999988888788777877777777777776777777666777777776777776777667777766554433221100//..--,,++**))((''&&%%$$##""!!`Å``!!""##$$%%%&&''(())**++,,--..//00112233445566778888888888888887777667665555444444444443444444433221100//..--,,++**))(((((()((())))**++,,--..//0011221100////001110000000001111111111111222222334333333322222111111111111111111111110110000000//..--,,++**))(((((())))))))***********))((''''&&%%$$##""!!""##$$%%&&''(''&&%%$$##""!!`ԑ`a!!""##$$%%&&''(())**++,,--.<<;;::999:::998888888888887877777777777777766666666666666656666666666666666666666777766554433221100//..--,,++**))((''&&%%$$##""!!``a!!""##$$$$$%%&&''(())**++,,--..//00112233445566778887777777777777766666555544344433344333444443333221100//..--,,++**)))())))))))))**++,,--..//0011222211000000110000000000001111111111111111122333333222211111111100000000000000000000000000000//..--,,++**))(((()))))))******++++++**))(('(''&&%%$$##""""##$$%%&&''(''&&%%$$##""!!`ʇ`!!""##$$%%&&''(())**++,,--..<;;::999999998888888888887777767766676666666666666566666655566666666566666566655666666554433221100//..--,,++**))((''&&%%$$##""!!`Á`a!!""##$$$$$$$%%&&''(())**++,,--..//00112233445566777777777777777666655655444433333333333233333333333221100//..--,,++**))))))*)))****++,,--..//001122111111000000000/////////000000000000011111122322222221111100000000000000000000000/00///////////..--,,++**))))))********+++++++++++**))((((''&&%%$$##""##$$%%&&''(((''&&%%$$##""!a```a!""##$$%%&&''(())**++,,--../;;::99888999887777777777776766666666666666655555555555555545555555555555555555555666666554433221100//..--,,++**))((''&&%%$$##""!a`э``!!""##$####$$%%&&''(())**++,,--..//00112233445566777666666666666665555544443323332223322233333222222221100//..--,,++***)**********++,,--..//00111211110000000000////////////00000000000000000112222221111000000000/////////////////////////////////..--,,++**))))*******++++++,,,,,,++**))()((''&&%%$$####$$%%&&''(()((''&&%%$$##""!!a``a!""##$$%%&&''(())**++,,--..//;::998888888877777777777766666566555655555555555554555555444555555554555554555445555555554433221100//..--,,++**))((''&&%%$$##""!!``!!""#######$$%%&&''(())**++,,--..//00112233445566666666666666655554454433332222222222212222222222222211100//..--,,++******+***++++,,--..//001111110000000////////........./////////////000000112111111100000///////////////////////.//..........///..--,,++******++++++++,,,,,,,,,,,++**))))((''&&%%$$##$$%%&&''(()))((''&&%%$$##""!a!!!""##$$%%&&''(())**++,,--..//0::998877788877666666666666565555555555555554444444444444443444444444444444444444455555554433221100//..--,,++**))((''&&%%$$##""!!``a!""###""""##$$%%&&''(())**++,,--..//00112233445566655555555555555444443333221222111221112222211111111111100//..--,,+++*++++++++++,,--..//000001010000//////////............/////////////////001111110000/////////.....................................--,,++****+++++++,,,,,,------,,++**)*))((''&&%%$$$$%%&&''(())*))((''&&%%$$##b""!!""##$$%%&&''(())**++,,--..//00:9988777777776666666666665555545544454444444444444344444433344444444344444344433444444444332221100//..--,,++**))((''&&%%$$##""!!`̓``a!""###""""""##$$%%&&''(())**++,,--..//00112233445555555555555554444334332222111111111110111111111111110101100//..--,,++++++,+++,,,,--..//0/00000000///////........---------.............//////0010000000/////.......................-..----------.....----,,++++++,,,,,,,,-----------,,++****))((''&&%%$$%%&&''(())***))((''&&%%$$##"""""##$$%%&&''(())**++,,--..//00199887766677766555555555555454444444444444443333333333333332333333333333333333333344444443322221100//..--,,++**))((''&&%%$$##""!!`ǎ`!!""###""!!!!""##$$%%&&''(())**++,,--..//00112233445554444444444444433333222211011100011000111110000000000000000//..--,,,+,,,,,,,,,,--..//0//////0/0////..........------------.................//000000////.........-----------------------------------------,,++++,,,,,,,--------------,,++*+**))((''&&%%%%&&''(())**+**))((''&&%%$$###""##$$%%&&''(())**++,,--..//001198877666666665555555555554444434433343333333333333233333322233333333233333233322333333333221221100//..--,,++**))((''&&%%$$##""!!``a!""###""!!!!!!""##$$%%&&''(())**++,,--..//00112233444444444444444333322322111100000000000/00000000000000/0/0000////..--,,,,,,-,,,----../////.////////.......--------,,,,,,,,,-------------......//0///////.....-----------------------,--,,,,,,,,,,-----,,,,,,,,,,,,--------,,----,,,,,,,,,++++**))((''&&%%&&''(())**+++**))((''&&%%$$#####$$%%&&''(())**++,,--..//0011288776655566655444444444444343333333333333332222222222222221222222222222222222222233333332211121100//..--,,++**))((''&&%%$$##""!!``!!""###""!!````!!""##$$%%&&''(())**++,,--..//001122334443333333333333322222111100/000///00///00000////////////////////..---,----------../////.....././....----------,,,,,,,,,,,,-----------------..//////....---------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,,,,,,,,,,,,,,,,,,,,,,,,+,++**))((''&&&&''(())**++,++**))((''&&%%$$$##$$%%&&''(())**++,,--..//00112287766555555554444444444443333323322232222222222222122222211122222222122222122211222222222110111100//..--,,++**))((''&&%%$$##""!!``!!""##""!!``!!""##$$%%&&''(())**++,,--..//0011223333333333333332222112110000///////////.//////////////././///........------.---....//.....-........-------,,,,,,,,+++++++++,,,,,,,,,,,,,------../.......-----,,,,,,,,,,,,,,,,,,,,,,,+,,++++++++++,,,,,++++++,,,,,,,,,,,,,,++,,,,++++++++++++,++**))((''&&''(())**++,,,++**))((''&&%%$$$$$%%&&''(())**++,,--..//00112237766554445554433333333333323222222222222222111111111111111011111111111111111111112222222110001100/0//..--,,++**))((''&&%%$$##""!!``a!"""##""!a````a!""##$$%%&&''(())**++,,--..//0011223333322222222222222111110000//.///...//.../////....................-....-.................------.-.----,,,,,,,,,,++++++++++++,,,,,,,,,,,,,,,,,--......----,,,,,,,,,+++++++++++++++++++++++++++++++++++++++++++,,,,,++++++++++++++++++++++++++++++**))((''''(())**++,,-,,++**))((''&&%%%$$%%&&''(())**++,,--..//001122337665544444444333333333333222221221112111111111111101111110001111111101111101110011111111100/0000/////..--,,++**))((''&&%%$$##""!!`@`!!!""##""!!!a!!""##$$%%&&''(())**++,,--..//00112233222222222222222111100100////...........-..............-.-....-------.-...............-----,--------,,,,,,,++++++++*********+++++++++++++,,,,,,--.-------,,,,,+++++++++++++++++++++++*++**********+++++******++++++++++++++**++++************+++++**))((''(())**++,,,--,,++**))((''&&%%%%%&&''(())**++,,--..//0011223346655443334443322222222222212111111111111111000000000000000/0000000000000000000000111111100///00//.////..--,,++**))((''&&%%$$##""!!`ŀ@̇`!!!""##""!!!!""##$$%%&&''(())**++,,--..//00112222222221111111111111100000////..-...---..---.....--------------------,------------.---------,,,,,,-,-,,,,++++++++++************+++++++++++++++++,,------,,,,+++++++++*******************************************+++++**********************************))(((())**++,,+,,,,,,++**))((''&&&%%&&''(())**++,,--..//001122334465544333333332222222222221111101100010000000000000/000000///00000000/00000/000//000000000//.////...////..--,,++**))((''&&%%$$##""!!````!!""##""""""##$$%%&&''(())**++,,--..//00112222221111111111111110000//0//....-----------,--------------,-,----,,,,,,,-,---------------,,,,,+,,,,,,,,+++++++********)))))))))*************++++++,,-,,,,,,,+++++***********************)**))))))))))*****))))))**************))****))))))))))))*********))(())**+++++++,,,,,,++**))((''&&&&&''(())**++,,--..//001122334455544332223332211111111111101000000000000000///////////////.//////////////////////0000000//...//..-........--,,++**))((''&&%%$$##""!!a``Ʉ`aa""##""""##$$%%&&''(())**++,,--..//00112221111111100000000000000/////....--,---,,,--,,,-----,,,,,,,,,,,,,,,,,,,,+,,,,,,,,,,,,-,,,,,,,,,++++++,+,++++**********))))))))))))*****************++,,,,,,++++*********)))))))))))))))))))))))))))))))))))))))))))*****))))))))))))))))))))))))))))))))))**))))****++++*+++++++,++**))(('''&&''(())**++,,--..//001122334455544332222222211111111111100000/00///0/////////////.//////...////////./////.///../////////..-....---.......---,,++**))((''&&%%$$##""!!!!``````a!""########$$%%&&''(())**++,,--..//001122111111000000000000000////../..----,,,,,,,,,,,+,,,,,,,,,,,,,,+,+,,,,+++++++,+,,,,,,,,,,,,,,,+++++*++++++++*******))))))))((((((((()))))))))))))******++,+++++++*****)))))))))))))))))))))))())(((((((((()))))(((((())))))))))))))(())))(((((((((((()))))))))))))***********++++++++++**))(('''''(())**++,,--..//001122334455644332211122211000000000000/0///////////////...............-......................///////..---..--,------------,,++**))((''&&%%$$##"""!!!!!!`a!!""##$$####$$%%&&''(())**++,,--..//00112211100000000//////////////.....----,,+,,,+++,,+++,,,,,++++++++++++++++++++*++++++++++++,+++++++++******+*+****))))))))))(((((((((((()))))))))))))))))**++++++****)))))))))((((((((((((((((((((((((((((((((((((((((((()))))(((((((((((((((((((((((((((((((((())))))))))****)*******+++++**))(((''(())**++,,--..//001122334455664332211111111000000000000/////.//.../.............-......---........-.....-...--.........--,----,,,-------,-,,,,,++**))((''&&%%$$##""""!!!!!!!""##$$$$$$$$%%%&&''(())**++,,--..//0011211000000///////////////....--.--,,,,+++++++++++*++++++++++++++*+*++++*******+*+++++++++++++++*****)********)))))))(((((((('''''''''((((((((((((())))))**+*******)))))((((((((((((((((((((((('((''''''''''(((((''''''((((((((((((((''((((''''''''''''((((((((((()))))))))))))********+*++**))((((())**++,,--..//00112233445566733221100011100////////////./...............---------------,----------------------.......--,,,--,,+,,,,,,,,,,,,,,,,++**))((''&&%%$$###""""""!"""##$$%%$$$$%%$%%&&''(())**++,,--..//00111000////////..............-----,,,,++*+++***++***+++++********************)************+*********))))))*)*))))((((((((((''''''''''''((((((((((((((((())******))))((((((((('''''''''''''''''''''''''''''''''''''''''''(((((''''''''''''''''''''''''''''''''''(((((((((())))()))))))*********)))(())**++,,--..//00112233445566773221100000000////////////.....-..---.-------------,------,,,--------,-----,---,,---------,,+,,,,+++,,,,,,,+,+++,,,,++**))((''&&%%$$####"""""""##$$%%%%%$%$$$$%%&&''(())**++,,--..//00100//////...............----,,-,,++++***********)**************)*)****)))))))*)***************)))))())))))))(((((((''''''''&&&&&&&&&'''''''''''''(((((())*)))))))((((('''''''''''''''''''''''&''&&&&&&&&&&'''''&&&&&&''''''''''''''&&''''&&&&&&&&&&&&'''''''''''((((((((((((())))))))*)******)))))**++,,--..//00112233445566778221100///000//............-.---------------,,,,,,,,,,,,,,,+,,,,,,,,,,,,,,,,,,,,,,-------,,+++,,++*++++++++++++++++++++**))((''&&%%$$$######"###$$$$%$%$$$$$#$$%%&&''(())**++,,--..//000///........--------------,,,,,++++**)***)))**)))*****))))))))))))))))))))())))))))))))*)))))))))(((((()()((((''''''''''&&&&&&&&&&&&'''''''''''''''''(())))))(((('''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&''''''''''(((('((((((()))))))))))*))**++,,--..//00112233445566778821100////////............-----,--,,,-,,,,,,,,,,,,,+,,,,,,+++,,,,,,,,+,,,,,+,,,++,,,,,,,,,++*++++***+++++++*+***++++++++**))((''&&%%$$$$#######$$$$$$$$$#$####$$%%&&''(())**++,,--..//0//......---------------,,,,++,++****)))))))))))())))))))))))))()())))((((((()()))))))))))))))((((('(((((((('''''''&&&&&&&&%%%%%%%%%&&&&&&&&&&&&&''''''(()((((((('''''&&&&&&&&&&&&&&&&&&&&&&&%&&%%%%%%%%%%&&&&&%%%%%%&&&&&&&&&&&&&&%%&&&&%%%%%%%%%%%%&&&&&&&&&&&'''''''''''''(((((((()())))))))))**++,,--..//0011223344556677881100//...///..------------,-,,,,,,,,,,,,,,,+++++++++++++++*++++++++++++++++++++++,,,,,,,++***++**)*******************+++**))((''&&%%%$$$$$$#$$$$$##$#$#####"##$$%%&&''(())**++,,--..///...--------,,,,,,,,,,,,,,+++++****))()))((())((()))))(((((((((((((((((((('(((((((((((()(((((((((''''''('(''''&&&&&&&&&&%%%%%%%%%%%%&&&&&&&&&&&&&&&&&''((((((''''&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&''''&'''''''((((((((((())))**++,,--..//00112233445566778100//........------------,,,,,+,,+++,+++++++++++++*++++++***++++++++*+++++*+++**+++++++++**)****)))*******)*)))************))((''&&%%%%$$$$$$$$$#######"#""""##$$%%&&''(())**++,,--../..------,,,,,,,,,,,,,,,++++**+**))))((((((((((('(((((((((((((('('(((('''''''('((((((((((((((('''''&''''''''&&&&&&&%%%%%%%%$$$$$$$$$%%%%%%%%%%%%%&&&&&&''('''''''&&&&&%%%%%%%%%%%%%%%%%%%%%%%$%%$$$$$$$$$$%%%%%$$$$$$%%%%%%%%%%%%%%$$%%%%$$$$$$$$$$$$%%%%%%%%%%%&&&&&&&&&&&&&''''''''('(((((((((())**++,,--..//001122334455667700//..---...--,,,,,,,,,,,,+,+++++++++++++++***************)**********************+++++++**)))**))()))))))))))))))))))****)))))((''&&&%%%%%$$$$$##""#"#"""""!""##$$%%&&''(())**++,,--...---,,,,,,,,++++++++++++++*****))))(('((('''(('''(((((''''''''''''''''''''&''''''''''''('''''''''&&&&&&'&'&&&&%%%%%%%%%%$$$$$$$$$$$$%%%%%%%%%%%%%%%%%&&''''''&&&&%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%&&&&%&&&&&&&'''''''''''(((())**++,,--..//0011223344556670//..--------,,,,,,,,,,,,+++++*++***+*************)******)))********)*****)***))*********))())))((()))))))()((())))))))))))))))((''&&&%%%$$$$$##"""""""!ba!!!""##$$%%&&''(())**++,,--.--,,,,,,+++++++++++++++****))*))(((('''''''''''&''''''''''''''&'&''''&&&&&&&'&'''''''''''''''&&&&&%&&&&&&&&%%%%%%%$$$$$$$$#########$$$$$$$$$$$$$%%%%%%&&'&&&&&&&%%%%%$$$$$$$$$$$$$$$$$$$$$$$#$$##########$$$$$######$$$$$$$$$$$$$$##$$$$############$$$$$$$$$$$%%%%%%%%%%%%%&&&&&&&&'&''''''''''(())**++,,--..//00112233445566//..--,,,---,,++++++++++++*+***************)))))))))))))))())))))))))))))))))))))*******))((())(('((((((((((((((((((())))((((((('''&&%%%$$#####""!!"abaaa!!`!!""##$$%%&&''(())**++,,---,,,++++++++**************)))))((((''&'''&&&''&&&'''''&&&&&&&&&&&&&&&&&&&&%&&&&&&&&&&&&'&&&&&&&&&%%%%%%&%&%%%%$$$$$$$$$$############$$$$$$$$$$$$$$$$$%%&&&&&&%%%%$$$$$$$$$###########################################$$$$$##################################$$$$$$$$$$%%%%$%%%%%%%&&&&&&&&&&&''''(())**++,,--..//0011223344556/..--,,,,,,,,++++++++++++*****)**)))*)))))))))))))())))))((())))))))()))))()))(()))))))))(('(((('''((((((('('''((((((((((((((((''&&&%%$$$#####""!!aaaa!`a```a!""##$$%%&&''(())**++,,-,,++++++***************))))(()((''''&&&&&&&&&&&%&&&&&&&&&&&&&&%&%&&&&%%%%%%%&%&&&&&&&&&&&&&&&%%%%%$%%%%%%%%$$$$$$$########"""""""""#############$$$$$$%%&%%%%%%%$$$$$#######################"##""""""""""#####""""""##############""####""""""""""""###########$$$$$$$$$$$$$%%%%%%%%&%&&&&&&&&&&''(())**++,,--..//001122334455..--,,+++,,,++************)*)))))))))))))))((((((((((((((('(((((((((((((((((((((()))))))(('''((''&'''''''''''''''''''(((('''''''&&&%%$$$##"""""!!``a`a````a!""##$$%%&&''(())**++,,-,,+++********))))))))))))))(((((''''&&%&&&%%%&&%%%&&&&&%%%%%%%%%%%%%%%%%%%%$%%%%%%%%%%%%&%%%%%%%%%$$$$$$%$%$$$$##########""""""""""""#################$$%%%%%%$$$$#########"""""""""""""""""""""""""""""""""""""""""""#####""""""""""""""""""""""""""""""""""##########$$$$#$$$$$$$%%%%%%%%%%%&&&&''(())**++,,--..//00112233445.--,,++++++++************)))))())((()((((((((((((('(((((('''(((((((('((((('(((''(((((((((''&''''&&&'''''''&'&&&''''''''''''''''&&%%%$$###"""""!!```a`a`aa!""##$$%%&&''(())**++,,-,,++******)))))))))))))))((((''(''&&&&%%%%%%%%%%%$%%%%%%%%%%%%%%$%$%%%%$$$$$$$%$%%%%%%%%%%%%%%%$$$$$#$$$$$$$$#######""""""""!!!!!!!!!"""""""""""""######$$%$$$$$$$#####"""""""""""""""""""""""!""!!!!!!!!!!"""""!!!!!!""""""""""""""!!""""!!!!!!!!!!!!"""""""""""#############$$$$$$$$%$%%%%%%%%%%&&''(())**++,,--..//0011223344--,,++***+++**))))))))))))()((((((((((((((('''''''''''''''&''''''''''''''''''''''(((((((''&&&''&&%&&&&&&&&&&&&&&&&&&&''''&&&&&&&%%%$$###""!!!!a!```aaa!!!!""##$$%%&&''(())**++,,-,,++***))))))))(((((((((((((('''''&&&&%%$%%%$$$%%$$$%%%%%$$$$$$$$$$$$$$$$$$$$#$$$$$$$$$$$$%$$$$$$$$$######$#$####""""""""""!!!!!!!!!!!!"""""""""""""""""##$$$$$$####"""""""""!!!!!!!!!!!!!!!!!!!!!!a!!a!!!!!!!!!!!!!!!!!"""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""""""""####"#######$$$$$$$$$$$%%%%&&''(())**++,,--..//001122334-,,++********))))))))))))((((('(('''('''''''''''''&''''''&&&''''''''&'''''&'''&&'''''''''&&%&&&&%%%&&&&&&&%&%%%&&&&&&&&&&&&&&&&%%$$$##"""!!!!a```aa"!"!"""##$$%%&&''(()))**++,,,,++**))))))(((((((((((((((''''&&'&&%%%%$$$$$$$$$$$#$$$$$$$$$$$$$$#$#$$$$#######$#$$$$$$$$$$$$$$$#####"########"""""""!!!!!!!!`````````!!!!!!!!!!!!!""""""##$#######"""""!!!!!!!!!!!!!!!a!!!!!a!`!!``````````!!!!!``````!!!!!!!!!!!!!!``!!!!````````````!!!!!!!!!!!"""""""""""""########$#$$$$$$$$$$%%&&''(())**++,,--..//00112233,,++**)))***))(((((((((((('('''''''''''''''&&&&&&&&&&&&&&&%&&&&&&&&&&&&&&&&&&&&&&'''''''&&%%%&&%%$%%%%%%%%%%%%%%%%%%%&&&&%%%%%%%$$$##"""!!``````aab""""""##$$%%&&''(()))))**++,,++**)))((((((((''''''''''''''&&&&&%%%%$$#$$$###$$###$$$$$####################"############$#########""""""#"#""""!!!!!!!!!a```!!!!!!!!!!!!!!!!!""######""""!!!!!!!!!``````````````````````````!!!!!````````````````````!!!!!!!!!!""""!"""""""###########$$$$%%&&''(())**++,,--..//0011223,++**))))))))(((((((((((('''''&''&&&'&&&&&&&&&&&&&%&&&&&&%%%&&&&&&&&%&&&&&%&&&%%&&&&&&&&&%%$%%%%$$$%%%%%%%$%$$$%%%%%%%%%%%%%%%%$$###""!!!````a!!""#"#"###$$%%&&''((((((())**++++**))(((((('''''''''''''''&&&&%%&%%$$$$###########"##############"#"####"""""""#"###############"""""!""""""""!!!!!!!```````ڛ````````````!!!!!!""#"""""""!!!!!`````ݜܚؗ`````ٙښ```!!!!!!!!!!!!!""""""""#"##########$$%%&&''(())**++,,--..//001122++**))((()))((''''''''''''&'&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%$%%%%%%%%%%%%%%%%%%%%%%&&&&&&&%%$$$%%$$#$$$$$$$$$$$$$$$$$$$%%%%$$$$$$$###""!!!!a``Ϗ`a!!""#######$$%%&&''((((((((())**++**))(((''''''''&&&&&&&&&&&&&&%%%%%$$$$##"###"""##"""#####""""""""""""""""""""!""""""""""""#"""""""""!!!!!!"!"!!!!````לܜ`````!!""""""!!!!````ۛۛ```````!!!!`!!!!!!!"""""""""""####$$%%&&''(())**++,,--..//00112+**))((((((((''''''''''''&&&&&%&&%%%&%%%%%%%%%%%%%$%%%%%%$$$%%%%%%%%$%%%%%$%%%$$%%%%%%%%%$$#$$$$###$$$$$$$#$###$$$$$$$$$$$$$$$$##"""!!``!!!`Җ``aa!"b##$#$$$%%&&''(('''''''(())****))((''''''&&&&&&&&&&&&&&&%%%%$$%$$####"""""""""""!""""""""""""""!"!""""!!!!!!!"!"""""""""""""""!!!!!`a!!!!!!!```ܜ`!!"!!!!!!!`ۜ`````!!!!!!!!"!""""""""""##$$%%&&''(())**++,,--..//0011**))(('''(((''&&&&&&&&&&&&%&%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$#$$$$$$$$$$$$$$$$$$$$$$%%%%%%%$$###$$##"###################$$$$#######"""!a``!a`ؖ``a!b"##$$$%%&&''(('''''''''(())**))(('''&&&&&&&&%%%%%%%%%%%%%%$$$$$####""!"""!!!""!!!"""""!!!!!!!!!!!!!!!!!!!!`!!!!!!!!!!!!"!!!!!!!!!`````!`!`ښ`a!!!!!!!```ڛؘ``````!!!!!!!!!!!""""##$$%%&&''(())**++,,--..//001*))((''''''''&&&&&&&&&&&&%%%%%$%%$$$%$$$$$$$$$$$$$#$$$$$$###$$$$$$$$#$$$$$#$$$##$$$$$$$$$##"####"""#######"#"""################"ba!!a```ל`a!""##$$%%&&''(''&&&&&&&''(())))((''&&&&&&%%%%%%%%%%%%%%%$$$$##$##""""!!!!!!!!!!!`!!!!!a!!!!!!!!`!`!!!!``````!`!!!!!!!!!!!!!!!```````ՙ``a!!!!````ۜ``!`!!!!!!!!!!""##$$%%&&''(())**++,,--..//00))((''&&&'''&&%%%%%%%%%%%%$%$$$$$$$$$$$$$$$###############"######################$$$$$$$##"""##""!"""""""""""""""""""####"""""""aaaa!a```Ә``a!""##$$%%&&'''&&&&&&&&&''(())((''&&&%%%%%%%%$$$$$$$$$$$$$$#####""""!!`!!!```!!``!!!!a````````````````````````a`````ٙܜܜ`aa!!``ۜ````````!!!!""##$$%%&&''(())**++,,--..//0)((''&&&&&&&&%%%%%%%%%%%%$$$$$#$$###$#############"######"""########"#####"###""#########""!""""!!!"""""""!"!!!""""""""""""""""aa``aaa`Ք``ғ`!!""##$$%%&&'&&%%%%%%%&&''((((''&&%%%%%%$$$$$$$$$$$$$$$####""#""!!!a`````````````ٖך۞ژ`ٙ`aa!`חЏ```!!""##$$%%&&''(())**++,,--..//((''&&%%%&&&%%$$$$$$$$$$$$#$###############"""""""""""""""!""""""""""""""""""""""#######""!!abbaa`aa!!!!!!!!!!!!!!!!!""""!!!!!!!````ǃ`a`՘`!!""##$$%%&&&&%%%%%%%%%&&''((''&&%%%$$$$$$$$##############"""""!!!a`ѓؙۙޞݝ`a````ؙ`a!""##$$%%&&''(())**++,,--../(''&&%%%%%%%%$$$$$$$$$$$$#####"##"""#"""""""""""""!""""""!!!""""""""!"""""!"""!!"""""""""!!`aaaa``aaaa!a!`a```!!!!!!!!!!!!!!!!!`````a`֗`a!""##$$%%&&&%%$$$$$$$%%&&''''&&%%$$$$$$###############""""!!b!!````ԗ``ט`!!""##$$%%&&''(())**++,,--../''&&%%$$$%%%$$############"#"""""""""""""""!!!!!!!!!!!!!!a`!!!!!!!!!!!!!!!!!!!!!!""""""ba!``aa``````````````````!!!!````````````````ڜ`!!""##$$%%&%%$$$$$$$$$%%&&''&&%%$$$########""""""""""""""!!!aa`ט`ܔ```a!""##$$%%&&''(())**++,,--..//'&&%%$$$$$$$$############"""""!""!!!"!!!!!!!!!!!!!`!!!!!a``a!aaaaaa`!!a!!`!!!``!!!!!!!!!!a`aa`ԕԖ```````ޞ`a!""##$$%%&%%$$#######$$%%&&&&%%$$######""""""""""""""ba!!!``a`ғؘ````a!aa""##$$%%&&''(())**++,,--..//0&&%%$$###$$$##""""""""""""!"!!!!!!!!!!!!!!!`````````````````````````````````!!!!!!!!!!aaa`ѓӓѓԖ``a!""##$$%%&%%$$#########$$%%&&%%$$###""""""""!!!!!!!!!aaa!!``ۚ``a!!!!!""##$$%%&&''(())**++,,--..//00&%%$$########""""""""""""!!!!!`!!```!``````ۘښ`Д``````````````@ё`a!!""##$$%%&%%$$##"""""""##$$%%%%$$##""""""!!!!!!!!!!!!!!!```ϓӕ`a`a!!!""""##$$%%&&''(())**++,,--..//001%%$$##"""###""!!!!!!!!!!!!`!`````ܝז֔ԕ````a!!""##$$%%&%%$$##"""""""""##$$%%$$##"""!!!!!!!!```````````ז`!!!""""""##$$%%&&''(())**++,,--..//0011%$$##""""""""!!!!!!!!!!!!``ҕٚ``````a!!!!"""##$$%%&%%$$##""!!!!!!!""##$$$$##""!!!!!!````ڙ`!!!"!""###$$%%&&''(())**++,,--..//00112$$##""!!!"""!!``````````a`````````````a!!!!!!!!!"""##$$%%&%%$$##""!!!!!!!!!""##$$##""!!!````ؖ`!!!!aa""##$$%%&&''(())**++,,--..//00112$##""!!!!!!!!```ט͒`!!!!!!!!!"""""###$$%%&%%$$##""!!```````!!""####""!!``ґ```!`aabb##$$%%&&''(())**++,,--..//0011##""!!```!!!!a```͍А@̍```````a!!!`!`aab""""###$$%%&%%$$##""!!``!!""##""!!`͍͌``a!""##$$%%&&''(())**++,,--..//001#""!!````!!!!`a````ϑ@@@Ą``!a!!!!!a```a!""###$$$%%&%%$$##""!!`̏`!!""""!!```ёё```````a`a!""##$$%%&&''(())**++,,--..//0011##""!a````!!!!a!!!!````τ`a!!!"baa`a`aabb###$$dee&&%%$$##""!a`ё`!!""""!a``````a`@@@@@@@`a!!!!!!!!""##$$%%&&''(())**++,,--..//00112 \ No newline at end of file diff --git a/tests/testdata/maps/world/map4x.bin b/tests/testdata/maps/world/map4x.bin new file mode 100644 index 000000000..8fce6cdc5 --- /dev/null +++ b/tests/testdata/maps/world/map4x.bin @@ -0,0 +1 @@ +88776666666655544444443333333332333333333333444444444444444444455544445555555555566666666555555555555554444433221100//..--,,++++++*****))))))))))))((((((('''''''''(())*))((''&&&&&&&''''''&&%%%%&&&&%%%$$$$$##########"""""""""""""!!!!"""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``!!`!!!!!!!!!!!!!!!!!!!!!!!!!!""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!````````````````````````!!!!!!!!!!""###"""####################$$%%&&''(())**++,,--..//001122334433221100//..--,,++**))((''&&&&&&&&&%&&&&&%%%%%%%%%%%$%$%%%%%$$%%$%%%%%%%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$$$$$$$$$$$$$$#$$%%%%%%$$$$$########""####$$####$$$$###$$%%&&''(())**++,,,++**))((''&&&&&&%%$$$$$$%%&&''(())****))((''&&%%$$####$$$$$$$$$####$$$$%%%%%%&&''&&&&&'''''''((((((())********++++++,,--..////////000000000000//////////////0000011221100//..--,,,,-,,+++++++,,+++++,,,,,,,---,,,,++***++,,--..//001122333333333333344555555555555555555555555555544455555555555555554433322222222233445566778899999:::::;;<8776666666655444444333333333322222222333333333333333333344444444444444444455555555556666555555555554444444433221100//..--,,++********)))))))))(())((((((''''''''''''(()))((''&&&&&&&&&&&&&&&%%%%%%&&%%$$$$###########"""""""""""""!!!!!!!!!!!!!!`!!!````````````````````````````````````!```!!``!!!!!!!"""""""!!!!!!!!!!!!!!!!!!"!!!!!!!!```!!`````````!!!!!!""""""""""""""""""""""""""##$$%%&&''(())**++,,--..//0011223333221100//..--,,++**))((''&&%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$%$$$$$$$$$$$$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$$$$$$$$$$$$$####$$%$$$$$#######""""""""######""#########$$%%&&''(())**++,++**))((''&&%%%%%%$$####$$%%&&''(())**))((''&&%%$$######$$#############$$%%%%%%&&&&&&&&&&&&'''''''('(())************++,,--..///////////000000///.....////////////00111100//..--,,++,,,+++++++++++++++++++++,,-,,,,++*****++,,--..//0011222222222233333445555555545555555555444445544444444444444444454433222222222222334455667788999999::::;;776655555555444333333322222222212222222222223333333333333333333444333344444444444555555554444444444444433333221100//..--,,++******)))))(((((((((((('''''''&&&&&&&&&''(()((''&&%%%%%%%&&&&&&%%$$$$%%%%$$$#####""""""""""!!!!!!!!!!!!!````!!!!!``````̘֙`````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!``````````````!!"""!!!""""""""""""""""""""##$$%%&&''(())**++,,--..//00112233221100//..--,,++**))((''&&%%%%%%%%%$%%%%%$$$$$$$$$$$#$#$$$$$##$$#$$$$$$$$%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%$$###############"##$$$$$$#####""""""""!!""""##""""####"""##$$%%&&''(())**+++**))((''&&%%%%%%$$######$$%%&&''(())))((''&&%%$$##""""#########""""####$$$$$$%%&&%%%%%&&&&&&&'''''''(())))))))******++,,--........////////////............../////001100//..--,,++++,++*******++*****+++++++,,,++++**)))**++,,--..//001122222222222223344444444444444444444444444443334444444444444444332221111111112233445566778888899999::;76655555555443333332222222222111111112222222222222222222333333333333333333444444444455554444444444433333333221100//..--,,++**))))))))(((((((((''((''''''&&&&&&&&&&&&''(((''&&%%%%%%%%%%%%%%%$$$$$$%%$$####"""""""""""!!!!!!!!!!!!!```````ʐ͌Ҏ΍`!!!!!!!``````````````````!``````!!!!!!!!!!!!!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//001122221100//..--,,++**))((''&&%%$$$$$$$$$$$$$$$$$$$$###########$#############$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##############""""##$#####"""""""!!!!!!!!""""""!!"""""""""##$$%%&&''(())**+**))((''&&%%$$$$$$##""""##$$%%&&''(())((''&&%%$$##""""""##"""""""""""""##$$$$$$%%%%%%%%%%%%&&&&&&&'&''(())))))))))))**++,,--...........//////...-----............//0000//..--,,++**+++*********************++,++++**)))))**++,,--..//001111111111222223344444444344444444443333344333333333333333333433221111111111112233445566778888889999::6655444444443332222222111111111011111111111122222222222222222223332222333333333334444444433333333333333222221100//..--,,++**))))))(((((''''''''''''&&&&&&&%%%%%%%%%&&''(''&&%%$$$$$$$%%%%%%$$####$$$$###"""""!!!!!!!!!!```````````Ąō`!`````````ʆ@@@@```!!!!```!!!!!!!!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$$$$$$$$#$$$$$###########"#"#####""##"########$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##"""""""""""""""!""######"""""!!!!!!!!``!!!!""!!!!""""!!!""##$$%%&&''(())***))((''&&%%$$$$$$##""""""##$$%%&&''((((''&&%%$$##""!!!!"""""""""!!!!""""######$$%%$$$$$%%%%%%%&&&&&&&''(((((((())))))**++,,--------............--------------.....//00//..--,,++****+**)))))))**)))))*******+++****))((())**++,,--..//001111111111111223333333333333333333333333333222333333333333333322111000000000112233445566777778888899:655444444443322222211111111110000000011111111111111111112222222222222222223333333333444433333333333222222221100//..--,,++**))(((((((('''''''''&&''&&&&&&%%%%%%%%%%%%&&'''&&%%$$$$$$$$$$$$$$$######$$##""""!!!!!!!!!!a``̏``````Ā@@@Ĉ`!`````````````````````!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$####################"""""""""""#"""""""""""""##$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""""""""""""""!!!!""#"""""!!!!!!!``````!!!!!!``aaaa!!!!!""##$$%%&&''(())*))((''&&%%$$######""!!!!""##$$%%&&''((''&&%%$$##""!!!!!!""!!!!!!!!!!!!!""######$$$$$$$$$$$$%%%%%%%&%&&''(((((((((((())**++,,-----------......---,,,,,------------..////..--,,++**))***)))))))))))))))))))))**+****))((((())**++,,--..//0000000000111112233333333233333333332222233222222222222222222322110000000000001122334455667777778888995544333333332221111111000000000/000000000000111111111111111111122211112222222222233333333222222222222221111100//..--,,++**))(((((('''''&&&&&&&&&&&&%%%%%%%$$$$$$$$$%%&&'&&%%$$#######$$$$$$##""""####"""!!!!!```````````````!`яՒ``ŀ`!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$#########"#####"""""""""""!"!"""""!!""!""""""""##$$%%&&''(())**++,,--....--,,++**))((''&&%%$$##""!!!!!!!!!!!!!!!`!!""""""!!!!!````````!!``aaaa```!!""##$$%%&&''(()))((''&&%%$$######""!!!!!!""##$$%%&&''''&&%%$$##""!!````!!!!!!!!!````!!!!""""""##$$#####$$$$$$$%%%%%%%&&''''''''(((((())**++,,,,,,,,------------,,,,,,,,,,,,,,-----..//..--,,++**))))*))((((((())((((()))))))***))))(('''(())**++,,--..//0000000000000112222222222222222222222222222111222222222222222211000/////////001122334455666667777788954433333333221111110000000000////////000000000000000000011111111111111111122222222223333222222222221111111100//..--,,++**))((''''''''&&&&&&&&&%%&&%%%%%%$$$$$$$$$$$$%%&&&%%$$###############""""""##""!!!!```````DŽ```````Ć֔``a!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""""""""""""""""""""!!!!!!!!!!!"!!!!!!!!!!!!!""##$$%%&&''(())**++,,--..--,,++**))((''&&%%$$##""!!!!!!!!!!!!!!```!!"!!!!!`````````!`````!!""##$$%%&&''(()((''&&%%$$##""""""!!````!!""##$$%%&&''&&%%$$##""!!``!!`````````!!""""""############$$$$$$$%$%%&&''''''''''''(())**++,,,,,,,,,,,------,,,+++++,,,,,,,,,,,,--....--,,++**))(()))((((((((((((((((((((())*))))(('''''(())**++,,--..//////////00000112222222212222222222111112211111111111111111121100////////////0011223344556666667777884433222222221110000000/////////.////////////0000000000000000000111000011111111111222222221111111111111100000//..--,,++**))((''''''&&&&&%%%%%%%%%%%%$$$$$$$#########$$%%&%%$$##"""""""######""!!!!""""!!!``Ȍ`````ÀƇ````````͋ˍ`````a!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##"""""""""!"""""!!!!!!!!!!!`!`a!!!!``!!`!!!!!!!!""##$$%%&&''(())**++,,----,,++**))((''&&%%$$##""!!``````````````aa!!!!!`@@@Å```a!""##$$%%&&''((((''&&%%$$##""""""!!``!!""##$$%%&&''&&%%$$##""!a````a``Ԕ`aa!!!!""##"""""#######$$$$$$$%%&&&&&&&&''''''(())**++++++++,,,,,,,,,,,,++++++++++++++,,,,,--..--,,++**))(((()(('''''''(('''''((((((()))((((''&&&''(())**++,,--../////////////001111111111111111111111111111000111111111111111100///.........//001122334455555666667784332222222211000000//////////........///////////////////000000000000000000111111111122221111111111100000000//..--,,++**))((''&&&&&&&&%%%%%%%%%$$%%$$$$$$############$$%%%$$##"""""""""""""""!!!!!!""!!``ː€@@@@@@@```````̍`````a!!!!!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!!!!!!!!!!!!!!!!!!!`````````!``````````!!""##$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!``aa!````À`@€`aa```````a!""##$$%%&&''((((''&&%%$$##""!!!!""!!````!!""##$$%%&&''''&&%%$$##""!!!!!``aa!!!!!""""""""""""#######$#$$%%&&&&&&&&&&&&''(())**+++++++++++,,,,,,+++*****++++++++++++,,----,,++**))((''((('''''''''''''''''''''(()((((''&&&&&''(())**++,,--........../////0011111111011111111110000011000000000000000000100//............//0011223344555555666677332211111111000///////.........-............///////////////////000////000000000001111111100000000000000/////..--,,++**))((''&&&&&&%%%%%$$$$$$$$$$$$#######"""""""""##$$%$$##""!!!!!!!""""""!a````!!!!`@@΋@``a!!``a!!!!!!!!!"""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!!!!!!!!`!!!!!``````Ȓё``Ϗ`a!""##$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!`````````!```@@````a!!!!!!!!!!""##$$%%%&&''(((''&&%%$$##""!!!!!!""!!!!!!""##$$%%&&''((''&&%%$$##""!!a```````!!""!!!!!"""""""#######$$%%%%%%%%&&&&&&''(())********++++++++++++**************+++++,,--,,++**))((''''(''&&&&&&&''&&&&&'''''''(((''''&&%%%&&''(())**++,,--.............//0000000000000000000000000000///0000000000000000//...---------..//0011223344444555556673221111111100//////..........--------...................//////////////////0000000000111100000000000////////..--,,++**))((''&&%%%%%%%%$$$$$$$$$##$$######""""""""""""##$$$##""!!!!!!!!!!!!!!!``!!!`ɐ@@ēՐ```!!!!!!```````„@```a!!!!!"""""""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``````````````ăÌϒ`!!""##$$%%&&''(())**++,,--,,++**))((''&&%%$$##""!!!!!```````a```!``````!``a````````a!!!!""!!!!!!!""##$$$$$%%&&''(''&&%%$$##""!!````!!""!!!!""##$$%%&&''(((''&&%%$$##""!!``!!!!!!!!!!!!"""""""#"##$$%%%%%%%%%%%%&&''(())***********++++++***)))))************++,,,,++**))((''&&'''&&&&&&&&&&&&&&&&&&&&&''(''''&&%%%%%&&''(())**++,,----------.....//00000000/0000000000/////00//////////////////0//..------------..//00112233444444555566221100000000///.......---------,------------...................///....///////////00000000//////////////.....--,,++**))((''&&%%%%%%$$$$$############"""""""!!!!!!!!!""##$##""!!```````!!!!!!!!````a!!!!```ʼnāʀ``````!!!!!!!!!!!!!!```````a!!!""""""""""###$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!`@@ĊĆ```a!""##$$%%&&''(())**++,,----,,++**))((''&&%%$$##""!!!!!!!!!!!!!!````!!!!!!!!!!!!!!!!!!!````!!!!!"""""""""""##$$$$$$$%%&&'''&&%%$$##""!!``!!""""""##$$%%%&&''('''&&%%$$##""!!```a!`````a!!!!!!"""""""##$$$$$$$$%%%%%%&&''(())))))))************))))))))))))))*****++,,++**))((''&&&&'&&%%%%%%%&&%%%%%&&&&&&&'''&&&&%%$$$%%&&''(())**++,,-------------..////////////////////////////...////////////////..---,,,,,,,,,--..//001122333334444455621100000000//......----------,,,,,,,,-------------------..................//////////0000///////////........--,,++**))((''&&%%$$$$$$$$#########""##""""""!!!!!!!!!!!!""###""!!``````!!!!!!!!!!!!!!a```@ǀ````!!!!!!!!!!!`````````ȋ`!`aa!!""""""#######$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!``ǀ@`````````!!!!""##$$%%&&''(())**++,,--..--,,++**))((''&&%%$$##"""""!!!!!!!"!!!!!!!"!!!!!!"!!"!!!!!!!!!!!!"""""##"""""""##$$$####$$%%&&'''&&%%$$##""!!````a!""""""##$$%%%%%&&''''''&&%%$$##""!!``a`````ņ`!!`````!!!!!!!"!""##$$$$$$$$$$$$%%&&''(()))))))))))******)))((((())))))))))))**++++**))((''&&%%&&&%%%%%%%%%%%%%%%%%%%%%&&'&&&&%%$$$$$%%&&''(())**++,,,,,,,,,,-----..////////.//////////.....//................../..--,,,,,,,,,,,,--..//0011223333334444551100////////...-------,,,,,,,,,+,,,,,,,,,,,,-------------------...----...........////////..............-----,,++**))((''&&%%$$$$$$#####""""""""""""!!!!!!!`````````!!""##""!!`````!!!``````````a`ǀdž`!!!!``!```````ғ`a``a!""##########$$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$$##""!!`````!`````!!!!!!a!""##$$%%&&''(())**++,,--....--,,++**))((''&&%%$$##""""""""""""""!!!!"""""""""""""""""""!!!!"""""####################$$%%&&'''&&%%$$##""!!!!!!""######$$$%$$$%%&&'&&&&&%%$$##""""!!!!a``a!!!```````NJ```!!!!!!!""########$$$$$$%%&&''(((((((())))))))))))(((((((((((((()))))**++**))((''&&%%%%&%%$$$$$$$%%$$$$$%%%%%%%&&&%%%%$$###$$%%&&''(())**++,,,,,,,,,,,,,--............................---................--,,,+++++++++,,--..//00112222233333445100////////..------,,,,,,,,,,++++++++,,,,,,,,,,,,,,,,,,,------------------..........////...........--------,,++**))((''&&%%$$########"""""""""!!""!!!!!!```!!""##""!!``!``a!```ʈ`a!!``Ԗ@@@@``!!""######$$$$$$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!``È```!!!!!!!!bbb"##$$%%&&''(())**++,,--.../..--,,++**))((''&&%%$$#####"""""""#"""""""#""""""#""#""""""""""""######$############""""##$$%%&&'''&&%%$$##""!!!!""######$$$$$$$$$%%&&&&&&%%$$##""""""!!"!!!!!!!!!!!````````````ˎ````!`!!""############$$%%&&''((((((((((())))))((('''''(((((((((((())****))((''&&%%$$%%%$$$$$$$$$$$$$$$$$$$$$%%&%%%%$$#####$$%%&&''(())**++++++++++,,,,,--........-..........-----..------------------.--,,++++++++++++,,--..//001122222233334400//........---,,,,,,,+++++++++*++++++++++++,,,,,,,,,,,,,,,,,,,---,,,,-----------........--------------,,,,,++**))((''&&%%$$######"""""!!!!!!!!!!!!`````@@`!!""##""!!!`Á`a``!!!`````Ȁ`!!!!`ÏԖ@@@``!!""##$$$$$$$$$$%%%&&''(())**++,,--..//00112221100//..--,,++**))((''&&%%$$##""!!!`````````!!""""""""##$$%%&&''(())**++,,--........--,,++**))((''&&%%$$##############""""###################""""################"""""""""##$$%%&&'''&&%%$$##""""""##$$$$$$$$#$###$$%%&%%%%%$$##""!!"""""!!!!"bb"!!!!!!!!!!!!!!`Ņ```````!!""""""""######$$%%&&''''''''((((((((((((''''''''''''''((((())**))((''&&%%$$$$%$$#######$$#####$$$$$$$%%%$$$$##"""##$$%%&&''(())**+++++++++++++,,----------------------------,,,----------------,,+++*********++,,--..//0011111222223340//........--,,,,,,++++++++++********+++++++++++++++++++,,,,,,,,,,,,,,,,,,----------....-----------,,,,,,,,++**))((''&&%%$$##""""""""!!!!!!!!!``!!``ƅ`!!""##""!a``!```````````!`````a!!``````````````Ɓ@``!!""aa`ʇ@`!ab"##$$$$$$%%%%%%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&&%%$$##""!!!!`a!```a!!!```aa""""####$$%%&&''(())**++,,-------.....--,,++**))((''&&%%$$$$$#######$#######$######$##$##############""""#""""""""""""!!!!""##$$%%&&'''&&%%$$##""""##$$$$$$$$#######$$%%%%%%$$##""!!!!"""!!`!!"bbb""!!!!!!!!!!!`````````````!`````a`a!""""""""""""""##$$%%&&'''''''''''(((((('''&&&&&''''''''''''(())))((''&&%%$$##$$$#####################$$%$$$$##"""""##$$%%&&''(())**********+++++,,--------,----------,,,,,--,,,,,,,,,,,,,,,,,,-,,++************++,,--..//00111111222233//..--------,,,+++++++*********)************+++++++++++++++++++,,,++++,,,,,,,,,,,--------,,,,,,,,,,,,,,+++++**))((''&&%%$$##""""""!!!!!`````````!`````Ą`a!!!""""!a```!!!!aaaaa``````!!!`````a!!!!``!!!`Æ@@``````!!!""""!!````aab"##$$%%%%%%%%%&&&''(())**++,,--..//001122333221100//..--,,++**))((''&&%%$$##"""!!!!!!!`ƀ`!!!!!``a!""####$$%%&&''(())**++,,,,--------....--,,++**))((''&&%%$$$$$$$$$$$$$$####$$$$$$$$$$$$$$######""#""""""""""""""""!!!!!!!!!""##$$%%&&'''&&%%$$######$$%%%%$$##"#"""##$$%$$$$$##""!!``!!"!!``!!""""!!!!!""!"""!!```!!!``````!a!`!!!!!!!!!!!""""""##$$%%&&&&&&&&''''''''''''&&&&&&&&&&&&&&'''''(())((''&&%%$$####$##"""""""##"""""#######$$$####""!!!""##$$%%&&''(())*************++,,,,,,,,,,,,,,,,,,,,,,,,,,,,+++,,,,,,,,,,,,,,,,++***)))))))))**++,,--..//0000011111223/..--------,,++++++**********))))))))*******************++++++++++++++++++,,,,,,,,,,----,,,,,,,,,,,++++++++**))((''&&%%$$##""!!!!!!!!``Ã`!!!!!````````a!!!!!"""!!``!!!!!!!!!!!!!!!!!!!!```````a!!!!!``````ѐ```a!!!!!!!""#""!a``!!""##$$%%%&&&&&&&''(())**++,,--..//00112233433221100//..--,,++**))((''&&%%$$##""""!""!!!````!!"""!a``````a!""##$$$$%%&&''(())**+++,,,,,,,,,,------.--,,++**))((''&&%%%%%$$$$$$$%$$$$$$$%$$$$$$%$$$######""""""""!!!!"!!!!!!!!!!!!````!!""##$$%%&&'''&&%%$$####$$%%%%$$##"""""""##$$$$$$##""!!``!!"!!`!!""""!!```aa!!!"!!!!!!!``ȉ````!!!!!!!!!!!!!!!""##$$%%&&&&&&&&&&&''''''&&&%%%%%&&&&&&&&&&&&''((((''&&%%$$##""###"""""""""""""""""""""##$####""!!!!!""##$$%%&&''(())))))))))*****++,,,,,,,,+,,,,,,,,,,+++++,,++++++++++++++++++,++**))))))))))))**++,,--..//000000111122..--,,,,,,,,+++*******)))))))))())))))))))))*******************+++****+++++++++++,,,,,,,,++++++++++++++*****))((''&&%%$$##""!!!!!!```Æ`a!``aa!!!`!!!!!!````!!""!!!`````!!!!!!!````!!!``!!!`Ɍ``!!!````````я``!!!!!"""###""!!```!!""##$$%%&&&&&'''(())**++,,--..//0011223344433221100//..--,,++**))((''&&%%$$###"""""""!!``Ɗ`!!!"""""!!!!!``a!!""##$$$$%%&&''(())**++++++++,,,,,,,,--------,,++**))((''&&%%%%%%%%%%%%%%$$$$%%%%%%%%$$$###""""""!!"!!!!!!!!!!!!!!!!`````a!""##$$%%&&''&&&%%$$$$$$%%%%$$##""!"!!!""##$#####""!!```a!"""!!!"!!!!!``a!`!!!!!!!!`Ņ````````````!!!!!!""##$$%%%%%%%%&&&&&&&&&&&&%%%%%%%%%%%%%%&&&&&''((''&&%%$$##""""#""!!!!!!!""!!!!!"""""""###""""!!```!!""##$$%%&&''(())))ii)))))))**++++++++++++++++++++++++++++***++++++++++++++++**)))((((((((())**++,,--../////00000112.--,,,,,,,,++******))))))))))(((((((()))))))))))))))))))******************++++++++++,,,,+++++++++++********))((''&&%%$$##""!!`````ņ```````!!!!!!!```!!!!!!!!`````!```````!a`ɈNj```̍р`!!"""""##$##""!!!```ԕ````````!!""##$$%%&&''''''(())**++,,--..//001122334454433221100//..--,,++**))((''&&%%$$####"##"""!!!````!!!""###""!!!!!!!!""#cd$%%%%&&''(())))*****++++++++++,,,,,,-----,,++**))((''&&&&&%%%%%%%&%%%%%%%&%%%%$$$$##""""""!!!!!!!!````!````````ю`!!""##$$%%&&&&%%&%%$$$$%%%%$$##""!!!!!!!""######""""!!`!!!""!"!!!!!!aa`@```!````````````!!""##$$%%%%%%%%%%%&&&&&&%%%$$$$$%%%%%%%%%%%%&&''''&&%%$$##""!!"""!!!!!!!!!!!!!!!!!!!!!""#""""!!``!!""##$$%%&&''(((((((((()))))**++++++++*++++++++++*****++******************+**))(((((((((((())**++,,--..//////000011--,,++++++++***)))))))((((((((('(((((((((((()))))))))))))))))))***))))***********++++++++**************)))))((''&&%%$$##""!!`ƀ@@```Dž```!!!``!!```!!!``džɈ`!!```ɉ@@@@@@@@@@@@@@@@@@@```!!""""###$$$##""!!!!!``͍``!``!!""##$$%%&&''''((())**++,,--..//00112233445554433221100//..--,,++**))((''&&%%$$$#######""!!!!!```a!"""#####"""""!!"""#cd$%%%%&&''((()))))********++++++++,,,,,,,---,,++**))((''&&&&&&&&&&&&&&%%%%&&%%%$$$###"""!!!!!!``!````΋``a!""##$$%%%&&&%%%%%%$$%%%%%$$##""!!`!```!!""#"""""""""!!!!!!!!!!!!!```````ă`!!""##$$$$$$$$%%%%%%%%%%%%$$$$$$$$$$$$$$%%%%%&&''&&%%$$##""!!!!"!!```````!!`````!!!!!!!"""!!!!!!```!!"""##$$ee&&''(((((((((((((())****************************)))****************))((('''''''''(())**++,,--...../////001-,,++++++++**))))))((((((((((''''''''((((((((((((((((((())))))))))))))))))**********++++***********)))))))))((''&&%%$$##"""!a`@@``ƒ``!!````a!``!!!!!``````@@@@@@@@@@@@@@``````!!!""#####$$%$$##"""!!!!!``````````!``````Ɗ```!!""##$$%%&&''(((())**++,,--..//0011223344556554433221100//..--,,++**))((''&&%%$$$$#$$###"""!!!!!!!"""##$$$##""""""""##$$%%&&&&''(((((((()))))**********++++++,,,,,,-,,++**))(('''''&&&&&&&'&&&&&&&%%%$$####""!!!!!!```֘ѐ````a!!""##$$$$%%%&%%$$%%$$$$%%%$$##""!!```!!""""""!!!!!!!!!!!!`!````ʊȊ`a!""##$$$$$$$$$$$$%%%%%%$$$#####$$$$$$$$$$$$%%&&&&%%$$##""!!``!!!`````````!!"!!!!!!!!!!!!!!""##dde%&&'''''''''''((((())********)**********)))))**))))))))))))))))))*))((''''''''''''(())**++,,--......////00,,++********)))((((((('''''''''&''''''''''''((((((((((((((((((()))(((()))))))))))********))))))))))))))((((((''&&%%$$##"""""!!``````````````Ɔ`!``````aa``````!!`@@@@@@@@@@֙``````!!!""####$$$%%%$$##"""""!!!!!!`````!``!!!!!!!!!!!!``````````!!""##$$%%&&''(())**++,,--..//001122334455666554433221100//..--,,++**))((''&&%%%$$$$$$$##"""""!!!""###$$$$$#####""###$$%%&&&&'''''''((((())))))))********+++++++,,,,-,,++**))((''''''''''''''&&&&%%$$$###"""!!!````ЙՓ````````a!!!!!""######$$$%%%$$$$$$##$$%%%$$##""!!````a!"""!!!!!!!!!````````ʌ`!!""#########$$$$$$$$$$$$##############$$$$$%%&&%%$$##""!!``!`Ĉ`a!!```````!``!!!!""##$$%%&&''''''''''''''(())))))))))))))))))))))))))))((())))))))))))))))(('''&&&&&&&&&''(())**++,,-----.....//0,++********))((((((''''''''''&&&&&&&&'''''''''''''''''''(((((((((((((((((())))))))))****)))))))))))(((((((((''&&%%$$##""!!!!!!!!!!!!!!!`````ŋƉɈ`a``!```````a`Ȉ`!`ćӕ`!!"""###$$$$%%%%%$$###"""""!!!!!!!!!!!!!!!!!"!!!!!!!!!!!```a!""##$$%%&&''(())**++,,--..//001122334455666554433221100//..--,,++**))((''&&%%%%$%%$$$###"""""""###$$%%%$$########$$%%&&'''&&&''''''''((((())))))))))******++++++,,-,,++**))((((('''''''('''&&%%$$$##""""!a``ϕ``````!!!!!!!!!!!!"""########$$$%$$##$$####$$$$$##""!!``a!!"""!!!!!`````ʌʍ`!!"""############$$$$$$###"""""############$$%%&&%%$$##""!!``a`Ć`a`````a!""##$$%%&&&&&&&&&&&'''''(())))))))())))))))))((((())(((((((((((((((((()((''&&&&&&&&&&&&''(())**++,,------....//++**))))))))((('''''''&&&&&&&&&%&&&&&&&&&&&&'''''''''''''''''''(((''''((((((((((())))))))((((((((((((((''''''&&%%$$##""!!!!!!!!!!!!!!!!!!!!a`````@`a!``a!!!!!!!``a!``!a`Ɋˆ`!!"""""##$$$$$%%%%$$#####""""""!!!!!"!!""""""""""""!!!!!!`````!!""##$$%%&&''(())**++,,--..//001122334455666554433221100//..--,,++**))((''&&&%%%%%%%$$#####"""##$$$%%%%%$$$$$##$$$%%&&&&&&&&&&&&&'''''(((((((())))))))*******++++,,,,++***))((((((((((((''&&%%$$###"""!!!`ɒ``a!!!!!!!!!!!!!""""""###"""""###$$$######""##$$$####""!!``a!!!!!!!````ɉ``!!""""""""""""############""""""""""""""#####$$%%&&%%$$##""!!!!!``ȅ``!!a```a!""##$$%%&&&&&&&&&&&&&&''(((((((((((((((((((((((((((('''((((((((((((((((''&&&%%%%%%%%%&&''(())**++,,,,,-----../+**))))))))((''''''&&&&&&&&&&%%%%%%%%&&&&&&&&&&&&&&&&&&&''''''''''''''''''(((((((((())))((((((((((('''''''''&&%%$$##""!!``````````````!!!!`!!!!!``!```````````````a!!!``a!"!!!!!!!````````a!!``!!!````a!"""""""####$$$$%%%$$$#####"""""""""""""""""#"""""""""""!!``````!!""##$$%%&&''(())**++,,--..//00112233445566556554433221100//..--,,++**))((''&&&&%&&%%%$$$#######$$$%%&&&%%$$$$$$$$%%&%%%&&&%%%&&&&&&&&'''''(((((((((())))))******++,,++**))))))))(((((((''&&%%$$###""!!!!`ď```!!!!!!!!""""""""""""####"""""""###$##""##""""#####"c#"""!!!!!!!!!a```!!"""!!""""""""""""######"""!!!!!""""""""""""##$$%%%%$$$$##""!!!!!!``````````````````a!!"!!!```````````a!""##$$%%&%%%%%%%%%%&&&&&''(((((((('(((((((((('''''((''''''''''''''''''(''&&%%%%%%%%%%%%&&''(())**++,,,,,,----..**))(((((((('''&&&&&&&%%%%%%%%%$%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&'''&&&&'''''''''''((((((((''''''''''''''&&&&&&%%$$##""!!`````````!!!!!!``````````!!!!!!!!!!!!!!!!!!!!""""""!!!!!!`````!!!```````````````````````````````````a````````a!!!!!!!!!""#####$$$$$$$$$$$######"""""#""############""""""!!a```a!!!""##$$%%&&''(())**++,,--..//0011223344556655556554433221100//..--,,++**))(('''&&&&&&&%%$$$$$###$$%%%&&&&&%%%%%$$%%%%%%%%%%%%%%%%%%&&&&&''''''''(((((((()))))))****++++**))))))))))))(('''&&%%$$##"""!!!`````a!!!!""""""""""""""######"""!!!!!"""###""""""!!""###""bb"!!!!!``````aa``@@@`!!!!!aa!!!!!!!""""""""""""!!!!!!!!!!!!!!"""""##$$%%$$$$##""aa`!!!!!!!!`a!``!!!!!!!!!!"""!!!!!!!!!!!!!!""##$$%%%%%%%%%%%%%%%%%%&&''''''''''''''''''''''''''''&&&''''''''''''''''&&%%%$$$$$$$$$%%&&''(())**+++++,,,,,--.*))((((((((''&&&&&&%%%%%%%%%%$$$$$$$$%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&''''''''''(((('''''''''''&&&&&&&&&&&%%$$##""!!`̍``!!!!!!!!!!!!!!!!!!!!!!!!!`````!!!""""!!!!```````!!!``a!!!!!!````````!!!!!`````!````!!!!!!!!!""""####$$$$$$$$$$$#################$###########""!!a````!!!!!""##$$%%&&''(())**++,,--..//001122334455665544556554433221100//..--,,++**))((''''&''&&&%%%$$$$$$$%%%&&&&&&&%%%%%%%%%%%$$$%%%$$$%%%%%%%%&&&&&''''''''''(((((())))))**++**))(((((())))(('''&&%%$$##"""!!``ʌ`a!!!!!""""""""#############"""!!!!!!!"""#""!!""!!!!"""""!""!!!!!``````@@@`a!!!!``a!!!!!!!!!!!""""""!!!`````!!!!!!!!!!!!""##$$$$####""!a``!!"!!!!!!``````!!!!"""""""!!!!!!!!!!!""##$$%%%%%$$$$$$$$$$%%%%%&&''''''''&''''''''''&&&&&''&&&&&&&&&&&&&&&&&&'&&%%$$$$$$$$$$$$%%&&''(())**++++++,,,,--))((''''''''&&&%%%%%%%$$$$$$$$$#$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%&&&%%%%&&&&&&&&&&&''''''''&&&&&&&&&&&&&&%%%%&&%%%%$$##""!!`Ä`a```!!!!!!!!!!!!!!"!a`!``a!"""!!!!`NJ`!`ʌ`a!!!`````````````````!!"""""########$$$$$$$$$#####$##$$$$$$$$$$$$######"""!!```!!!!""""##$$%%&&''(())**++,,--..//00112233445566554444556554433221100//..--,,++**))((('''''''&&%%%%%$$$%%&&%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$%%%%%&&&&&&&&''''''''((((((())))****))((((((((()((''&&&%%$$##""!!!```!!!!"""""##############$###""!!!`````!!!"""!!!!aa``!!"""!!!!!`````````Ƈ@@@Ą`````````````a!!!!!!!!!!!`````````!!!!!""##$$######""!!`a!""""""!!````!!"""""""""""""""""""##$$$$$$$$$$$$$$$$$$$$$$%%&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%&&&&&&&&&&&&&&&&%%$$$#########$$%%&&''(())*****+++++,,-)((''''''''&&%%%%%%$$$$$$$$$$########$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%&&&&&&&&&&''''&&&&&&&&&&&%%%%%%%%%%%$$$$##""!!`ɉ````!`!!!!!!``!!!!!```!!"!!`````!`ɋ`a!!``̋@@ёǂ`!!!!""""########$$$$$$$$$$$$$$$$$$$$%$$$$$$$$$$$##"""!!!````a!!"""""##$$%%&&''(())**++,,--..//0011112233445555443344556554433221100//..--,,++**))(((('(('''&&&%%%%%%%&&%%%%%%%%%$%$$$$$$$$###$$$###$$$$$$$$%%%%%&&&&&&&&&&''''''(((((())**))((''''''((((''&&&%%$$##""!!!``‰`!!!""""""########$$$$$$$$###""!!!``!!!"!!``aa``!!!!!`!!`ʋ@@@ÄĄ````!!!!!!``````!!""####"""###""!!!""#"""!!```!!!!!!!!!!!!!""""""####$$$$$$$##########$$$$$%%&&&&&&&&%&&&&&&&&&&%%%%%&&%%%%%%%%%%%%%%%%%%&%%$$############$$%%&&''(())******++++,,((''&&&&&&&&%%%$$$$$$$#########"############$$$$$$$$$$$$$$$$$$$%%%$$$$%%%%%%%%%%%&&&&&&&&%%%%%%%%%%%%%%$$$$%%$$$$##""!!``````̌```````````!`ȋˈ`a!"!!```````˃`!!!`ʋ@@̅@È`!!!!!""""""""######$$$$$$$$%$$%%%%%%%%%%%%$$$$$$###""!!````aa!!""""####$$%%&&''(())**++,,--..//001000112233445544333344556554433221100//..--,,++**)))(((((('''&&&&&%%%%%%%$$$$$$$$$$$####################$$$$$%%%%%%%%&&&&&&&&'''''''(((())))(('''''''''(''&&%%%$$##""!!``Ɉ```!!!""""#####$$$$$$$$$$$$$##"""!!``````!!!```!``a!!!!``!`ń````````!!""##""""""""""!""""""""!!``a````````a!!!!!!!!!!!!!!!!!""""#######################$$%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$%%%%%%%%%%%%%%%%$$###"""""""""##$$%%&&''(()))))*****++,(''&&&&&&&&%%$$$$$$##########""""""""###################$$$$$$$$$$$$$$$$$$%%%%%%%%%%&&&&%%%%%%%%%%%$$$$$$$$$$$####""!!`…```Ɉ`Ȋ````!!!!`„````````!!!!`ȋ@A@ɍ@@Í````!!!!""""""""#######$$$%%%%%%%%%%&%%%%%%%%%%$$##""!!``a!!"""#####$$%%&&''(())**++,,--..//00100000112233444433223344555544332211000//..--,,++**))))((('''&&&&%%&%%%%%$$$$$$$$$#$########"""###"""########$$$$$%%%%%%%%%%&&&&&&''''''(())((''&&&&&&''''&&%%%$$##""!!`Ċ`a!!!"""######$$$$$$$$%%%%$$##"""!!`Ã`!!a```!!````````a!`ŅȊɉ`a!""##""!!!""""""""""""""!!``````````````````!!!!!"""""#######""""""""""#####$$%%%%%%%%$%%%%%%%%%%$$$$$%%$$$$$$$$$$$$$$$$$$%$$##""""""""""""##$$%%&&''(())))))****++''&&%%%%%%%%$$$#######"""""""""!""""""""""""###################$$$####$$$$$$$$$$$%%%%%%%%$$$$$$$$$$$$$$####$$####""!!`ƈ``ȉȋ͎``Ň`!!"!!```Ã`a`ȋ`!!!!!!!!`lj@@@Ȁ``!!!!!!!!""""""#####$$%%%%&&&&&&&&&&&&%%%%%$$##""!!``!!"""####$$$$%%&&''(())**++,,--..//00100///00112233443322223344554433221100////...--,,++***))((''&&&%%%%%%%$$$$$###########""""""""""""""""""""#####$$$$$$$$%%%%%%%%&&&&&&&''''((((''&&&&&&&&&'&&%%$$$##""!!```a!!!"""#####$$$$$$$$$$$$$$$##""!!!!`Ã`!!!!``!`````Ã`!!""""!!!!!!!!!!!!!!!!!!!`ĉ````!!!!"""""""""""""""""""""""##$$$$$$$$$$$$$$$$$$$$$$$$$$$$###$$$$$$$$$$$$$$$$##"""!!!!!!!!!""##$$%%&&''((((()))))**+'&&%%%%%%%%$$######""""""""""!!!!!!!!"""""""""""""""""""##################$$$$$$$$$$%%%%$$$$$$$$$$$###########""""!!`ʉ```ʋ```!!"!!!!````Ã`!`ń`!!!!!!"!!`ɉ@Ӎ``!!!!!!!!"""""""###$$%%&&&&&&'&&&&&&&&&%%$$##""!!```!!""###$$$$$%%&&''(())**++,,--..//00100/////001122333322112233444433221100///....---,,++**))((''&&&%%%%$$%$$$$$#########"#""""""""!!!"""!!!""""""""#####$$$$$$$$$$%%%%%%&&&&&&''((''&&%%%%%%&&&&%%$$$##""!!`Lj`!!""""#"""########$$$$$$$$##""!!!!`Ã`!`````````@`!!"""!!```!!!!!!!!!!!!!!!``!!!!!"""""""!!!!!!!!!!"""""##$$$$$$$$#$$$$$$$$$$#####$$##################$##""!!!!!!!!!!!!""##$$%%&&''(((((())))**&&%%$$$$$$$$###"""""""!!!!!!!!!`!!!!!!!!!!!!"""""""""""""""""""###""""###########$$$$$$$$##############""""##""""""!a`````ˆ`!!``!!""!!!!!!!``````̌`!!""""!!`ɊȀ``````!!!!!!"""""##$$%%&&&&''''''''&&&%%$$##""!!`ŋȀ`!!""##$$%%%%&&''(((())**++,,--..//000//...//0011223322111122334433221100//....---,,,++**))((''&&%%%$$$$$$$#####"""""""""""!!!!!!!!!!!!!!!!!!!!"""""########$$$$$$$$%%%%%%%&&&&''''&&%%%%%%%%%&%%$$####""!!``!!!!!"""""""###############""!!```ƒ`!`Ã```ńÀ`!!!!!!``````````````````````!!!!!!!!!!!!!!!!!!!!!!!""############################"""################""!!!`````````!!""##$$%%&&'''''((((())*&%%$$$$$$$$##""""""!!!!!!!!!!```````!!!!!!!!!!!!!!!!!!!""""""""""""""""""##########$$$$###########"""""""""""!!!"""!!!!!!`ǒ``a!!!```!!!!!"!!!!!!````a``!!!""!!```!!!!!!!"""##$$%%%&&&&&&''''''&&%%$$##""!!`@@`!!""##$$%%%&&'''(('(())**++,,--..//0//.....//00112222110011223333221100//...----,,,++**))((''&&%%%$$$$##$#####"""""""""!"!!!!!!!!```!!!```!!!!!!!!"""""##########$$$$$$%%%%%%&&''&&%%$$$$$$%%%%$$######""!a````!!!!"!!!""""""""########""!!`Ã`````À``!!!!`ÃÃ``!!!!!!!``````````!!!!!""########"##########"""""##""""""""""""""""""#""!!```!!""##$$%%&&''''''(((())%%$$########"""!!!!!!!```````‚```````!!!!!!!!!!!!!!!!!!!"""!!!!"""""""""""########""""""""""""""!!!!""!!!!!"""!!!!!!`````a!!""!!`Ȍ`!!!!!!!!!"!!!```a!!``!!!""!!`````!!!!!""##$$%%%%&&&&&&'''''&&%%$$##""!!````@@@@@`!!""##$$%%&&''''''''(())**++,,--..///..---..//001122110000112233221100//..----,,,+++**))((''&&%%$$$#######"""""!!!!!!!!!!!``````````````!!!!!""""""""########$$$$$$$%%%%&&&&%%$$$$$$$$$%$$##""""##""!!a`ň```!!!!!!!"""""""""""""""!!`ƒ``ăÃ````Ä```````````!!b"""""""""""""""""""""""""""!!!""""""""""""""""!!``!!""##$$%%&&&&&&'''''(()%$$########""!!!!!!```Ã````````````!!!!!!!!!!!!!!!!!!""""""""""####"""""""""""!!!!!!!!!!!```!!"""!!!!!!``!!!!!!""""!a`ƒ`````!!!!ab"!!!!!!!!````!!""!!`ņ```!!!""##$$$%%%%%%&&&''(''&&%%$$##""!!`Ϛ@@@Njπ`!!""##$$%%&&'&&&''&''(())**++,,--../..-----..//00111100//001122221100//..---,,,,+++**))((''&&%%$$$####""#"""""!!!!!!!!!`a`̃````!!!!!""""""""""######$$$$$$%%&&%%$$######$$$$##""""""##""!!!`````!```!!!!!!!!""""""""!!```!``Ãņă`aabbb"b"""!""""""""""!!!!!""!!!!!!!!!!!!!!!!!!"""!!```````````a!""##$$%%&%&&&&&&&''''(($$##""""""""!!!```````````!!!````!!!!!!!!!!!""""""""!!!!!!!!!!!!!!````!!``!!!!!``!!!!!!!!!!!!!"""!!````@@@@@@@````aab"!!!!!!!`Ȉ`!!!"!!``̉``!!""##$$$$%%%%%%&&'''&&%%$$##""!!`@ĐÆ@@@@@`a!""##$$%%&&&&&&&&&&''(())**++,,--...--,,,--..//001100////0011221100//..--,,,,+++***))((''&&%%$$###"""""""!!!!!``````````!!!!!!!!""""""""#######$$$$%%%%$$#########$##""!!!!""##"""!!!!!``````````!```!!!!!!!!!!!!!""!!``Ã`!`…`!!!!!a!!!!!!!!!!!!!!!!!!!!!!```!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""##$$$%%%%%%%%%&&&&&''($##""""""""!!``Ņ```````!!!!!!!!!!""""!!!!!!!!!!!```````ņ`!!!``!!!`````!!!!!!!!!!`ʋʊ`!!!!!!```!``!!!"!!!`````````````Ȅ`!!""###$$$$$$%%%&&'''&&%%$$##""!!`ˏ@ؙπ`!!""##$$%%&&&&%%%&&%&&''(())**++,,--.--,,,,,--..//0000//..//00111100//..--,,,++++***))((''&&%%$$###""""!!"!!!!!`Àǐ```````!!!!!!!!!!""""""######$$%%$$##""""""####""!!!!!!"""""""!!!!!!!!!!!!!!!```````!!!!!!!!!!!!`Ä``Å`!!!!!!!!!`!!!!!!!!!!`````!!```````````````!!!!!!!!!!!!!!!!""###$$$$$%$%%%%%%%&&&&''##""!!!!!!!!`Äю```````!!!!!!!!``````````€Ņ````````````!!!!!!`ćŅ`!!!!!```Ɇ```!!!!!!!!````a````````````````!!""####$$$$$$%%&&'&&%%$$##""!!`ǃ`πޝ```!!""##$$%%%%&%%%%%%%%%&&''(())**++,,---,,+++,,--..//00//....//001100//..--,,++++***)))((''&&%%$$##"""!!!!!!!````ˀ````!!!!!!!!"""""""####$$$$##"""""""""#""!!````!!""""""!!!!!!!!!!!!!!!!``````````!!!!`Ä``Ć``````````````````````ˍ```````!!!!!""""""######$$$$$$$$$%%%%%&&'#""!!!!!!!!``Lj```!!!!`†͑````!!!``…`ąń@`!`!```Å@@@@`!```!!!!!!!`Ì````!````````!!"""######$$$%%&&'&&%%$$##""!!```a`ȃ```!!!!""##$$%%%%%%%%$$$%%$%%&&''(())**++,,-,,+++++,,--..////..--..//0000//..--,,+++****)))((''&&%%$$##"""!!!!``a`À``````!!!!!!""""""##$$##""!!!!!!""""!!``a!!!!!!!!!!!"!!!!!!!!!!!`a`````!!```Ä`!`ńҐŃ```!a``ǐ``!!!!!!!"""""#####$#$$$$$$$%%%%&&""!!```````΍`````````````````ņ````a``ă@@@```!!!!!!``!!`!``a`@`!!"""""######$$%%&&'&&%%$$##""!!!``````a!`ɀ``a!!!!!""##$$%$$$$$%$$$$$$$$$%%&&''(())**++,,,++***++,,--..//..----..//00//..--,,++****)))(((''&&%%$$##""!!!```````!!!!!!!""""####""!!!!!!!!!"!!`ā`!!!!!!````aaa`!!!!!!!```!!`````!``a!`@````Ã```!!!!!!""""""#########$$$$$%%&"!!`̌ʄ```ņń``````Dž```!``a`@@@Ņ`!!!!`ˌ`!!!!``!!!`````!!!!!!""""""###$$%%&&'&&%%$$##""!!!!!``````Ȍ``!!!!!""""##$$$$$$$$$$$$###$$#$$%%&&''(())**++,++*****++,,--....--,,--..////..--,,++***))))(((''&&%%$$##""!!!`ʼn````!!!!!!""##""!a``````!!!"!!```a!``````a````````À```Ã````Ã``!``ÄŅ@Ã````!!!!!"""""#"#######$$$$%%!!```````````a````````````a!!``!``@@@@@Ä@ȇ`!``!`͌`a!"!!``a!!!````@``!!!!!!""""""##$$%%&&'&&%%$$##"""!!`Ɗ```````!!!!""""""##$$$#$#####$#########$$%%&&''(())**+++**)))**++,,--..--,,,,--..//..--,,++**))))((('''&&%%$$##""!!``````!!!!""""!a```!!"!!``a``````ÅȈ`Ņ`Ã``@``!!!!!!"""""""""#####$$%"!a``ˆ``a!``a!`````````````!`!!``````@@ƇƇ`a``Ύ`!!"""!a`a!!!`Ã`†````!!!!!!"""##$$%%&&'&&%%$$##""!!`‚`````!!!!!!!!!"""""""###$$###########"""##"##$$%%&&''(())**+**)))))**++,,----,,++,,--....--,,++**)))(((('''&&%%$$##""!!`@@```!!""""!!`„`!!!!````ƅÆňă`a!`ÃÃ```!!!!!"!"""""""####$$""!!!```ċ```````ʅ``Ņ```@ƒ@@Ȉ```͎`!!"""!a!!!`Ä```Ć``!!!!!!""##$$%%&&&%%$$##""!!`Ȃ```````!!!!!!!!!!!""""#""""""####"#"""""#"""""""""##$$%%&&''(())***))((())**++,,--,,++++,,--..--,,++**))(((('''&&&&&%%$$##""aa`````!!"""!!`Ã`a!``Ɔ`!``ń```!!!!!!!!!"""""##$#""!!!!!```Ć͍ņƆƅ@@@Ƈ``!!"""!"!!``a```a`````!!!""##$$%%&%%$$##""!!`ƍ```!!!!!!!!!!!"""""""""##"""!!"""##"""""""""""!!!""!""##$$%%&&''(())*))((((())**++,,,,++**++,,----,,++**))(((''''&&&&&&%%$$$##""a!!``!!!!!`Ą````a!`Ȋ``a`Ą``!`!!!!!!!""""###""!!!!!!!`ą`!!""""""!!``````a!!!!!``Ć``!!""##$$%%%%$$##""!!`ċ`a!!!!!!!!!"""""""""""###""!!!!!!""""!"!!!!!"!!!!!!!!!""##$$%%&&''(()))(('''(())**++,,++****++,,--,,++**))((''''&&&%%%%%%$$###""!!!`Ê`!!!!```````ć`a!``Ą``````!!!!!""#""!!!!```````````a!""##"#""!!!!!!!!!!!``Ä`a!""##$$%%%%$$##""!!``a!!!"""""""""""#########""!!!``!!!""!!!!!!!!!!!```!!`!!""##$$%%&&''(()(('''''(())**++++**))**++,,,,++**))(('''&&&&%%%%%%$$###""!!``єŇ`a````!``ĄÄ`a``ą@@ņ``!!!!"""!!````!!```!!!""######""!!!!!!!!``ń`a!""##$$%%%%$$##""!!`є``a!""""""""""############""!!````!!!!`!`````a`````!!""##$$%%&&''(((''&&&''(())**++**))))**++,,++**))((''&&&&%%%$$$$$$##"""!!`ȅ````Ň``a```Æ```ą```!!"!!`````ǃ@@``a!!!""##$$##""!!!!!!!!`Ã``a!""##$$%%&%%$$##""!!`ȉ``a!!""""###########$$$$$##""!!`Ȁ`a!```ŏ`!!""##$$%%&&''((''&&&&&''(())****))(())**++++**))((''&&&%%%%$$$$$$##"""!!``!```````````ąÃ`!!!`LjÏÁ`!!"""###$##""!!``!!!!!!``a``̉`a!""##$$%%&&&%%$$##""!!`ǐ``!!!!""##########$$$$$$$$##""!!``ʐ``̌``!!""##$$%%&&''''&&%%%&&''(())**))(((())**++**))((''&&%%%%$$$######""!!!a`ϋņ`!!!!!!`````````Ƅ``Ό``a!"a```````a!!!""""###""!!`````````!!`````a!""##$$%%&&'&&%%$$##""!!```````````!!!!"""####$$$$$$$$$$$%$$##""!!``ċ`!!""##$$%%&&''&&%%%%%&&''(())))((''(())****))((''&&%%%$$$$######""!!!a`Š````````ņ`!``!!`!!!!!!`ȇ````Ŋ``a!!""a`Ê````!!!!""""#""!!`ˆÈ``!!``!!!""##$$%%&&'''&&%%$$##""!!```!!!!!!!!!!!""""##$$$$$$$$$$%%%%%%$$##""!!``````!!""##$$%%&&&&%%$$$%%&&''(())((''''(())**))((''&&%%$$$$###""""""!!`````a!!!!!````````!!!``!````a!``̎```a!!!""#!!``LjÃ``ą```!!!!"""!!`ʋ``!````a!!""##$$%%&&''(''&&%%$$##""!!``a!!!!!!!!!!""""###$$$$%%%%%%%%%%%%%$$##""!!``a!""##$$%%&&&&%%$$$$$%%&&''((((''&&''(())))((''&&%%$$$####""""""!!``!!!!!!!`Ą````Ƈ`````ƀ```!!!!!!!!!`ʍ`!!!!""""""!!a``````````!`Å`!!!!""!!`‡Lj`!!!a!"""##$$%%&&''((''&&%%$$##""!!`À`!!"""""""""""####$$%%%%%%%%%%&&&&&%%$$##""!!```````a!""##$$%%&&&&%%$$###$$%%&&''((''&&&&''(())((''&&%%$$####"""!!!!!!!`Ɂ`!!!!!``Ɔ```!`Ą@```a!!!"!!!!""!!``````!!!!!!"""""!!!!```a!!```!!!`ɉ`a!``Ä```!!""!!``````````Ɔ``!!"""##$$%%&&''(((''&&%%$$##""!!``!!"""""""""####$$$%%%%&&&&&&&&&&&&&%%$$##""!!!!!``̋```a!!""##$$%%&&&&%%$$#####$$%%&&''''&&%%&&''((((''&&%%$$###""""!!!!!!``ύ`a!!!!`Ɔ`````Lj`!!!!!"""""""""!!!!!!````a!!!!!!!!!#"""!!!!!!!!!!!`````ΐ`````a!``„`!!!!``````!!!!!!!!```!!""##$$%%&&''((((''&&%%$$##""!!``̓`!!""#########$$$$%%&&&&&&&&&&'''''&&%%$$##""!!!`‹``a!!!!""##$$%%&&&&%%$$##"""##$$%%&&''&&%%%%&&''((''&&%%$$##""""!!!`````͉`!!```Ň`Ć`!!"""#""""##""!!!!!!!`!!!``````!!!##""""!!!```!!`΍``aaaa!!!````ƃ```!`````a!!!```!!!!!!!!!a```!!""##$$%%&&''(()((''&&%%$$##""!!``a!""########$$$$%%%&&&&'''''''''''''&&%%$$##"""!!```````````!!!!!"""##$$%%&&&&%%$$##"""""##$$%%&&&&%%$$%%&&''''&&%%$$##"""!!!!`΄````!``ņɇ``!!""########""""""!!!!!````$###""!!```Ɏ`!!!!!!"!!`!!``!!````!```!!!!!```a!!!!!!!!!!!a`@`a!""##$$%%&&''(()))((''&&%%$$##""!!`Ê`a!""##$$$$$$$$$%%%%&&''''''''''(((((''&&%%$$##"""!!!!!!!a```````!!!!!!"""""##$$%%&&&&%%$$##""!!!""##$$%%&&%%$$$$%%&&''&&%%$$##""!!!!````a!!!``!!""####$$##"""""""!"!!````$##""!!`lj`!!""""""!!!!!```!!``!!!!!!!!!`````!!!!!!``!!!!!a`р`aa""##$$%%&&''(())*))((''&&%%$$##""!!```!!""##$$$$$$$$%%%%&&&''''(((((((((((((''&&%%$$###""!!!!!!!!!!!!!!!!!!"""""###$$%%&&&&%%$$##""!!!!!""##$$%%%%$$##$$%%&&&&%%$$##""!!!``dž``!!!!`…lj`!!""##$$$$$######"""""!!!!!`````##""!!````!!"""""#""!""!!!!!`Ä`a!!!!```!!`````````!!!!!````Ĉ````!!""##$$%%&&''(())*))((''&&%%$$##""!!`Ő``!!""##$$%%%%%%%%%&&&&''(((((((((()))))((''&&%%$$###""""""""!!!!!!!""""""#####$$%%&&&&%%$$##""!!```!!""##$$%%$$####$$%%&&%%$$##""!!``Ď``a!!"!!`Æ``!!""##$$%%$$#######"#""!!!!!!a!!#""!!```!!!!""######"""""!!!!``a!"!!``!`Ƈǎ```!!!!`!!``dž`!``a!""##$$%%&&''(())***))((''&&%%$$##""!!```!!""##$$%%%%%%%%&&&&'''(((()))))))))))))((''&&%%$$$##""""""""""""""""""#####$$$%%&&&&%%$$##""!!``!!""##$$$$##""##$$%%%%$$##""!!`Ȏ`a!!!""!!```Ј`````````!!""##$$%%%%$$$$$$#####"""""!!!!!""!!``a!!!!""#####$##"##""""!!```a!""!!``a!`„`!!!!!!!!`````````!!""##$$%%&&''(())****))((''&&%%$$##""!!``!!""##$$%%&&&&&&&&''''(())))))))))*****))((''&&%%$$$########"""""""######$$$$$%%&&''&&%%$$##""aa``!!""##$$$$##""""##$$%%$$##""!!`Ò`!!"""""!!`ą``Ȋ```!!!!!!!!!!""##$$%%&&%%$$$$$$$#$##"""""""""""!!```a!!""""##$$$$$$#####""""!!!!!""""!!``a!!!`Ç`!!!!!!!!!!!!!````a!""##$$%%&&''(())**+**))((''&&%%$$##""!!``a!""##$$%%&&&&&&&''''((())))*************))((''&&%%%$$##################$$$$$%%%&&'''&&%%$$##""!!``!!""##$$$##""!!""##$$%$$##""!!``a!""""""!!`„`````````ҋ````Ƅ`````!!!!!!!!!!!!""##$$%%&&&&%%%%%%$$$$$#####""""""!!!!``!!!"""""##$$$$$%$$#$$####""!!!""##""!!a!"!!`ˊ``````!!!!!!!!!!!``a!""##$$%%&&''(())***++**))((''&&%%$$##""!!``!!""##$$%%&&'''''''(((())**********+++++**))((''&&%%%$$$$$$$$#######$$$$$$%%%%%&&''(''&&%%$$##""!!`a!""##$$$##""!!!!""##$$$$##""!!``!!!!"!!!!!`ą`a!!!!!!`ɉ`!!a`ą`a!!!!!!!""""""""""##$$%%&&''&&%%%%%%%$%$$#########!!!!!!``ŀ@Ƒ`a!!"""####$$%%%%%%$$$$$####"""""####""!!"!a``!!`!!""!!!!!`!!""##$$%%&&''(())***++**))((''&&%%$$##""!!```!!""##$$%%&&'''''(((()))****+++++++++++++**))((''&&&%%$$$$$$$$$$$$$$$$$$%%%%%&&&''(((''&&%%$$##""!!!""#######""!!``a!""##$$$##""!!```!!!!!!!!``a!!!!!!!!```!`````!!!!!!""""""""""""##$$%%&&''''&&&&&&%%%%%$$$$$#####!``````Â`NJ@@€`a!"""#####$$%%%%%&%%$%%$$$$##"""####""!""""aa``!``!!"""!!``!!""##$$%%&&''(()))**++**))((''&&%%$$##""!!!```````!!""##$$%%&&''(((((())))**++++++++++,,,,,++**))((''&&&%%%%%%%%$$$$$$$%%%%%%&&&&&''(()((''&&%%$$##""!""#######""!!``!!""##$$##""!!````!```````!!"""""""!a```!!`ƆŽ```!!!""""""""##########$$%%&&''((''&&&&&&&ef%%$$$$$$$$$```````Ή````!!""###$$$$%%%%%&&&%%%%%$$$$#######""!!!"""!!``!``a!"""!!``!!""##$$%%&&''((()))***+**))((''&&%%$$##""!!!!!!!!```a!""##$$%%&&''((((())))***++++,,,,,,,,,,,,,++**))(('''&&%%%%%%%%%%%%%%%%%%&&&&&'''(()))((''&&%%$$##"""###""""""!!!``!!""##$$##""!!```@@@@@@`a!!"""""""""!a!!``͈ƀ``````````!!!!!""""""############$$%%&&''((((''''''&&&ff%%%%%$$$$$!``!`…`a`Ѕ```!!!``````````!!""##$$$$$$$%%%%%&&%&&%%%%$$#####""!!`a!"""!!`Ƈ`!!`a!"""!!`̋`!!""##$$%%&&''(((())***+**))((''&&%%$$##"""!!!!!!!!``a!""##$$%%&&''(()))))****++,,,,,,,,,,-----,,++**))(('''&&&&&&&&%%%%%%%&&&&&&'''''(())*))((''&&%%$$##""##""""""!!!a``!!""##$$$##""!!```````@@@@@@@A@@@ƅɒ``!!!""#####""!!!``ё`````a!!!!!!a``a!!!!"""########$$$$$$$$$$%%&&''(())(('''''''&'&&%%%%%%%%%!!`````!!!```````ˉ`a!````````a!!a!!!!``a!!!!!!````Â`!!!""##$##$$$$$$%%%&&&&&%%%%$$$##""!!``a!"!!`…`!!!!""!!!`ʓ`!!""##$$%%&&'''((()))**+**))((''&&%%$$##""""""""!!!`````a!""##$$%%&&''(())))****+++,,,,-------------,,++**))(((''&&&&&&&&&&&&&&&&&&'''''((())*))((''&&%%$$##""""""!!!!!!``!!`!!""##$$$$##""!!``!!```!!!``````@@@LJŋŏɈ````a!""##""""!!``ё```!`!!!`!!!!!!!!!!a!!"""""######$$$$$$$$$$$$%%&&''(())))(((((('''''&&&&&%%%%%"!!!!!!!"!!!!!!```a!```!!!!!!!!!ab""!!!!!!!!!!!!!!!```!!!!""#######$$$$$%%%%%&&&&%%$$$##""!!`!!"!!`†`!!!!!!!``!!""##$$%%&&''''(()))**+**))((''&&%%$$###""""""""!!!!!!!""##$$%%&&''(())*****++++,,----------.....--,,++**))(((''''''''&&&&&&&''''''((((())*))((''&&%%$$##""!!""!!!!!!``!!!""##$$%$$##""!!``!!!!!!!!````Ņą```````````!!!````aa"""""""!!`ɐ````!!!!!!""""""""!!"""""###$$$$$$$$%%%%%%%%%%&&''(())**))((((((('(''&&&&&&&&&""!!!!!"""!!!!!!`€ƒ„Ā``````a!!!!!!!!""""""""!!"""""""!!!!!!``ˉ````!!""#""######$$$%%%%%%%%%%%%$$##""!a!"!a`Ņ```!!!```ɏ`!!""##$$%%&&&'''((())**+**))((''&&%%$$########"""!!!!!""##$$%%&&''(())****++++,,,----.............--,,++**)))((''''''''''''''''''((((()))*))((''&&%%$$##""!!!!!!``````!!!""##$$%%%$$##""!!``Ȑ``Ĉ`a!"!!!!!`````!!!!!!``a!!`!``a!!````````aa"""""!!!!``͌``!!"!"""""""""""""#####$$$$$$%%%%%%%%%%%%&&''(())****))))))((((('''''&&&&&#"""""""#""""!!````````Ä````!!!!!""""""""""###"""""""""""""""!!!!``Ȅ`!!"""""""#####$$$$$%%%%%%%%%$$##""!"!!````Ì`a!!""##$$%%&&&&''((())**+**))((''&&%%$$$########"""""""##$$%%&&''(())**+++++,,,,--........../////..--,,++**)))(((((((('''''''(((((()))))*))((''&&%%$$##""!!``a!``a!"""##$$%%&%%$$##""!!`͊```!!`ņ````!!a"""!!`Ã``!!!!!!!!!!!!!!!!!!!!"!!`!`````!!!a!!!""""!!!!!`Ȏ``````!!""""########""#####$$$%%%%%%%%&&&&&&&&&&''(())**++**)))))))()(('''''''''##"""""###""""!!``!`!!!!``a``„````!!"""""""""########""#######""""""!!!!````!!"!!""""""###$$$$$$$$$$%%%%$$##""""!!``lj``!!""##$$%%%&&&'''(())**+**))((''&&%%$$$$$$$$###"""""##$$%%&&''(())**++++,,,,---..../////////////..--,,++***))(((((((((((((((((()))))**))((''&&%%$$##""!!````!!!""##$$%%&&%%$$##""!!````!!!!``!!!!`a!""!!``````a!!!!!""""""!!"""!"!!"""!!!!!!!!!!!!!!""""!!!```LJ`!!`a!!!""#"#############$$$$$%%%%%%&&&&&&&&&&&&''(())**++++******)))))((((('''''$#######$####""!!!!!!!!!!!!!`ń`````a!"""##########$$$###############""""!!!!``!!!!!!!!"""""#####$$$$$$$$$$%$$##""""!!!```!!""##$$%%%%&&'''(())**+**))((''&&%%%$$$$$$$$#######$$%%&&''(())**++,,,,,----..//////////00000//..--,,++***))))))))((((((())))))****))((''&&%%$$##"b!!````ȑ`````!!""##$$%%&&%%$$##""!!!```a!!!``!``!!!```!!""!!```a!!`Ņ`a!!!""""""""""""""""""""#""!"!!!!!"""""""""!!``Ň```!!!!""####$$$$$$$$##$$$$$%%%&&&&&&&&''''''''''(())**++,,++*******)*))((((((((($$#####$$$####""!!"!""""!!``````Ȑ`!!""#########$$$$$$$$##$$$$$$$######""""!!!`ˆ`!!``!!!!!!"""##########$$$$$$$##""b!"!!!!`È`!!""##$$$%%%&&&''(())**+**))((''&&%%%%%%%%$$$#####$$%%&&''(())**++,,,,----...////0000000000000//..--,,+++**))))))))))))))))))*****))((''&&%%$$##""a!`Ɍ`!!""##$$%%&&%%$$##""!!!```a!!!!``!`Æ`!!``a!""!!```!!!`Ņ`a!!""""""######""###"#""###""""""""""""""""!!`Ȉ`!!""####$$$$$$$$$$$$$%%%%%&&&&&&''''''''''''(())**++,,,,++++++*****)))))(((((%$$$$$$$$$$####""""""!!!!`Ċ``a`Ɖ`a!""##$$$$$$$$$$%%%$$$$$$$$$$$$$$$####""""!!`@@ȍ``````!!!!!"""""##########$$##""!aa!"b!!``!!""##$$$$$%%&&&''(())**+**))((''&&&%%%%%%%%$$$$$$$%%&&''(())**++,,-----....//00000000001111100//..--,,+++********)))))))******++**))((''&&%%$$##""!!````a!""##$$%%&&&%%$$##"""!!!!!!```Ä`a!`ň@`!``!!"!!`ą``!`Ň`!!""""####################$##"#"""""#####""!!!`ȏ``!!""#####$$%%%%%%%$$%%%%%&&&''''''''(((((((((())**++,,--,,+++++++*+**))))ii)))%%$$$$$$$####"""""!"!!!!``҇`!!!```!!""##$$$$$$$$%%%%%%%%$$%%%%%%%$$$$$$####""!!`‹Ljņ```!!!""""""""""#######""!!a`!!aa!!`ˊ`!!""####$$$%%%&&''(())**+**))((''&&&&&&&&%%%$$$$$%%&&''(())**++,,----....///0000111111111111100//..--,,,++******************+++**))((''&&%%$$##""!!````a!""##$$%%&&'&&%%$$##"""!!!!`Å`aa!``!``!!""!!`ń`Ä``!!"""######$$$$$$##$$$#$##$$$############""!!``Ƈ`!!""###"##$$%%%%%%%%%%&&&&&''''''(((((((((((())**++,,----,,,,,,+++++*****ii)))%%$$$$$$###"""""!!!!!```ъ``!!"!!```!!!""##$$%%%%%%%%%%&&&%%%%%%%%%%%%%%%$$$$###""!!`````!!!!!""""""""""##""!!```a!``!`lj`!!"""#####$$%%%&&''(())**+**))(('''&&&&&&&&%%%%%%%&&''(())**++,,--.....////001111111111222221100//..--,,,++++++++*******+++++++**))((''&&%%$$###""!!`!``!!""##$$%%&&''&&%%$$###""!!```!aa``!!!`!!""!!`ćÄ``!!!""######$$$$$$$$$$$$$$$$$$%$$#$#####$##""!!`ą`!!""#"""##$$%%&&&%%&&&&&'''(((((((())))))))))**++,,--..--,,,,,,,+,++******j**$$$##$$##""""!!!!!`!`Ռ``aa!"""aa`a!!!""##$$%%%%%%%%&&&&&&&&%%&&&&&&&%%%%%%$$$$##""!!!```!!!!!!!!!!"""""""!!`````ć`!!!"""""###$$$%%&&''(())**+**))((''''''''&&&%%%%%&&''(())**++,,--....////000111122222222222221100//..---,,++++++++++++++++++++**))((''&&%%$$#####""!!a``!!""##$$%%%&&'''&&%%$$##""!!`ń`!!``a!"!!!"""!!`Ć`a!!!""###$####$$%%%%%$$%%%$%$$%%%$$$$$$$$$##""!!`Ć`!!""""!""##$$%%&&&&&&'''''(((((())))))))))))**++,,--....------,,,,,+++++**j**$$######"""!!!!!`````a!aa""c""!!!!"""##$$%%&&&&&&&&&&'''&&&&&&&&&&&&&&&%%%%$$$##""!!!``````!!!!!!!!!!""""!!``!````ˋ`!!!!"""""##$$$%%&&''(())**+**))(((''''''''&&&&&&&''(())**++,,--../////000011222222222233333221100//..---,,,,,,,,+++++++,,,++**))((''&&%%$$##"""""!!!!!`‡`!!""##$$%%%&&'&&%%$$$##""!!```````a`Ć`````a!"""!""""!!`Ň`a!!"""##$$##""##$$%%%%%%%%%%%%%%&%%$%$$$$$$##""!!`Ɖ``a!""""!!!""##$$%%&&&'''''((())))))))**********++,,--..//..-------,-,,+++++++++###""##""!!!!```ƀ````a!!!"b"cc#""!""""##$$%%&&&&&&&&''''''''&&'''''''&&&&&&%%%%$$##"""!!a```````!!!!!""""!a```!!!`ʊ``!!!!!"""###$$%%&&''(())**+**))(((((((('''&&&&&''(())**++,,--..////000011122223333333333333221100//...--,,,,,,,,,,,,,,,,++**))((''&&%%$$##"""""!!!````ǀ`!!""##$$$%%&&&%%$$####""!!``````†``!!a!!"!!!!""""!!`Å``!!!"""""####""""##$$%%&%%&&&%&%%&&&%%%%%%$$##""!!`ć`!`a!""""!!`!!""##$$%%&&''((((())))))************++,,--..////......-----,,,,,+++++##""""""!!!``ʀ`!!!!""""##$##""""###$$%%&&''''''''''((('''''''''''''''&&&&%%%$$##"""!!`````a!""""!!!!!``Ɉ``a!!!!""###$$%%&&''(())**+**)))(((((((('''''''(())**++,,--..//0000011112233333333334444433221100//...--------,,,,,,,,++**))((''&&%%$$##""!!!!!````a```!!""##$$$%%&%%$$######""!a`„````````!!!!!!!!!!!!!!```````!!""!""##""!!""##$$%%&&&&&&&&&&'&&%&%%%$$##""!!`ć`!!!""""!!``!!""##$$%%&&''(()))********++++++++++,,--..//00//.......-.--,,,,,,,,,"""!!""!!```````!!"""###$$$##"####$$%%&&''''''''((((((((''(((((((''''''&&&&%%$$###""!!````!!""!!````ʊ```a!!"""##$$%%&&''(())**+**))))))))((('''''(())**++,,--..//000011112223333444444444444433221100///..------------,,++**))((''&&%%$$##""!!!!!`Lj```Ā`!!""###$$%%%$$##"""""""!!``````a!`a!``a!!!!````!!!!```a``!!!!!""""!!!!""##$$%%&&''&'&&'''&&&&%%$$##""!!`È`!!""##""!a`a!""##$$%%&&''(()))******++++++++++++,,--..//0000//////.....-----,,,,,""!!!!!!```a!!!```a!""####$$%$$####$$$%%&&''(((((((((()))(((((((((((((((''''&&&%%$$###""!a``````a!"!!`Ȉ``a!"""##$$%%&&''(())**+***))))))))((((((())**++,,--..//00111112222334444444444555554433221100///........----,,++**))((''&&%%$$##""!!````````ˌ``!!""###$$%$$##"""""""!!!`@```````!!`a!!!``````Ą``@@``!a`!!""!!``!!""##$$%%&&''''''(''&'&&%%$$##""!!`Ȍ`a!""###""!!!""##$$%%&&''(())***++++++++,,,,,,,,,,--..//001100///////./..---------!!!``aa``````!!!!!!!!""###$$$%%%$$#$$$$%%&&''(((((((())))))))(()))))))((((((''''&&%%$$$##""!!````!``!!bb!!``!!!""##$$%%&&''(())**+********)))((((())**++,,--..//00111122223334444555555555555544332211000//........--,,++**))((''&&%%$$##""!!``ƈ```a!`Å`!!"""##$$$##""!!!!!!!!a!`Ã`a````!`````LjƇ@`````!!!!``!!""##$$%%&&''''((('''&&%%$$##""!!`Ō````a!""##$##""!""##$$%%&&''(())***++++++,,,,,,,,,,,,--..//001111000000/////.....-----!!``!a``!!!!``!!"""!!!""##$$$$%%&%%$$$$%%%&&''(())))))))))***)))))))))))))))((((''&&%%$$##""!!````!!"!!!`Å``!!!""##$$%%&&''(())**++********)))))))**++,,--..//0011222223333445555555555666665544332211000///////..--,,++**))((''&&%%$$##""!!`Ɔ`a``!``!!"""##$##""!!!!!!!``````ă`lj@`a`Ē`!!!!``!!""##$$%%&&''((()((''&&%%$$##""!!`Ƌ`!!!!!""##$$$##"""##$$%%&&''(())**+++,,,,,,,,----------..//001122110000000/0//.........```!!a!!!!!!!!""""""""##$$$%%%&&&%%$%%%%&&''(())))))))********))*******))))))((''&&%%$$##""!!`̀`!`„`!!!!`a`†``a!""##$$%%&&''(())**+++++++***)))))**++,,--..//001122223333444555566666666666665544332211100//////..--,,++**))((''&&%%$$##""!!``!!!`````LJ`!!!""###""!!``````ÃĄȀ```!```!!""##$$%%&&''(())((''&&%%$$##""!!`É`!!!!!""##$$%$$##"##$$%%&&''(())**+++,,,,,,------------..//0011222211111100000/////.....``!!"!!""""!!""###"""##$$%%%%&&'&&%%%%&&&''(())**********+++***************)))((''&&%%$$##""!!``!!a````!````!!""##$$%%&&''(())**++++++++*******++,,--..//00112233333444455666666666677777665544332211100000//..--,,++**))((''&&%%$$##""!!``!!``!!!!""#""!!`ˍ``!!""##$$%%&&''(()((''&&%%$$##""!!``!!"""##$$%%%$$###$$%%&&''(())**++,,,--------..........//001122332211111110100/////////```!!!"""""""""""########$$%%%&&&'''&&%&&&&''(())********++++++++**+++++++*****))((''&&%%$$##""!!``!!!``!`a``!!""##$$%%&&''(())**++,,,,+++*****++,,--..//0011223333444455566667777777777777665544332221100000//..--,,++**))((''&&%%$$##""!!``!`Í````!!"""!!``Ņ`!!""##$$%%&&''(())((''&&%%$$##""!!`ą``a!"""##$$%%&%%$$#$$%%&&''(())**++,,,------............//00112233332222221111100000/////!!!!!""#""####""##$$$###$$%%&&&&''(''&&&&'''(())**++++++++++,,,+++++++++++++++**))((''&&%%$$##""!!``!!!!````!a!`Æ`!!""##$$%%&&''(())**++,,,,,,+++++++,,--..//00112233444445555667777777777888887766554433222111100//..--,,++**))((''&&%%$$##""!!``a!!``ʊ`!!""!!`‚`dž`!!""##$$%%&&''(())((''&&%%$$##""!!`Ñ``!!!""###$$%%&&&%%$$$%%&&''(())**++,,---........//////////00112233443322222221211000000000!!!"""###########$$$$$$$$%%&&&'''(((''&''''(())**++++++++,,,,,,,,++,,,,,,,+++++**))((''&&%%$$##""!!```!!!!````!!a```!!""##$$%%&&''(())**++,,-,,,+++++,,--..//00112233444455556667777888888888888877665544333221100//..--,,++**))((''&&%%$$##""!!``ɋ`!!```Ћ`!!"!!!`‚`Ɇ`!!""##$$%%&&''(())((''&&%%$$##""!!``!!!""###$$%%&&'&&%%$%%&&''(())**++,,---......////////////001122334444333333222221111100000"""""##$##$$$$##$$%%%$$$%%&&''''(()((''''((())**++,,,,,,,,,,---,,,,,,,,,,,,,,,++**))((''&&%%$$##""!!!``!!!!a`É`!!``Æ`a!""##$$%%&&''(())**++,,----,,,,,,,--..//00112233445555566667788888888889999887766554433221100//..--,,++**))((''&&%%$$##""!!`Ȉ``a!`ȍ`!!!!!`‚`!!""##$$%%&&''(()))((''&&%%$$##""!!`ɐ`a!"""##$$$%%&&'''&&%%%&&''(())**++,,--...////////000000000011223344554433333332322111111111"""###$$$$$$$$$$$%%%%%%%%&&'''((()))(('(((())**++,,,,,,,,--------,,-------,,,,,++**))((''&&%%$$##""!!!`a!""!!``!a``a!""##$$%%&&''(())**++,,-----,,,,,--..//0011223344555566667778888999999999999887766554433221100//..--,,++**))((''&&%%$$##""!!`````a!!!```!!!!````Ň`!!""##$$%%&&''(())(((''&&%%$$##""!!`Ӊ`a!"""##$$$%%&&''(''&&%&&''(())**++,,--...//////000000000000112233445555444444333332222211111#####$$%$$%%%%$$%%&&&%%%&&''(((())*))(((()))**++,,----------...---------------,,++**))((''&&%%$$##"""!!!""""!!```À`!!""##$$%%&&''(())**++,,--.-------..//001122334455666667777889999999999::::99887766554433221100//..--,,++**))((''&&%%$$##""!a`````a!!!!!"!!````!!```a!`ˍ`!!""##$$%%&&''((((((''&&%%$$##""!!`χ`a!""###$$%%%&&''(((''&&&''(())**++,,--..///00000000111111111122334455665544444443433222222222###$$$%%%%%%%%%%%&&&&&&&&''((()))***))())))**++,,--------........--.......-----,,++**))((''&&%%$$##"""!""#""!!``††````̆`!!""##$$%%&&''(())**++,,--..-----..//001122334455666677778889999::::::::::::99887766554433221100//..--,,++**))((''&&%%$$##""!!a!!!!!!!"""!!!``ɈŅ`a``ă`!!`͍`!!""##$$%%&&''((('(''&&%%$$##""!a```!!""###$$%%%&&''(()((''&''(())**++,,--..///000000111111111111223344556666555555444443333322222$$$$$%%&%%&&&&%%&&'''&&&''(())))**+**))))***++,,--..........///...............--,,++**))((''&&%%$$###"""#""!a`ɀ``!!`ʍ`!!"""##$$%%&&''(())**++,,--.......//0011223344556677777888899::::::::::;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!""""""!!!`ˊ````a`Ń`!!`ˊ`!!""##$$%%&&''((''''&&%%$$##""!a```!!""##$$$%%&&&''(()))(('''(())**++,,--..//00011111111222222222233445566776655555554544333333333$$$%%%&&&&&&&&&&&''''''''(()))***+++**)****++,,--........////////..///////.....--,,++**))((''&&%%$$###"###""!!`͌Å``a!!`̒``a!!!!""##$$%%&&''(())**++,,--.....//0011223344556677778888999::::;;;;;;;;;;;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""""""""!!`````````a!`a!!`Ƈ`!!!`Ά`!!""##$$%%&&''''&'&&%%$$##""!!``!!!""##$$$%%&&&''(())*))(('(())**++,,--..//000111111222222222222334455667777666666555554444433333%%%%%&&'&&''''&&''((('''(())****++,++****+++,,--..//////////000///////////////..--,,++**))((''&&%%$$$#####""!!`̍````````````````a!!!!`ь`a!!!!!""##$$%%&&''(())**++,,--..///0011223344556677888889999::;;;;;;;;;;<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""##""!a``````!!!!!!!!!!```dž`!!`ӄ`!!""##$$%%&&'''&&&&%%$$##""!!``!!!""##$$%%%&&'''(())***))((())**++,,--..//0011122222222333333333344556677887766666665655444444444%%%&&&'''''''''''(((((((())***+++,,,++*++++,,--..////////00000000//0000000/////..--,,++**))((''&&%%$$$#$$##""!!```Ë`aa!!!``````!!!!!!!!`ы`````!!""##$$%%&&''(())**++,,--..//00112233445566778889999:::;;;;<<<<<<<<<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$#########""aa``a!!!!!!`a```!!`Ɋ`!!`υ`!!""##$$%%&&&'&&%&%%$$$##""aaa``!!"""##$$%%%&&'''(())**+**))())**++,,--..//00111222222333333333333445566778888777777666665555544444&&&&&''(''((((''(()))((())**++++,,-,,++++,,,--..//0000000000111000000000000000//..--,,++**))((''&&%%%$$$$$##""!!!!``!`````````!!!!!"!!`͇`!!""##$$%%&&''(())**++,,--..//00112233445566778899::::;;<<<<<<<<<<====<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####$$##""!!!!!!!!!`````!!`҂`!!""##$$%%&&&&%%%%$$$##""!!`aa!!"""##$$%%&&&''((())**+++**)))**++,,--..//001122233333333444444444455667788998877777776766555555555&&&'''((((((((((())))))))**+++,,,---,,+,,,,--..//000000001111111100111111100000//..--,,++**))((''&&%%%$%%$$##""!!!!`@`````!```!!""!!!`Î`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;<<<<============<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$$$##""!!!!!!``!``ljƉ`!!`ď```a!""##$$%%&&%&%%$%$$###""!!``!!""###$$%%&&&''((())**++,++**)**++,,--..//0011222333333444444444444556677889999888888777776666655555'''''(()(())))(())***)))**++,,,,--.--,,,,---..//00111111111122211111111111111100//..--,,++**))((''&&&%%%%%$$##""""!!```̍```̉`!!````!!""!!``ʎ``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=========>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$%$$##""!!````````Ƌ`!!`ʏ`!!!ab"##$$%%%%%%%%$$$$#####""aa`!!""###$$%%&&'''(()))**++,,,++***++,,--..//00112233344444444555555555566778899::9988888887877666666666'''((()))))))))))********++,,,---...--,----..//0011111111222222221122222221111100//..--,,++**))((''&&&%&&%%$$##""""!!!!`@@@@@@@@я΋`!!!!!!!""!!``̏`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>>>>>>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%$$##""!!`Ɋƈ`!!!!``!!!bb##$$%%%%%%$%$$#$##"####""a!!""##$$$%%&&'''(()))**++,,-,,++*++,,--..//00112233344444455555555555566778899::::999999888887777766666((((())*))****))**+++***++,,----../..----...//001122222222223332222222222222221100//..--,,++**))(('''&&&&&%%$$####""!!!`ǐ@@A@ˉ``!!"!!!!!"""!!`ϑ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>>>>????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%$$##""!!``!!!!``a!"""##$$%%%%$$$$$$####"""##cc""!""##$$$%%&&''((())***++,,---,,+++,,--..//00112233444555555556666666666778899::;;::99999998988777777777((()))***********++++++++,,---...///..-....//00112222222233333333223333333222221100//..--,,++**))(('''&''&&%%$$####"""!!`Β@@@@̏`!!""!!`a!!!!`€`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&&%%$$##""!!```!!"!!``!!""##$$%%%%$$$$#$##"#""!""#cc#"""##$$%%%&&''((())***++,,--.--,,+,,--..//00112233444555555666666666666778899::;;;;::::::999998888877777)))))**+**++++**++,,,+++,,--....//0//....///0011223333333333444333333333333333221100//..--,,++**))((('''''&&%%$$$$##""!!`Ǎ@@A@@@@͎`!!!!!!``a!!!!``````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&&%%$$##""!!````a!!"!!`lj`!!""##$$%$$$######""""!!!b"c###"##$$%%%&&''(()))**+++,,--...--,,,--..//00112233445556666666677777777778899::;;<<;;:::::::9:99888888888)))***+++++++++++,,,,,,,,--...///000//.////001122333333334444444433444444433333221100//..--,,++**))((('((''&&%%$$$##""!!`@@@@@AA@͏`!a!!!!a`!!`a!!!!!!!!!!````€`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))(('''&&&%%%%$$##""!!!!```‚`!!""!!`ɍ`!!""##$$$$####"#""!"!!`aab"#####$$%%&&&''(()))**+++,,--../..--,--..//00112233445556666667777777777778899::;;<<<<;;;;;;:::::9999988888*****++,++,,,,++,,---,,,--..////00100////000112233444444444455544444444444444433221100//..--,,++**)))(((((''&&%%%$$##""!!`ƍ@@@@@@Ό@@@@@@@A@͎````````a!``!!!!!!!!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%%$$##""!!!!!```@@@@@@@@`!!"""!!`΄`!!""##$###""""""!!!!``a!""###$$%%&&&''(())***++,,,--..///..---..//00112233445566677777777888888888899::;;<<==<<;;;;;;;:;::999999999***+++,,,,,,,,,,,--------..///00011100/000011223344444444555555554455555554444433221100//..--,,++**)))())((''&&%%$$##""!!`ȏЏ@@@ʊ````!!"""""!!````!!````a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$$$$$$$##""""!!!````````@@@A@‚`!!""""!!````!!""#####""""!"!!`!a!`a!""##$$$%%&&'''(())***++,,,--..//0//..-..//00112233445566677777788888888888899::;;<<====<<<<<<;;;;;:::::99999+++++,,-,,----,,--...---..//000011211000011122334455555555556665555555555555554433221100//..--,,++***))))((''&&%%$$##""!!`ȇɉȈ``ȁ`!!"""""!!!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$$$$$##"""""!!``a```!!!!!`@A@‚`!!""""!!``a``!!""###"""!!!!!!``a!!!""##$$$%%&&'''(())**+++,,---..//000//...//00112233445566777888888889999999999::;;<<==>>==<<<<<<<;<;;:::::::::+++,,,-----------........//00011122211011112233445555555566666666556666666555554433221100//..--,,++***)))((''&&%%$$##""!!`Ȑ@@@@@ɉ@```!!""##""!!!!""!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$##############"""!!`Å`!!`````!!`!!!`ƒ@A@`!!""#""!!!`a!!`a!"""#""""!!!!`!``a!"!""##$$%%%&&''((())**+++,,---..//00100//.//00112233445566777888888999999999999::;;<<==>>>>======<<<<<;;;;;:::::,,,,,--.--....--..///...//0011112232211112223344556666666666777666666666666666554433221100//..--,,+++**))((''&&%%$$##""!!`ȏ@@@@@@A@@@@@ɉȉLj```!!""####""""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#################""!!```Ϗ``!!!!!`Ą``````‚@@@@@@@`!!""#""!a````!!!!"""""""!!!````a`!!""""##$$%%%&&''((())**++,,,--...//0011100///001122334455667788899999999::::::::::;;<<==>>??>>=======<=<<;;;;;;;;;,,,---...........////////001112223332212222334455666666667777777766777777766666554433221100//..--,,++**))((''&&%%$$##""!!`φ@@@@@@@ɉ```ǀ`!!!""##$$##""""##""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""""""""""##""#""!!`Ă`!`˃`!!""!!a``DŽ@@ƒ``!!""#""!!``!!!"""!"!!!!```a!!!""#"##$$%%&&&''(()))**++,,,--...//001121100/0011223344556677888999999::::::::::::;;<<==>>????>>>>>>=====<<<<<;;;;;-----../..////..//000///0011222233433222233344556677777777778887777777777777766554433221100//..--,,++**))((''&&%%$$##""!!`ʅ@@͎@@ɉ@Ɋ```Ɉ```!!!""##$$$$############$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""""""""""""""""!!`Ą`!!``!!""""!!``Е```a`ʋ@@@@‚`a!!""###""!!``ˌ`!!!!!!!!!```a!!"!""####$$%%&&&''(()))**++,,---..///0011222110001122334455667788999::::::::;;;;;;;;;;<<==>>??????>>>>>>>=>==<<<<<<<<<---...///////////00000000112223334443323333445566777777778888888877888888877766554433221100//..--,,++**))((''&&%%$$##""!!`ψ@@͎@@ɋА````Ɇ````!!!!"""##$$%%$$####$$####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!!!!!!!!""!!"""!!`ŅNj`!!!```!!""#""!!````!a!!!``Ǝ@A@@ą`!!""##$##""!!`Ҋ``!!!`!````!!!""""##$#$$%%&&'''(())***++,,---..///0011223221101122334455667788999::::::;;;;;;;;;;;;<<==>>????????????>>>>>=====<<<<<.....//0//0000//001110001122333344544333344455667788888888889998888888888887766554433221100//..--,,++**))((''&&%%$$##""!!`ˇ@@ˍ@@@ʌƆ``a!!`Ň``!!!!!!!"""##$$%%%%$$$$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!!!!!!!!!!!!!!`````!!!``!!!""###""!!```a!!!!!"!!!``@@@Ć``!!""##$##""!!!`͌``````a!!"""#"##$$$$%%&&'''(())***++,,--...//0001122333221112233445566778899:::;;;;;;;;<<<<<<<<<<==>>???????????????>?>>=========...///0000000000011111111223334445554434444556677888888889999999988999999887766554433221100//..--,,++**))((''&&%%$$##""!!`͎@@ˍ@@@@ʍ@@@Ɔ``a!!!!```!!!!!!""""###$$%%&&%%$$$$%%$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``````````!!``!!!!`ń`!!```!!!`ʎ`!!""##$##""!!!!!!!"""""!!!!`ɑ@@`!!""##$##""!!!`ˇ@``aa!!"""####$$%$%%&&''((())**+++,,--...//0001122334332212233445566778899:::;;;;;;<<<<<<<<<<<<==>>???????????????????>>>>>=====/////0010011110011222111223344445565544445556677889999999999:::999999999887766554433221100//..--,,++**))((''&&%%$$##""!!`ǎ@@ʊ@@̍@@@@@ƈ```!!!!""!!``a!!!"""""""###$$%%&&&&%%%%%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````````Lj```a!!!!`ʍ`!!!````!!""##$###""!!!""""""#"""!!!``Ə@@`!!""##$##""!!```Ȏ`aaaa"""###$#$$%%%%&&''((())**+++,,--..///0011122334443322233445566778899::;;;<<<<<<<<==========>>?????????????????????>>>>>>>>>///000111111111112222222233444555666554555566778899999999::::::::99:::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɒ@@Ɋ@@ˋ@@@@@@@@Lj`a!!!!"""""!!``!!!""""""####$$$%%&&''&&%%%%&&%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`͒ԗӒ``````a!!!!!`a`ŏ`!!!!```a!""#####""""""""""""###""""!!!`@@Ƈ``!!""##$##""!!``a!"""###$$$$%%&%&&''(()))**++,,,--..///0011122334454433233445566778899::;;;<<<<<<============>>??????????????????????????>>>>>00000112112222112233322233445555667665555666778899::::::::::;;;:::::::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ѐ@@ʊɊˊ`!!!""""##""!!!!""""#######$$$%%&&''''&&&&&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``a!!!!```a!!!!!```‹`!!!!a``˒`!!""#####""""!!!!!!""""""##"""!!!``Ñ@@@@````a!!""##$##""!!``Ə``!!""###$$$%$%%&&&&''(()))**++,,,--..//00011222334455544333445566778899::;;<<<========>>>>>>>>>>????????????????????????????????0001112222222222233333333445556667776656666778899::::::::;;;;;;;;::;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ώ@@ˌ@@@@Ɏ`!!"""#####""!!"""######$$$$%%%&&''((''&&&&''&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!`!!""!!``a``Ȍ`!!!!aa````Ѐ`!!""""""""!!!!!!!!!!!!""""""""""!!!``ƈ@@Ȉ`a`````a!!!""##$##""!!`ɋ````!!!""###$$$%%%%&&'&''(())***++,,---..//00011222334455655443445566778899::;;<<<======>>>>>>>>>>>>?????????????????????????????????111112232233332233444333445566667787766667778899::;;;;;;;;;;<<<;;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ː@@@@ˋ@@@@@@@@Ҏ```!!""##$$##""""####$$$$$$$%%%&&''((((''''''''''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɖ`!!""!!!!""!!`͎`aaa``̇````!!!!!!``Ƈ`!!"""""""!!!!``````a!!!!!""""""""!!!`Ç@@ʉ``!!!!!!!!!"""##$##""!!`@`````a!!!!!""##$$$%%%&%&&''''(())***++,,---..//00111223334455666554445566778899::;;<<===>>>>>>>>??????????????????????????????????????????11122233333333333444444445566677788877677778899::;;;;;;;;<<<<<<<<;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɨˋ@@@@ϐ`!!""##$$##""###$$$$$$%%%%&&&''(())((''''((''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`NJ`!!"""""!"""!!`ɐ`!!!!`ē`!!!!!!!``!!!!!!!!!``````!!!!!!!!!!!!!!`̞@@@@@@ˉ``a!!"!!!!!""""##$$$##""!!```!!!``a!!!!"""##$$$%%%&&&&''('(())**+++,,--...//00111223334455667665545566778899::;;<<===>>>>>>?????????????????????????????????????????????2222233433444433445554445566777788988777788899::;;<<<<<<<<<<===<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Җ@@@@@@@ˍ``!!""##$$$####$$$$%%%%%%%&&&''(())))(((((((((((())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʐ`a!""##""""#""!!``!!""!!```!!!!"!!```!!!!!!!`՗```!!!!!!!!!!``՚@@A@ˌ`!!!"""""""""###$$%$$##""!a```!!!!!!""""""##$$%%%&&&'&''(((())**+++,,--...//00112223344455667776655566778899::;;<<==>>>??????????????????????????????????????????????????222333444444444445555555566777888999887888899::;;<<<<<<<<========<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϔ͋````!!""##$$$$##$$$%%%%%%&&&&'''(())**))(((())(((())**++,,--..//00112233445566778899::;;<<==>>??????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʎ``!!"""####"##""!a!``!!"""!!!````!!!!`Ì```````ӕ``````````ۍ@A@ċ`!!""#"""""####$$%%%$$##""aa````!!!!"""""###$$%%%&&&''''(()())**++,,,--..///00112223344455667787766566778899::;;<<==>>>???????????????????????????????????????????????????3333344544555544556665556677888899:998888999::;;<<==========>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ԑ`a!`!`!!""##$$%%$$$$%%%%&&&&&&&'''(())****))))))))))))**++,,--..//00112233445566778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`΍```a!!""!""#####""!!```!!"""!!!```È`!!!`‰````ٍޞ@@@@@ȉ`!!""########$$$%%%%$$##""!!``!!"""######$$%%&&&'''('(())))**++,,,--..///00112233344555667788877666778899::;;<<==>>?????????????????????????????????????????????????????333444555555555556666666677888999:::9989999::;;<<========>>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̒```a!!!!!!""##$$%%%%$$%%%&&&&&&''''((())**++**))))**))))**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ȇ`!!!!!!!!!""###""!!`Δ`!!""""!!!a```!`ǐ@````````͎@A@@ʍ`````!!""#######$$$$%%%%$$##""!!`ˑ`!!""#####$$$%%&&&'''(((())*)**++,,---..//000112233344555667788988776778899::;;<<==>>??????????????????????????????????????????????????????44444556556666556677766677889999::;::9999:::;;<<==>>>>>>>>>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ŋ```!!!!""!"!""##$$%%&&%%%%&&&&'''''''((())**++++************++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!!!!`!!""###""!!`ʕ`!!"""""!!!!``ɏ````Ì`a``!`````Б@AA@ɉˈ`!!`ϐ`a!!""##$$$$$$$$%%%&%%$$##""!!`Ŏ`!!""##$$$$%%&&'''((()())****++,,---..//000112233444556667788999887778899::;;<<==>>???????????????????????????????????????????????????????444555666666666667777777788999:::;;;::9::::;;<<==>>>>>>>>????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̑`!!!!!"""""""##$$%%&&&&%%&&&''''''(((()))**++,,++****++****++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,+++**))((''&&%%$$##""!!`nj`a!!!!!`````!!""#""!!``!!""###""""!!!``Ԁ`!``!````a```΍@@@‚``a!`Ɉ``!!!""##$$$$$$$%%%%&%%$$##""!!``!!""##$$%%&&'''((())))**+*++,,--...//00111223344455666778899:998878899::;;<<==>>????????????????????????????????????????????????????????5555566766777766778887778899::::;;<;;::::;;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Г`!!""""##"#"##$$%%&&''&&&&''''((((((()))**++,,,,++++++++++++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++****))((''&&%%$$##""!!`υ`!!!!!```a!""###""!!`Ǝ`!!""###"""""!!!`œ`!!``!!``!``!a`!`@A@`a!!`ą``````a!!"""##$$%%%%%%%%&&%%$$####""!!`Ɛ`!!""##$$%%&&''(()))*)**++++,,--...//00111223344555667778899:::9988899::;;<<==>>?????????????????????????????????????????????????????????555666777777777778888888899:::;;;<<<;;:;;;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Б`a!""""#######$$%%&&''''&&'''(((((())))***++,,--,,++++,,++++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++****))((''&&%%$$##""!!`Ȅ`!!!`!!``a!!""###""!!``!!""##""""""""!!`Ռ`!!!!!!`ł```aa`@Ȉ@AA@ƒ`a!!!``a!!!``Ņ`!!!"""##$$%%%%%$%%&&%%$$####""!!`ƌ`!!""##$$%%&&''(())****++,+,,--..///00112223344555667778899::;::99899::;;<<==>>??????????????????????????????????????????????????????????66666778778888778899988899::;;;;<<=<<;;;;<<<==>>??????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̊`a!""####$$#$#$$%%&&''((''''(((()))))))***++,,----,,,,,,,,,,,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))*))((''&&%%$$##""!!`DŽ`a!``!!`a!!""#####""!!```a!""##""!!!!!!!!!``!!!""!!``Nj```!!`@A@Ć``a!"!!```aa!!!!`È``!!""##$$%%%%$$$%%%%$$##""""!!!`ƈ`!!""##$$%%&&''(())**+*++,,,,--..///00112223344556667788899::;;;::999::;;<<==>>???????????????????????????????????????????????????????????6667778888888888899999999::::;;;;<<<<<;<<<<==>>????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȉ`!!""###$$$$$$$%%&&''((((''((())))))****+++,,--..--,,,,--,,,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))))*))((''&&%%$$##""!a`‡`!``!!!!"""#####"#""!!`a!!""##""!!aa!!!!a```a!"""""!!``a!`@@@ƒ```!!""!!a``!!!b"!!`ǂ`!!""##$$%%$$#$$%%$$##""""!!!!`ي`!!""##$$%%&&''(())**++++,,-,--..//000112233344556667788899::;;<;;::9::;;<<==>>????????????????????????????????????????????????????????????777778898899998899:::9999::9::::;;<<<<<<<===>>??????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ǂ`a!""##$$$%%$%$%%&&''(())(((())))*******+++,,--....------------..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))(())*))((''&&%%$$##""!a`ƈ``!!!`!!"!""""""#"""""""!!!!!"""""!!``````````!!"""""!!````!`@@ƒ``a!"!!aa!!!!"""!!`ʼn`!!""##$$%$$###$$$$##""!!!!`a`ˌ`!!""##$$%%&&''(())**+++,,----..//000112233344556677788999::;;<<<;;:::;;<<==>>?????????????????????????????????????????????????????????????77788899999999999::::99899999::::;;;<<<====>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%%%%&&''(())))(()))******++++,,,--..//..----..----..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((())))((''&&%%$$##""!!`Ŋ`a!!"!!!""""""""""""!"!"""!!!!!"""!a```a!""###""!a``Ɨ`!```@@ƒ`a!!```!!!!!"!!``!!""##$$$##"##$$##""!!!!```a!""##$$%%&&''(())**++,,,--.-..//001112233444556677788999::;;<<=<<;;:;;<<==>>??????????????????????????????????????????????????????????????8888899:99::::99::::998889989999::;;;<<==>>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`†@`a!""##$$%%&&%&%&&''(())**))))****+++++++,,,--..////............//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''(()))((''&&%%$$##""!!`ʌ`!!"""!"!"!!!!!!!"!!!!!!!!!!``!!!"!!`Ƌ``a!""####""!!``aaa`@@@@‚`!`````!!"!!`````!!"b##$##"""####""!!``!a`•`!!""##$$%%&&''(())**++,,--....//00111223344455667788899:::;;<<===<<;;;<<==>>???????????????????????????????????????????????????????????????888999:::::::::::::99887888889999:::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`‰`!!""##$$%%&&&&&&''(())****))***++++++,,,,---..//00//....//....//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''''(()((''&&%%$$##""!!`Ņ``a!""!!!!!!!!!!!!!!!!`!`!!!!``!!!"!!``Ɗ`!!""##$$##""!!``Ў`````!`@@@ƒ``ʈ`!!"!!!`a``!!"bc###""!""##""!!````Ζ`!!""##$$%%&&''(())**++,,--...//00112223344555667788899:::;;<<==>==<<;<<==>>????????????????????????????????????????????????????????????????99999::;::;;;;::::9988777887888899:::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&'&'&''(())**++****++++,,,,,,,---..//0000////////////00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&''((((''&&%%$$##""!!````!!!"!!!!!!`!```````!```````ϋ``a!"!!!```!!""##$$$##""!!```!``!`ňđƒ@@@@@@Ƒƅ`!!""!!!``!!""##""!!!"""""!!```֙`!!""##$$%%&&''(())**++,,--..//00112223344555667788999::;;;<<==>>>==<<<==>>?????????????????????????????????????????????????????????????????999:::;;;;;;;;;::9988776777778888999::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʍ`!!""##$$%%&&'''''(())**++++**+++,,,,,,----...//001100////00////00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&''((((''&&%%$$##""!!````!!````````a!!!!!!``````ˑՏƌ`!ab!!!!````!!""##$$$$##""!!```!``aa````Ƒ``@@@@ޞ````!!""""!!``!!""#""!!`!!""!!!`ǏІ`a!""##$$%%&&''(())**++,,--..//00112233344556667788999::;;;<<==>>?>>==<==>>??????????????????????????????????????????????????????????????????:::::;;<;;<<;;::998877666776777788999::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ή`!!""##$$%%&&'''(())**++,,++++,,,,-------...//001111000000000000112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%&&''((((''&&%%$$##""!!!!!!!!```a!!!!a!!!!!!``Ɉӑғ`a!""""!!!!!`!!""##$$%%$$##""!!!```!!````aa`@```a!``΃`a!``NjӘ`a!!!!""##""!!`ȃ`!!""""!!``!!!!!`Ȝ`!!""##$$%%&&''(())**++,,--..//001122334455666778899:::;;<<<==>>???>>===>>???????????????????????????????????????????????????????????????????:::;;;<<<<<;;::99887766566666777788899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɋ`!!""##$$%%&&''(())**++,,,,++,,,------....///001122110000110000112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%&&''((((''&&%%$$##""!!!!""!!```a!!!!!!!!!!!``NJ`!!"""b""aa!!!""##$$%%%%$$##""!!!a`a!!!!!`a!!!``a!````a!!!!````a!!!`΍`!!!!!""###""!!``!!"""!!``a!!!`!`Ҕ`!!""##$$%%&&''(())**++,,--..//00112233445566778899:::;;<<<==>>?????>>=>>????????????????????????????????????????????????????????????????????;;;;;<<=<<;;::9988776655566566667788899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̏`!!""##$$%%&&''(())**++,,-,,,,----.......///001122221111111111112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$%%&&''((((''&&%%$$##"""""""!!````!!!!!!!!!``Đ`!!"bc"""bb!""##$$%%&&%%$$##"""!!!!``````!!!`a`a!!!!a!!""!!!````aa!!`Վ``!!"""""####""!!`Ì`!!"""!!````````Ə`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<===>>???????>>>?????????????????????????????????????????????????????????????????????;;;<<<=<<;;::998877665545555566667778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ˏ`a!""##$$%%&&''(())**++,,---,,---......////0001122332211112211112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$%%&&''((((''&&%%$$##"""""!!``````````ԑ`!!"b###"""""##$$%%&&&&%%$$##"""!!``a``!!""!!!!"""!!```a!!`׈`a!!"""""##$##""!!`ȉ`a!"!!!!`΋Є`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<===>>?????????>??????????????????????????????????????????????????????????????????????<<<<<=<<;;::99887766554445545555667778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ǐ`aa""##$$%%&&''(())**++,,--.----....///////0001122333322222222222233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##$$%%&&''((((''&&%%$$###"""!!`Njʘ`a!""######"##$$%%&&'&&%%$$$###""!a````a`!!"""""""""!!`Ԏ`!!!`ό`a!!""#####$##""!!``!!!!!!`ώ@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????<<<==<<;;::9988776655443444445555666778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɋ`a!""##$$%%&&''(())**++,,--..--...//////000011122334433222233222233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####$$%%&&''(((''&&%%$$##"""!!``!!""#######$$%%&&&&&%%$$######""!!aa````a!!!""##""""""!!```a!!!`ʐ``!!""###$$##""!a````!!!```؈````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????====<<;;::998877665544333443444455666778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!a`Č```!!""##$$%%&&''(())**++,,--......////000000011122334444333333333333445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""##$$%%&&''(''&&%%$$##""!!!!`ń```!!"""""#####$$%%%%%&%%$$###"""""""!!!!!!!!"!""########""!!```a!!"!!`ޔ`!!""##$$##""!a````a``!`ψ@````a`a`!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????===<<;;::99887766554433233333444455566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!""##$$%%&&''(())**++,,--..//..///0000001111222334455443333443333445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""##$$%%&&'''&&%%$$##""!!!!`ʏ`a`!!""""""""""##$$$%%%%%$$##""""""""""""!!!!""""##$$######""!!!!!!"!!`ۋ`!!""##$$$##"ba!```a!!!a``!`€`͏`a!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????==<<;;::9988776655443322233233334455566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!`ˋ```a!!!""##$$%%&&''(())**++,,--..//////00001111111222334455554444444444445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""##$$%%&&'&&%%$$##""!!```ϑ``!!!!!!!"""""##$$$$$%$$##"""!!!!!""""""""""#"##$$$$$$$###""!!!"""!!`Ԑ`!!""##$$$##b"!!``aa!!!!``ˇ@ƈ```a!!!!"!!`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????=<<;;::998877665544332212222233334445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!a!```Ô`a!!!""""##$$%%&&''(())**++,,--..//00//00011111122223334455665544445544445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!""##$$%%&&&%%$$##""!!`͐````!!!!!!!!!!""###$$$$$##""!!!!!!!!""""""""#######$$$######""""""!!`Ӕ`!!""##$$##""!!``!!!!a`Ņ``!a``a!""""""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????<<;;::99887766554433221112212222334445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!aa!`a!`Θ`!!!""""##$$%%&&''(())**++,,--..//000000111122222223334455666655555555555566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``aa""##$$%%&%%$$##""!!`ȉ``````!!!!!""#####$##""!!!`````!!!"""""""""#########""""#"""""!!`Ѝ`!!""##$$##""!a``!!!!````a`a!!!a!"""""#""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????<;;::9988776655443322110111112222333445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""!aa!`ˑ``!!"""####$$%%&&''(())**++,,--..//001100111222222333344455667766555566555566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``a!""##$$%%%$$##""!!`Ȋ````!!"""#####""!!```!!!!!""""""""""###"""""""""""!!`Ň`!!""##$$$##""!!!!!!``````!!!""!!""######"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????;;::998877665544332211000110111122333445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""!!!`ǎ`a!!"""####$$%%&&''(())**++,,--..//001111112222333333344455667777666666666666778899::;;<<==>>??????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``a!""##$$%%%$$##""!!`Nj`!!"""""#""!!`Ҍ``!!!!!!!!!"""""""""!!!!"""""!!`ʋ`!!""##$$$##""!!""!!`a!``!``!!!""""""#####$##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????;::99887766554433221100/00000111122233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####"""!!`Α`!!!""###$$$$%%&&''(())**++,,--..//001122112223333334444555667788776666776666778899::;;<<==>>????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!""##$$%$%%$$##""!!`΍`!!!!"""""!!`̐```!!!!!!!!!!"""!!!!!!!!!!!!!`ρ`!!""##$$$##""""""!!!!`Š`!!!!"""##""##$$$$$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????::99887766554433221100///00/00001122233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####""!!`Ŕā`!!"""###$$$$%%&&''(())**++,,--..//001122222233334444444555667788887777777777778899::;;<<==>>??????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!""##$$%$$$$$##""!!`͍`!!!!!!!""!!`ň``````!!!!!!!!!````a!!!!!!`׀`!!""##$$$##""##""!!!``!!!!"""######$$$$$%$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????:99887766554433221100//./////00001112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$##""!!`ǔ````a!"""##$$$%%%%&&''(())**++,,--..//001122332233344444455556667788998877778877778899::;;<<==>>????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""##$$%$$#$$$##""!!`Ә````!!!!!!!`Ć````!!!`````````ˑ`!!""##$$$$######"""!a``!!"""###$$##$$%%%%%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????99887766554433221100//...//.////001112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$##""!!`Ž`!a``!!""##$$$%%%%&&''(())**++,,--..//001122333333444455555556667788999988888888888899::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""##$$%$$###$$##""!!`՛```!!!!`Æ```ƒ`ʏ`!!""##$$%$$##$$##"""!a``a!"""###$$$$$$%%%%%&%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????9887766554433221100//..-.....////000112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%$$##""!!`͔`!!``!!""##$$%%&&&&''(())**++,,--..//00112233333344455555566667778899::99888899888899::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$######$$$$$##"##$##""!!`ۈ``!!`DŽŃ``ʏ``aa""##$$%%%$$$$$$##""aa``a!""###$$$%%$$%%&&&&&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????887766554433221100//..---..-....//000112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$##""!!``!!!`ˌ`!!""##$$%%&&&''(())**++,,--..//00112232222233445566666667778899::::999999999999::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"#####$#$##"""####""!!```ă``Ϗ`!`a!""##$$%%%$$$$##""!!``!!""##$$%%%%%%&&&&&'&&%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????87766554433221100//..--,-----....///00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%$$##""!!`͐`!!!`ȏ````````!!""##$$%%&&''(())**++,,--..//00011222222222334455666777788899::;;::9999::9999::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##"#c###""!""###""!!`ǛÃ`Ѝ``!!""##$$%%%%%$$##""!a``a!""##$$%%&&%%&&''''''&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????7766554433221100//..--,,,--,----..///00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɋ`!`!`ɋ``!`!!!!!````!!""##$$%%&&''(())**++,,--..//0000112211111223344556677788899::;;;;::::::::::::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!"""""c"#""!!!""#"""!!`ϖ`̗`````Ç`!!""##$$%%%%%%$$##bba!!!""##$$%%&&&&&&'''''(''&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????766554433221100//..--,,+,,,,,----...//00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʏ```ˆ````````a!!!!!!!!```a!``!!""##$$%%&&''(())**++,,--..////001111111112233445566778899::;;<<;;::::;;::::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""!"""""!!`a!"""!!!`ח``Ӕ͘`!!!``!!""##$$%%&&&&%%$$#cb"!!""##$$%%&&''&&''(((((('''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????66554433221100//..--,,+++,,+,,,,--...//00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``̋̀`ǂ``!!!!!!````!!"""""!!!!!!!``!!""##$$%%&&''(())**++,,--...////001100000112233445566778899::;;<<;;;;;;;;;;;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!!!!"!"!!``!!"!!!`͍``ԗ`Ӑ`!!!!``!!""##$$%%&&&&&%%$$##""""##$$%%&&''''''((((()(('(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????6554433221100//..--,,++*+++++,,,,---..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`ȕ```a!!!!!!!!!````!``!!"""""""!!!""!!`ă`!!""##$$%%&&''(())**++,,--.....//000000000112233445566778899::;;<<;;;;<<;;;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!`a!!!!!``a!!!!``͒``Ӛ``ڔ`!!"!a`Ǎ`a!""##$$%%&&'''&&%%$$##""##$$%%&&''((''(())))))((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????554433221100//..--,,++***++*++++,,---..//00112233445566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!`Ћ`````!!!""""""!!!!!!!!!!""#####""""""!!`Ä`!!""##$$%%&&''(())**++,,----....//00/////00112233445566778899::;;<<<<<<<<<<<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````a`!!``!!!!`ʉ````͒`!!"!!``!!""##$$%%&&''''&&%%$$####$$%%&&''(((((()))))*))())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????54433221100//..--,,++**)*****++++,,,--..//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!`Ɋ`!!`Å`!!!""""""""""!!!!"!!""#######"""""!!`Ä`!!""##$$%%&&''(())**++,,-------../////////00112233445566778899::;;<<<<==<<<<==>>?????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```````a!```ʊ```ɏ`!!"!!`ʈ`a!""##$$%%&&''((''&&%%$$##$$%%&&''(())(())******)))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????4433221100//..--,,++**)))**)****++,,,--..//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`a``!```!!!"""######""""""""""##$$$$$###""!!``!!""##$$%%&&''(())**++,,,,,,----..//.....//00112233445566778899::;;<<========>>?????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```````a`a!`͋```a`ɏ`!!!"!!`Ð`!!""##$$%%&&''(((''&&%%$$$$%%&&''(())))))*****+**)**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????433221100//..--,,++**))()))))****+++,,--..//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȃ`a```!!"""##########""""#""##$$$$$$$###""!!`ƒ`!!""##$$%%&&''(())**++,,,,,,,,--.........//00112233445566778899::;;<<======>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!a`!!!!!``!!!!`ć``!!`ƌ``!!"!!```!!""##$$%%&&''((((''&&%%$$%%&&''(())**))**++++++***++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????33221100//..--,,++**))((())())))**+++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`σ`!!``a!"""###$$$$$$##########$$%%%%%$$##""!!``!!""##$$%%&&''(())**+++++++,,,,--..-----..//00112233445566778899::;;<<==>>>>?????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!!!!"!!`Lj`!!!`Ɍ`!!"!!!```!!""##$$%%&&''(())((''&&%%%%&&''(())******+++++,++*++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????3221100//..--,,++**))(('((((())))***++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```ƒ`!!`Š`!!""##$$$$$$$$$$####$##$$%%%%%%%$$##""!!``!!""##$$%%&&''(())**+++++++++,,---------..//00112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!"""""!!"!!``Ɋ`!!!``!!!!!!!`ā``͝`!!!""##$$$%%&&''(()))((''&&%%&&''(())**++**++,,,,,,+++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????221100//..--,,++**))(('''(('(((())***++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!``Đ`!!!``ą`!!""##$$%%%%%$$$$$$$$$$%%&&&&%%$$##""!!`ƒ`!ab"##$$%%&&''(())********++++,,--,,,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""""""!!`LJ`!!!!`Č`!!!!"!!`````````Ɣ`a!!""##$$#$$%%&&''(()))((''&&&&''(())**++++++,,,,,-,,+,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????21100//..--,,++**))((''&'''''(((()))**++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!``!!!`Ɖ`!!""##$$%%%%%%%$$$$%$$%%&&&&&&%%$$##""!!``Ã`!!""##$$%%&&''(()))**********++,,,,,,,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"####""!!`Ƈ`!!!!`Ƌ```!!"!!!`a`aa!``ą`!!"!""#####$$%%&&''(()))((''&&''(())**++,,++,,------,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????1100//..--,,++**))((''&&&''&''''(()))**++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!!`Ǎ`!!``!!""##$$%%&&&%%%%%%%%%%&&'&''&&%%$$##""!!``!!""##$$%%&&''(())))))))))****++,,+++++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$######""!!`LJ`!!!!```!!"!!!aa!!``a`Ƅ`!!!!!""##"##$$%%&&''(()))((''''(())**++,,,,,,-----.--,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????100//..--,,++**))((''&&%&&&&&''''((())**++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!`È`a!!``!!""##$$%%&&&&&%%%%$%%&&&&&&''&&%%$$##""!!`ƒ`!ab"##$$%%&&''((())())))))))))**+++++++++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#$##""!!`LJ`!!!`ő`!!"""!"!!``!!```!!!`!!"""""##$$%%&&''(()))((''(())**++,,--,,--......---..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????00//..--,,++**))((''&&%%%&&%&&&&''((())**++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""!!`Ć`!!!```a!""##$$%%&&''&&&%%$$$%%%%&%&&'&&%%$$##""!!``!!""##$$%%&&''''((((((((((())))**++*****++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$##""!!`Lj`!!!!``є`!!"!!!!!`Ȋ`!!!!`````````````ň`a!!``!!""!""##$$%%&&''(()))(((())**++,,------...../..-..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????0//..--,,++**))((''&&%%$%%%%%&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!``!!""##$$%%&&''&&%%$$#$$%%%%%%&&&%%$$####""!!``a!""##$$%%%&&&&'''(('(((((((((())*********++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ȋ`!!!!`ύ`!!!!!!!`Ɗ`!!!!!!!!!!!````````a!```!!!```a!!`ӏ`!!!!!""##$$%%&&''(()))(())**++,,--..--..//////...//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????//..--,,++**))((''&&%%$$$%%$%%%%&&'''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!``!!""##$$%%&&'&&%%$$###$$$$%$%%&%%$$###"""bbaa`a!""####$$%%%%&&&&'''''''''''(((())**)))))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ȋ`!!!!`Ƅ`a`!````ň`!!!!!!!!!!!!!a!!!!!!!!!!!!!``!!!`֞`!aa`aa"bc#$$%%&&''(()))))**++,,--....../////0//.//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????/..--,,++**))((''&&%%$$#$$$$$%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!``!!""##$$%%&&&&%%$$##"##$$$$$$%%%$$##""""""bb!!!"""""###$$$%%%%&&&''&''''''''''(()))))))))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ŋ`!!!!`Č``Ç`!!!!!""""!!!!!!!!""!!!""!!```!!!!`֘`a!a``a!""##$$%%&&''(()))**++,,--..//..//000000///00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????..--,,++**))((''&&%%$$###$$#$$$$%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!`ǐ`!!"!!``!!""##$$%%&&&%%$$##"""####$#$$%$$##"""!!!!!!!!!!""""""##$$$$%%%%&&&&&&&&&&&''''(())((((())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɖ`!!!!``ŎÆLJ````!!"""""""""""""""""""!!``a!!!!`ǖ`!!!!`a!""##$$%%&&''(())***++,,--..//////00000100/00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????.--,,++**))((''&&%%$$##"#####$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``΀`!!"!!``!!""##$$%%&&&%%$$##""!""######$$$##""!!!!!!!!!`!!!a!!"""###$$$$%%%&&%&&&&&&&&&&''((((((((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ȋ`!!""!!``!!""""""""""##"""##""!!```a!!"aa`Л`!!"!!!""##$$%%&&''(())***++,,--..//00//00111111000112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????--,,++**))((''&&%%$$##"""##"####$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!``!!""!!`ć`!!""##$$%%&&%%$$##""!!!""""#"##$##""!!!`````````!a!!!!""####$$$$%%%%%%%%%%%&&&&''(('''''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ċ`!!"""!!`ƍ`!!""###############""!!!```a!""!!``!!"""!""##$$%%&&''(())**+++,,--..//000000111112110112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????-,,++**))((''&&%%$$##""!"""""####$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!``a!""""!!`Ê`!!""##$$%%&%%$$##""!!`!!""""""###""!!``Ć````!!!"""####$$$%%$%%%%%%%%%%&&'''''''''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɉ`!!""!!```!!""######$$###$$##""!!!``a!!"""!!``!!"""""##$$%%&&''(())**+++,,--..//001100112222221112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????,,++**))((''&&%%$$##""!!!""!""""##$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""!!`a!""##""!!`Î`!!""##$$%%%%$$##""!!``!!!!"!""#""!!`Ă```!!""""####$$$$$$$$$$$%%%%&&''&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɋ`!!""!!`ȕ`!!""##$$$$$$$$$$$##"""!!``„````a!!""#""!!``aa""##"##$$%%&&''(())**++,,,--..//001111112222232212233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????,++**))((''&&%%$$##""!a`a!!!!""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""!!!""##""!!!`Ê`!!""##$$%%&%%$$##""!!`a!!!!!!!"""!!`À````!!!"b""###$$#$$$$$$$$$$%%&&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƈ`!!"!!`Ǐ`!!""##$$$%%$$$%$$##""!!`ć``Ǝ`a!!!!"""###""!!```!!""###$$%%&&''(())**++,,,--..//001122112233333322233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????++**))((''&&%%$$##""!a``!!`!!!!""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$##""!""##""!!`!``!!""##$$%%%%%$$##""!!!!!``!`!!"!!```````!!!ab"""###########$$$$%%&&%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Å`!!!!`ɍ`!!""##$$%%%%%%%%$$##""!!`†€`a`ōǁ``!!!!!"""####""!!```!!""##$$%%&&''(())**++,,--..//001122222233333433233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????,++**))((''&&%%$$##""aa`!!``!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$##"""##""!!``!`֔`!!""##$$%%%%$$##""!!``````!!"!!```!```````…``!!!!"""##"##########$$%%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Æ`!!!!`ȋ`!!""##$$%%&&%%%&%%$$##""!!`„`````!!`Č```aa!"""""###$$##""!!`!`!!""##$$%%&&''(())**++,,--..//001122332233444444333445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????,,++**))((''&&%%$$##""!!!!``a``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$##"####""!!`aa`͒`!!""##$$%$$$$##""!!`ÃÃ`!!"!!!!!!``!a`!!!!````Ň``!!!!""""""""bb"####$$%%$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Å`!!!`ĉ`a!""##$$%%&&&&&&&&%%$$##""!!`Ŋ```a````!!!!!!````````a``!!!!"""""###$$$$##""!!!!!""##$$%%&&''(())**++,,--..//001122333333444445443445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????-,,++**))((''&&%%$$##""!"!!`a``a!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$###$$##""!!!!`ɓ`!!""##$$$$$##""!!`Ã`!!""!!!"!!!!!!!!!!```Ä``!!!b"!""""b"""""##$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!``a!""##$$%%&&''&&&'&&%%$$##""!!``a`Ċ`!!!!!!!!!!"!!`ń`!!aa``!!!!!!!!"""#####$$$%%$$##""!"!a!""##$$%%&&''(())**++,,--..//0011223333445555554445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????--,,++**))((''&&%%$$##""""!!!!``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%$$#$$$$##""!!`͜`!!""##$$####""!!``!!"""""""!!""!"""!!```````!a!!!!!!!!!""""##$$#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!a``!!!!``!!""##$$%%&&'''''''&&%%$$##""!!````a!`Ɛ`!!!!!""""""!!`Ä```a!!!a``!!!"!!""""#####$$$%%%%$$##""!!`a!""##$$%%&&''(())**++,,--..//00112233445555565545566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????.--,,++**))((''&&%%$$##"#""!"!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%$$$%$$##""!!`ȇ`!!""######"""!!``!!"""""#""""""""""!!!`a!`č`!!`!!!!!!!!!!""#########$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ą`!!"!!`Ċ`!!""##$$%%&&'''''(''&&%%$$##""!!!!!!!`ʑ`!!""""""""""!!``!!!""!!``!!""""""###$$$$$%%%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//001122334455666655566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????..--,,++**))((''&&%%$$####""""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>==<<;;::99887766554433221100//..--,,++**))(('''&&%%$%%%$$##""!!`͕`!!""##""""""!!`†``!!""######""##"###""!!!!``a!````````!!!!""##"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ą`!!""!!``ŏ```a!""##$$%%&&''((((((''&&%%$$##""!!!!!``a!"""""#####""!!``a!!""!!````a!""""####$$$$$%%%&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//001122334455666766566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????/..--,,++**))((''&&%%$$#$##"""!!`ޒ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::99887766554433221100//..--,,++**))(('''&&%%%%%$$##""!!``!!!""""""!!!!!`ć`!!""#####$##########"""!!a`````````a!````!!"""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!``!!!""##$$%%&&''((((()((''&&%%$$##"""""!!`Ɖ``!!""##########""!!``!!"""!!`ȉ`!!""###$$$%%%%%&&&%%$$##""!!`aa""##$$%%&&''(())**++,,--..//001122334455667777666778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????//..--,,++**))((''&&%%$$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????>>==<<;;::99887766554433221100//..--,,++**))(((''&&%&&%%$$##""!!`ʍ`!!!""!!!!!!!``Ĉ`!!""##$$$$$##$$#$$$##"""!!!!!!!!!!!!!!``̍`!!""!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""""!!`Š`!!""##$$%%&&''(())))))((''&&%%$$##""""!!`‰``!!!""#####$$$$##""!!``!!""!!`̎`!!""##$$$%%%%%&&&%%$$##""!!``a!""##$$%%&&''(())**++,,--..//0011223344556677776778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????0//..--,,++**))((''&&%%$%$$##""!!```a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))(((''&&&&&%%$$##""!!``ɗ```!!!!!!````Ň`!!""##$$$%$$$$$$$$$##""!!!!!!!!!!!!``!``Ȉ`!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Â``!!""""!!`ɏ`a!""##$$%%&&''(())))*))((''&&%%$$###""!!`Ɩ`a!!!""##$$$$$$$$$##""!!``!!""!!`Њ`!!""##$$%%%&&&&&&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566777778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????00//..--,,++**))((''&&%%%%$$##""!!a!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887766554433221100//..--,,++**)))((''&''&&%%$$##""!!!``ώ`!!`````!!""##$$%%$$%%$$$##""!!````!!!!!```ń`!!`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!`Ǐ```a!""##$$%%&&''(())*****))((''&&%%$$##""!!`Ǔ`a!!"""##$$$$$%%%%$$##""!a``!!""!!`Ï`!!""##$$%%&&&&&&&%%$$##""!!````!!""##$$%%&&''(())**++,,--..//0011223344556677878899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????100//..--,,++**))((''&&%&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..mm,,++**)))(('''''&&%%$$##""!!!```Ã``a!""##$$$$%%%%%$$##""!!```a!``ˈ```!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""!!``!!!""##$$%%&&''(())******))((''&&%%$$##""!!`ƌ`!!"""##$$%%%%%%%%%$$##""!a`ҁ`!!"!!``!!""##$$%%&&'''&&%%$$##""!!`ԇ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????1100//..--,,++**))((''&&&&%%$$##"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????>>==<<;;::99887766554433221100//..m-,,++***))(('((''&&%%$$##"""!!``Ä`!!""#####$$$%%&%%$$##""!!``!!`!````````````a!``aa``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""!!`Ƈ`!!""##$$%%&&''(())**+++**))((''&&%%$$##""!!`ď``!!""###$$%%%%%&&&%%$$##""!!`ς`!!"!!````!!""##$$%%&&'''&&%%$$##""!!`Ɣ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????21100//..--,,++**))((''&'&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????>>==<<;;::99887766554433221100//..--,,++***))(((((''&&%%$$##"""!!!```͇`!!""""######$$%%&%%$$##""!!````a!!!!!!a!!!!``!!!!!!a!a!`````a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?>??????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""!!`````!!""##$$%%&&''(())**+++++**))((''&&%%$$##""!!`Ȕ`a!!""###$$%%&&&&&&&%%$$##""!!`ŀ`!!""!!!!!!""##$$%%&&''''&&%%$$##""!!`ǖ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????221100//..--,,++**))((''''&&%%$$#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????>>==<<;;::99887766554433221100//..--,,+++**))())((''&&%%$$###""!!!!!```!!!!"""""###$$%%&%%$$##""!!!`!!!""!"!!!!!!!!`!!!!""!!""!!!!!!!""##$$%%&&''(())**++,,--..//0011222334445566778899::;;<<==>>>>>????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ä`!!"""!!`Ċ`aa!!""##$$%%&&''(())**++,,++**))((''&&%%$$##""!!`Ȕ`a!!""##$$$%%&&&&&'&&%%$$##""!!`Ƃ`!!""!!!!""##$$%%&&''(''&&%%$$##""!!`̞`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????3221100//..--,,++**))(('(''&&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????>>==<<;;::99887766554433221100//..--,,+++**)))))((''&&%%$$###"""!!!!!``!!!!!!""""""##$$%%&%%$$##""!!!!!""""""""""""!!!""""""""""!!!!!""##$$%%&&''(())**++,,--..//001111222333445566778899::;;<<==>=>>>>>>>>>?????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ã`!!"""!!``!!!""##$$%%&&''(())**++,,,++**))((''&&%%$$##""!!`ɔ`a!"""##$$$%%&&'''''&&%%$$##""!!`ă`!!!""""""##$$%%&&''((''&&%%$$##""!!`Ϝ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????>>?>?????????????????????????????????????????????????????????????????????????????????????????????????????????????33221100//..--,,++**))((((''&&%%$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????>>==<<;;::99887766554433221100//..--,,,++**)**))((''&&%%$$$##"""""!!!``É`!!!``a!!!!"""##$$%%&%%$$##"""!"""##"#""""""""!""""##""##"""""""##$$%%&&''(())**++,,--..//00001111122333445566778899::;;<<=====>>>>>>>>>???>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Â`!!""!!``Œ`````!!"""##$$%%&&''(())**++,,,,++**))((''&&%%$$##""!!`ǎ`!!""##$$%%%&&''''''&&%%$$##""!!`ƒ`ƒ``!!""""##$$%%&&''(((''&&%%$$##""!!`֐`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????433221100//..--,,++**))()((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,,++*****))((''&&%%$$$###"""""!!!`````!!!``a!!!!!""##$$%%&%%$$##"""""############"""##########"""""##$$%%&&''((hi)**++,,--..//000000011122233445566778899::;;<<=<=========>>>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƒ`!!!""!!``Ò``!!!!!!"""##$$%%&&''(())**++,,-,,++**))((''&&%%$$##""!!`Ì`a!""##$$%%%&&''(((''&&%%$$##""!!```a`Ĉ`!!""##$$%%&&''(((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????>>==>=>>???????????????????????????????????????????????????????????????????????????????????????????????????????????4433221100//..--,,++**))))((''&&%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????>>==<<;;::99887766554433221100//..---,,++*++**))((''&&%%%$$#####"""!!!!!!`Ɂ``ǖ```````````!!!""##$$%%&%%$$###"###$$#$########"####$$##$$#######$$%%&&''((((())**++,,--../////000001122233445566778899::;;<<<<<=========>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ã``a!""!!`“`!!!!!!!""###$$%%&&''(())**++,,---,,++**))((''&&%%$$##""!!`ȑ```!!""##$$%%&&&''(((''&&%%$$##""!!``a!!`Ƈ`!!""##$$%%&&''(''&&%%$$##""!!``a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>>??????????????>>======>>??????????????????????????????????????????????????????????????????????????????????????????????????????????54433221100//..--,,++**)*))((''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..---,,+++++**))((''&&%%%$$$#####"""!!!!!```````!!``‹ɒ``!!""##$$%%&%%$$#####$$$$$$$$$$$$###$$$$$$$$$$#####$$%%&&''(((('(())**++,,--..///////0001112233445566778899::;;<;<<<<<<<<<====>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ą``!!"!!`Ǝ`!!""""""###$$%%&&''(())**++,,----,,++**))((''&&%%$$##""!!```!!!""##$$%%&&&''(()((''&&%%$$##""!!````a!!!`NJ``!!""##$$%%&&''(''&&%%$$##""!!`Մ`a!""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<===>>>????????????>>==<<=<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????554433221100//..--,,++****))((''&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????>>==<<;;::99887766554433221100//...--,,+,,++**))((''&&&%%$$$$$###""""""!!!!!``!!!!!!!``!!""##$$%%&%%$$$#$$$%%$%$$$$$$$$#$$$$%%$$%%$$$$$$$%%&&''''(('''(())**++,,--...../////001112233445566778899::;;;;;<<<<<<<<<===>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ą`a!"!!`Ï`!!""""""##$$$%%&&''(())**++,,--..--,,++**))((''&&%%$$##""!!`ȏ`a`!!!""##$$%%&&'''(()))((''&&%%$$##""!!!!`a!"!!`ŋ`!!""##$$%%&&''''&&%%$$##""!!`dž`a!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<====>>>>????????>>==<<<<<<==>>>???????????????????????????????????????????????????????????????????????????????????????????????????????6554433221100//..--,,++*+**))((''&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//...--,,,,,++**))((''&&&%%%$$$$$###"""""!!!!!!!!!""!!!`†`!!""##$$%%&%%$$$$$%%%%%%%%%%%$$$$%%$%%%%%%%$$$$$%%&&''''''''&''(())**++,,--.......///000112233445566778899::;:;;;;;;;;;<<<<===<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ą``!!!!```!!""######$$$%%&&''(())**++,,--...--,,++**))((''&&%%$$##""!!`NJ`!!!"""##$$%%&&'''(())*))((''&&%%$$##""!!!!!""!!`ō`!!""##$$%%&&''''&&%%$$##""!!`ǀ``!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<===>>>>??????>>==<<;;<;<<==>>>??????????????????????????????????????????????????????????????????????????????????????????????????????66554433221100//..--,,++++**))(('''''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????>>==<<;;::99887766554433221100///..--,--,,++**))(('''&&%%%%%$$$######"""""!!"""""""!!`Œ`!!""##$$%%&&%%%$%%%&&%&%%%%%$$##$$$$$%%%&&%%%%%%%&&&&&&&&''&&&''(())**++,,-----.....//000112233445566778899:::::;;;;;;;;;<<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ă`a!!!`Ș````!!!""######$$%%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!`Γ`!!"""##$$%%&&''((())*))((''&&%%$$####b"""!"""!!``!!""##$$%%&&''(''&&%%$$##""!!``!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<====>>????>>==<<;;;;;;<<===>>?????????????????????????????????????????????????????????????????????????????????????????????????????766554433221100//..--,,+,++**))(('''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????>>==<<;;::99887766554433221100///..-----,,++**))(('''&&&%%%%%$$$#####"""""""""##"""!!`„`a!""##$$%%&&&%%%%%&&&%%%%%%$$####$$#$$$%%&&%%%%%&&&&&&&&&&&&%&&''(())**++,,-------...///00112233445566778899:9:::::::::;;;;<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ã`a!!`ȗ``!!!!!!""######$$%%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""!!`ǒ`!!""##$$%%&&''(())*))((''&&%%$$##"###"""""#""!!`ʌ`!!""##$$%%&&''(''&&%%$$##""!!`@@`!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;<<<====>>?>>>==<<;;::;:;;<<===>>????????????????????????????????????????????????????????????????????????????????????????????????????7766554433221100//..--,,,,++**))((((())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????>>==<<;;::998877665544332211000//..-..--,,++**))(((''&&&&&%%%$$$$$$#####""#######""!!``a!""##$$%%&&&&&%&&&&%%%%$$$$##""#####$$$%%%%%%%&&&&%%%%%%&&%%%&&''(())**++,,,,,-----..///00112233445566778899999:::::::::;;;<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!`Ə`a!!!!!"""###"""##$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())))((''&&%%$$##"""cc###"##""!!`đ`!!""##$$%%&&''((''&&%%$$##""!!`NJ````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;<<<<==>>>>==<<;;::::::;;<<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????87766554433221100//..--,-,,++**))((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????>>==<<;;::998877665544332211000//.....--,,++**))((('''&&&&&%%%$$$$$#########$$###""!!````Ґ`!!""##$$%%&&&'&&&&&&%%$$$$$$##""""##"###$$%%%%%%%%&%%%%%%%%%%$%%&&''(())**++,,,,,,,---...//00112233445566778898999999999::::;;<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ą`aa`֓```a!!"""""""##"""""##$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""!!`Ǒ`!!""##$$%%&&''(()))((''&&%%$$##""!bb#######""!!``!!""##$$%%&&''''&&%%$$##""!!`@`!!""##$$%%&&''(())**++,,--..//00112233445566778899:::;;;<<<<==>===<<;;::99:9::;;<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????887766554433221100//..----,,++**)))))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????>>==<<;;::998877665544332211100//.//..--,,++**)))(('''''&&&%%%%%%$$$$$##$$$$$$$##""!!!!!```Å`!!""cc$$%%&&&&''&&&%%$$$$####""!!"""""###$$$$$$$%%%%$$$$$$%%$$$%%&&''(())**+++++,,,,,--...//001122334455667788888999999999:::;;<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!`ѓ``!!!!""""""#"""""!!!""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!`ŕ`!!""##$$%%&&''(())((''&&%%$$##""!aa""cc$#$##""!!`Ń`!!""##$$%%&&''''&&%%$$##""!!`Ô@@``a!""##$$%%&&''(())**++,,--..//0011223344556677889999::::;;;;<<====<<;;::999999::;;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????9887766554433221100//..-.--,,++**)))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????>>==<<;;::998877665544332211100/////..--,,++**)))((('''''&&&%%%%%$$$$$$$$$%%$$$##""!!!!!!!````!!""cc$$%%%%%&&'&&%%$$######""!!!!""!"""##$$$$$$$$%$$$$$$$$$$#$$%%&&''(())**+++++++,,,---..//0011223344556677878888888889999::;;<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!`Dž````!!!!!"""""""""!""!!!!!""##$$%%&&''(())**++,,--....--,,++**))((''&&%%$$##""!!`Ņ`!!""##$$%%&&''(()((''&&%%$$##""!!`a!""##$##""!!````Dž`!!""##$$%%&&''(''&&%%$$##""!!`ʋ``!!!""##$$%%&&''(())**++,,--..//00112233445566778899999:::;;;;<<=<<<;;::99889899::;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????99887766554433221100//....--,,++*****++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::998877665544332221100/00//..--,,++***))((((('''&&&&&&%%%%%$$%%%%%%%$$##"""""!!!!!`a`Ȇ`!!""c#$$%%%%%%&&&%%$$####""""!!``!!!!!"""#######$$$$######$$###$$%%&&''(())*****+++++,,---..//0011223344556677777888888888999::;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!``!!!!!!""""""""!!"!!!!!```!!""##$$%%&&''(())**++,,--....--,,++**))((''&&%%$$##""!!`ȏ`!!""##$$%%&&''((((''&&%%$$##""!!``!!""###""!!```ʑ```!!""##$$%%&&''(''&&%%$$##""!!`ā```````!!""##$$%%&&''(())**++,,--..//001122334455667788889999::::;;<<<<;;::9988888899:::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????:99887766554433221100//./..--,,++***++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????>>==<<;;::998877665544332221100000//..--,,++***)))((((('''&&&&&%%%%%%%%%&&%%%$$##"""""""!!!!`ń`!!"bc#$$%$$$$%%&%%$$##""""""!!``!!`!!!""########$##########"##$$%%&&''(())*******+++,,,--..//0011223344556676777777777888899::;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``a```!!!!!"""""""!!!!!!!`!!``!!""##$$%%&&''(())**++,,--...--,,++**))((''&&%%$$##""!!`ɕ`!!""##$$%%&&''((((''&&%%$$##""!!``!a""####""!!``!````!!""##$$%%&&''''&&%%$$##""!!`!````@`!!""##$$%%&&''(())**++,,--..//001122334455667788888999::::;;<;;;::998877878899:::;;<<==>>>?>???????????????????????????????????????????????????????????????????????????????????????????::99887766554433221100////..--,,+++++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????>>==<<;;::998877665544333221101100//..--,,+++**)))))(((''''''&&&&&%%&&&&&&&%%$$#####"""""!!!``ш`aa""##$$%$$$$$$%%%$$##""""!!!!`ĉ`!``!!!"""""""####""""""##"""##$$%%&&''(()))))*****++,,,--..//0011223344556666677777777788899:::::::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!"""""!!!!!!!!!``!``aa```!!""##$$%%&&''(())**++,,--....--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()((''&&%%$$##""!!``aa""###""!!``!!!!``!!""##$$%%&&'''&&%%$$##""!!````````@`!!""##$$%%&&''(())**++,,--..//00112233445566777788889999::;;;;::998877777788999::;;<<==>>>>>??????????????????????????????????????????????????????????????????????????????????????????;::99887766554433221100/0//..--,,+++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????>>==<<;;::998877665544333221111100//..--,,+++***)))))((('''''&&&&&&&&&''&&&%%$$#######""""!!``!a""##$$$$####$$%$$##""!!!!!!```!````!a""""""""#""""""""""!""##$$%%&&''(()))))))***+++,,--..//0011223344556566666666677778899:::::::99887766554433221100//..--,,++**))((''&&%%$$##""!!``a!!!!""""!!!!!!!!````!`a!a!!!!""##$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""!!`Ð`!!""##$$%%&&''(()((''&&%%$$##""!!``!!""####""!a``!!!!!!``a!""##$$%%&&''''&&%%$$##""!!``!````````!!""##$$%%&&''(())**++,,--..//001122334455667777778889999::;:::99887766767788999::;;<<===>=>>>????????????????????????????????????????????????????????????????????????????????????????;;::9988776655443322110000//..--,,,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????>>==<<;;::998877665544433221221100//..--,,,++*****)))(((((('''''&&'''''''&&%%$$$$$#####"""!!``a!""##$$$######$$$##""!!!!`````!```!!!!!!!""""!!!!!!""!!!""##$$%%&&''((((()))))**+++,,--..//00112233445555566666666677788999999::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"!!!!!!!``````Ϗ`!!!""!!!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##""!!`Ą`!!""##$$%%&&''(()((''&&%%$$##""!a``!!""##$##""!!``Ǝ`!!"""!a`ń`!!""##$$%%&&''''&&%%$$##""!aa`!!!!``a``!!""##$$%%&&''(())**++,,--..//0011223344555666667777888899::::9988776666667788899::;;<<=====>>>?>?????????????????????????????????????????????????????????????????????????????????????<;;::9988776655443322110100//..--,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????>>==<<;;::998877665544433222221100//..--,,,+++*****)))((((('''''''''(('''&&%%$$$$$$$####""!!``!!""##$###""""##$##""!!```˅``ϋ`!!!!!!!!"!!!!!!!!!!`!!""##$$%%&&''((((((()))***++,,--..//00112233445455555555566667788999999:99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!!``ؚ`!!"""""""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%dd##""!!`Ĉ`!!""##$$%%&&''(()((''&&%%$$##""!!``a!""##$$$##""!a`ʃ`!!"""!!`À`a!""##$$%%&&''''&&%%$$##""!!`aa!"!!`Ά```!!""##$$%%&&''(())**++,,--..//00112233445555666666777888899:9998877665565667788899::;;<<<=<===>>>>????????????????????????????????????????????????????????????????????????????????????<<;;::9988776655443322111100//..-----..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????>>==<<;;::998877665554433233221100//..---,,+++++***))))))(((((''(((((((''&&%%%%%$$$$$###""!a`nj`!!""####""""""###""!!`đʑ```````!!!!``````aa``!!""##$$%%&&'''''((((())***++,,--..//00112233444445555555556667788888899:99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!`````ޑ`!!""#"""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%e$$##""!!``!!""##$$%%&&''((((''&&%%$$##""!!``!!""##$$##""!a`ĉ`!!""""!!```a!""##$$%%&&''''&&%e$$##""!!``a!baa``a!""##$$%%&&''(())**++,,--..//001122334444445555566667777889999887766555555667778899::;;<<<<<===>=>>???????????????????????????????????????????????????????????????????????????????????=<<;;::9988776655443322121100//..---..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????>>==<<;;::9988776655544333s3221100//..---,,,+++++***)))))((((((((())(((''&&%%%%%%%$$##""!!`ǃ`!!"""#"""!!!!""#""!!`Ȃč``!````!!""##$$%%&&''''''''((()))**++,,--..//00112233434444444445555667788888899:99887766554433221100//..--,,++**))((''&&%%$$##""!!!!``̙`!!""#####$$%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%$$##""!!`Ə`!!""##$$%%&&''(()((''&&%%$$##""!!`a!""##$$$##""!a`Ë`!!""#""!!``a!a""##$$%%&&''(''&&%e$$##""!!``a!b!a`@`a!""##$$%%&&''(())**++,,--..//0011223333444445555556667777889888776655445455667778899::;;;<;<<<====>>??????????????????????????????????????????????????????????????????????????????????==<<;;::9988776655443322221100//.....//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????>>==<<;;::998877666554434t33221100//...--,,,,,+++******)))))(()))))))((''&&&&&%%%$$##""!!`ʀ`!!"""""!!!!!!""""!!`Ć@@ʑ`ϖ```!!""##$$%%&&'&&&&'''''(()))**++,,--..//00112233333444444444555667777778899:99887766554433221100//..--,,++**))((''&&%%$$##""!!!!`Í֙`a!""#####$$%%&&''(())**++,,--..//00100//..--,,++**))((''&&%%$$c#""!!```!!!""##$$%%&&''(())((''&&%%$$##""!!!""##$$$$##""!!``!!""##""!!`````!!!b"##$$%%&&''(''ff%%$$##""!!```a!"""!a`Հ@`a!""##$$%%&&''(())**++,,--..//0011223333333444445555666677888877665544444455666778899::;;;;;<<<=<==>>?????????????????????????????????????????????????????????????????????????????????>==<<;;::9988776655443323221100//...//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????>>==<<;;::998877666554444433221100//...---,,,,,+++*****)))))))))**)))((''&&&&&&%%$$##""!!``ƌ`!!!"!!!````!!"""!!`Ѓ@@Ɖ€`!!""##$$%%&&&&&&&&&&&'''((())**++,,--..//00112232333333333444455667777778899:99887766554433221100//..--,,++**))((''&&%%$$##""""!!``Ō`!!""##$$$$%%&&''(())**++,,--..//0011100//..--,,++**))((''&&%%$d##""!!`ǘ`!``!!""##$$%%&&''(())((''&&%%$$##""!!!""##$$##""!!```!!""##""!!aa`ƒ`!!!"""##$$%%&&''(''&&%%$$##""!!``a!!"""!!`ˈ@@`!!""##$$%%&&''(())**++,,--..//0011222233333444444555666677877766554433434455666778899:::;:;;;<<<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443333221100/////00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????>>==<<;;::998877766554554433221100///..-----,,,++++++*****))*******))(('''''&&&%%$$##""!!!``È`!!!!!``!!!!!`@@`!!""##$$%%%&&%%%%&&&&&''((())**++,,--..//00112222233333333344455666666778899:99887766554433221100//..--,,++**))((''&&%%$$##""""!!``!!""##$$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!`Œ`!``!!""##$$%%&&''((((''&&%%$$##""!!`!!""##$$##""!a`҃``!!""##""!!!`Ã`!!"""##$$%%&&''(''&&%%$$##""!!``!!"""ba!`@@@@@`!!""##$$%%&&''(())**++,,--..//00111222222233333444455556677776655443333334455566778899:::::;;;<;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443433221100///00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????>>==<<;;::998877766555554433221100///...-----,,,+++++*********++***))((''''''&&%%$$##""!!!!``ƈ``!`````Dž`!!!`ń@ޛ`!!!""##$$%%%%%%%%%%%&&&'''(())**++,,--..//00112122222222233334455666666778899:99887766554433221100//..--,,++**))((''&&%%$$####""!!`Å`!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!`č`a`Ņ`!!""##$$%%&&''((''&&%%$$##""!!``!!""##$##""!a`Ȁ`!!""###""!!`À``!!""###$$%%&&''(''&&%%$$##""!!``!!""##""!!`@@@@`!!""##$$%%&&''(())**++,,--..//001111122222333333444555566766655443322323344555667788999:9:::;;;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444433221100000112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????>>==<<;;::9988877665665544332211000//.....---,,,,,,+++++**+++++++**))((((('''&&%%$$##"""!!!`Ň``a`DŽ```ǃޘ`!!!""##$$$%%$$$$%%%%%&&'''(())**++,,--..//00111112222222223334455555566778899:99887766554433221100//..--,,++**))((''&&%%$$###""!!``!!""##$$%%&&''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$##""!!```aa`Ɔ`!!""##$$%%&&''(((''&&%%$$##""!!`!!!""##$##""!!`̇`!!""###""!!``!!a""###$$%%&&''(''&&%%$$##""!!``!!""####""!!``@@@Ċ`!!""##$$%%&&''(())**++,,--..//000011111112222233334444556666554433222222334445566778899999:::;:;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554544332211000112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::9988877666665544332211000///.....---,,,,,+++++++++,,+++**))((((((''&&%%$$##"""!!`ŀ`a`Ĉ``!!""##$$$$$$$$$$$%%%&&&''(())**++,,--..//00101111111112222334455555566778899:99887766554433221100//..--,,++**))((''&&%%$$##""!!``a!""##$$%%&&''(())**++,,--..//001122221100//..--,,++**))((''&&%%$$##""!!`É`!!``!!""##$$%%&&''(((''&&%%$$##""!!``a!""####""!!``!!""####""!a``!!ab"##$$$%%&&''(''&&%%$$##""!!```!!""####""!!!`@҉`!!""##$$%%&&''(())**++,,--..////000001111122222233344445565554433221121223344455667788898999::::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665555443322111112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????>>==<<;;::9998877677665544332211100/////...------,,,,,++,,,,,,,++**)))))(((''&&%%$$###""!!````a``DŽ`!!""###$$####$$$$$%%&&&''(())**++,,--..//00000111111111222334444445566778899:99887766554433221100//..--,,++**))((''&&%%$$##""!!`†`!!""##$$%%&&''(())**++,,--..//0011223221100//..--,,++**))((''&fe%$$##""!!``a!!`Æ`!!""##$$%%&&''((''&&%%$$##""!!``!!""###""!!``!!""####""!a!!"""##$$$%%&&''((''&&%%$$##""!!``!!""####""!!``цҖ`!!""##$$%%&&''(())**++,,--..//////00000001111122223333445555443322111111223334455667788888999:9::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776656554433221112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????>>==<<;;::99988777776655443322111000/////...-----,,,,,,,,,--,,,++**))))))((''&&%%$$###""!!!````ƀ`!!``̐`!!""###########$$$%%%&&''(())**++,,--..//0/00000000011112233444444556677889999887766554433221100//..--,,++**))((''&&%%$$##""!!``a!""##$$%%&&''(())**++,,--..//001122333221100//..--,,++**))((''&&%%$$##""!!``a!!!`Ć`!!""##$$%%&&''((''&&%%$$##""!!``a!""##$##""!a``!!""##$##""!!"""##$$%%%&&''((((''&&%%$$##""!a`!!""####""!!`ʞ`!!""##$$%%&&''(())**++,,--../../////00000111111222333344544433221100101122333445566777878889999::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766665544332222233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::998878877665544332221100000///......-----,,-------,,++*****)))((''&&%%$$$##""!!!!```!!``!!"""##""""#####$$%%%&&''(())**++,,--../////000000000111223333334455667788999887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0011223333221100//..--,,++**))((''&&%%$$##""!!!!"!!`ˆ`!!""##$$%%&&''(((''&&%%$$##""!!a`!!""#####""!a``!!!""##$##""""###$$%%%&&''(((''''&&%%$$##""!!`!!""###"""!!````†`!!""##$$%%&&''(())**++,,,--......///////00000111122223344443322110000001122233445566777778889899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877676655443322233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::9988888776655443322211100000///.....---------..---,,++******))((''&&%%$$$##"""!!!`a``!!!!``!!"""""""""""###$$$%%&&''(())**++,,--.././////////000011223333334455667788999887766554433221100//..--,,++**))((''&&%%$$##""!!```a!""##$$%%&&''(())**++,,--..//001122334433221100//..--,,++**))((''&&%%$$##""!!""!!``!!""##$$%%&&''(((''&&%%$$##""!!``!!""#####""!!``!`!!""##$##""###$$%%%%&&''((''''&&%%$$##""!!``!!b"#""!!!````a`„Ą`!!""##$$%%&&''(())**++,,,,--.--...../////0000001112222334333221100//0/001122233445566676777888899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988777766554433333445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;::9989988776655443332211111000//////.....--.......--,,+++++***))((''&&%%%$$##""""!!!!``!!""!!`˃``!!!""!!!!"""""##$$$%%&&''(())**++,,--...../////////00011222222334455667788999887766554433221100//..--,,++**))((''&&%%$$##""!!!```!!""##$$%%&&''(())**++,,--..//0011223344433221100//..--,,++**))((''&&%%$$##"""""!!``!!""##$$%%&&''(((''&&%%$$##""!!``!!!""""""""!!```!!""##$####$$$%%%$%%&&''''&&&&%%$$##""!!``!ab"""!!!!!``aa!`ʆ``a!""##$$%%&&''(())**++,,++,,------......./////00001111223333221100//////001112233445566666777878899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887877665544333445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????>>==<<;;;::99999887766554433322211111000/////.........//...--,,++++++**))((''&&%%%$$###"""!"!!!!""""!!`ƈ`!!!!!!!!!!!"""###$$%%&&''(())**++,,--.-.........////0011222222334455667788999887766554433221100//..--,,++**))((''&&%%$$##""!!!!`Ä`!!""##$$%%&&''(())**++,,--..//001122334454433221100//..--,,++**))((''&&%%$$##""#""!!`ʊ`!!""##$$%%&&''((((''&&%%$$##""!!`!!!!!"""""""!!`ƅ`!!""##$##$$$%%%$$$%%&&''&&&&%%$$###""!!`ӂ`!!""!!`!!``!!!`ˊ``!!""##$$%%&&''(())**+++++++,,-,,-----.....//////00011112232221100//.././/001112233445556566677778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::998888776655444445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????>>==<<<;;::9::99887766554443322222111000000/////..///////..--,,,,,+++**))((''&&&%%$$####""""!!""""!!```!!````!!!!!""###$$%%&&''(())**++,,-----.........///0011111122334455667788999887766554433221100//..--,,++**))((''&&%%$$##"""!!!`````````!!""##$$%%&&''(())**++,,--..//0011223344554433221100//..--,,++**))((''&&%%$$####""!!`Ƅ`a!""##$$%%&&''(())((''&&%%$$##""!!!!!`!!!!!!"""!a``Š`!!""##$$$%%%%$$#$$%%&&&&%%%%$$##"""!!`ׅ`!!!!!```!``!!!!`Œ``a!""##$$%%&&''(())**+++++**++,,,,,,-------.....////00001122221100//......//000112233445555566676778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::9989887766554445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????>>==<<<;;:::::99887766554443332222211100000/////////00///..--,,,,++*+**))((''&&&%%$$$###"#""""##""!!`Ʉ`````!!!"""##$$%%&&''(())**++,,-,---------....//0011111122334455667788999887766554433221100//..--,,++**))((''&&%%$$##""""!!``‡```a!!!!!!``!!""##$$%%&&''(())**++,,--..//00112233445554433221100//..--,,++**))((''&&%%$$####""!!```a!""##$$%%&&''(())))((''&&%%$$##""!!!``!!!!!!"""!!``!!""##$$%%%$$###$$%%&&%%%%$$##"""!!`؏``!!!!```aa!""!!```!!""##$$%%&&''(()))****+*****++,++,,,,,-----......///000011211100//..--.-..//000112233444545556666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::99998877665555566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????>>===<<;;:;;::99887766555443333322211111100000//0000000//..--,,++***+**)ih('''&&%%$$$$####""###""!!`ąÃ``!!"""##$$%%&&''(())**++,,,,,---------...//0000001122334455667788999887766554433221100//..--,,++**))((''&&%%$$###"""!!!````a!!!!!!!!!``!!""##$$%%&&''(())**++,,--..//0011223344556554433221100//..--,,++**))((''&&%%$$$$##""!!`!!!""##$$%%&&''(())**))((''&&%%$$##""!!``````!!""!!``!!""##$$%$$##"##$$%%%%$$$$##""!!!`ň`a!`!a`a!!""""!!`a`a!"!""##$$%%&&''(())))*****))**++++++,,,,,,,-----....////00111100//..------..///00112233444445556566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::9:9988776655566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????>>===<<;;;;;::998877665554443333322211111000000000100//..--,,++**)**+**))(('''&&%%%$$$#$######""!!`†`!!!""##$$%%&&''(())**++,+,,,,,,,,,----..//0000001122334455667788999887766554433221100//..--,,++**))((''&&%%$$####""!!!```a!!!!!""""""!!`ƒ`!!""##$$%%&&''(())**++,,--..//00112233445566554433221100//..--,,++**))((''&&%%$$$$##""!!!!""##$$%%&&''(())***))((''&&%%$$##""!!`ē`!!"!!``!!""##$$$##"""##$$%%$$$$##""!!!````!!!"""##""!!!a!"!!!""##$$%%&&''((())))*)))))**+**+++++,,,,,------...////001000//..--,,-,--..///00112233343444555566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::::99887766666778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????>>>==<<;<<;;::9988776665544444333222222111110011100//..--,,++**)))**+**))(((''&&%%%%$$$$##$##""!!`ƅ`!!!""##$$%%&&''(())**+++++,,,,,,,,,---..//////001122334455667788999887766554433221100//..--,,++**))((''&&%%$$$###"""!!`Æ``````````a!!!!"""""""""!!``!!""##$$%%&&''(())**++,,--..//0011223344556666554433221100//..--,,++**))((''&&%%%%$$##""!"""##$$%%&&''(())**+**))((''&&%%$$##""!!`ŏ`!!"!!`̏`!!""###$##""!""##$$$$####""!!`````a!!"""####""!"!"!!`!!""##$$%%&&''(((()))))(())******+++++++,,,,,----....//0000//..--,,,,,,--...//00112233333444545566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<|{;:;::998877666778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????>>>==<<<<<;;::99887766655544444333222221111111100//..--,,++**))())**+**))(((''&&&%%%$%$$$$##""!!`ƈ``!!""##$$%%&&''(())**+*+++++++++,,,,--..//////001122334455667788999887766554433221100//..--,,++**))((''&&%%$$$$##"""!!`````a!!!!!!!````a!!!""""""#####""!!``a!""##$$%%&&''(())**++,,--..//001122334455667766554433221100//..--,,++**))((''&&%%%%$$##""""##$$%%&&''(())**++**))((''&&%%$$##""!!``!!!!`Nj`!!""#"###""aa!""##$$####""!!`ǎ`a`a!"""###$$##"""!!!``!!""##$$%%&&'''(((()((((())*))*****+++++,,,,,,---....//0///..--,,++,+,,--...//00112223233344445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;;;::9988777778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<==<<;;::998877766555554443333332222211100//..--,,++**))((())**+**)))((''&&&&%%%%$$##""!!``!!""##$$%%&&''(())*****+++++++++,,,--......//001122334455667788999887766554433221100//..--,,++**))((''&&%%%$$$###""!!!````a!!!!!!!!!!!!!!!!"""""#########""!!```````ҁ`a!""##$$%%&&''(())**++,,--..//00112233445566777766554433221100//..--,,++**))((''&&&&%%$$##"###$$%%&&''(())**++++**))((''&&%%$$##""!!``!!!!``!!"""""#""!!`!!""####""""!!`ć`a!!!"""###$$$##""!!!!``!!""##$$%%&&'''''(((((''(())))))*******+++++,,,,----..////..--,,++++++,,---..//00112222233343445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;|;;::99887778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=====<<;;::9988777666555554443333322221100//..--,,++**))(('(())**+**)))(('''&&&ef%%$$##""!!``!!""##$$%%&&''((())*)*********++++,,--......//001122334455667788999887766554433221100//..--,,++**))((''&&%%%%$$###""!!!!!!!!!""""""""!!!!""""######$$$$$##""!!``a!!!!```!!""##$$%%&&''(())**++,,--..//001122334455667787766554433221100//..--,,++**))((''&&&&%%$$####$$%%&&''(())**++,,++**))((''&&%%$$##""!!`̛`!!!!`Ê`!!"""!"""!!``!!""##""""!!!`ń``a!"!""###$$$$##""!!`!!a`a!""##$$%%&&'''&''''('''''(()(()))))*****++++++,,,----../...--,,++**+*++,,---..//00111212223333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<||<;;::998888899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=>>==<<;;::99888776666655544444433221100//..--,,++**))(('''(())**+***))((''''&&%%$$##""!!!`Κ`!!""##$$%%&&'''((()))))*********+++,,------..//001122334455667788999887766554433221100//..--,,++**))((''&&&%%%$$$##"""!!!!"""""""""""""""""#####$$$$$$$$$##""!!!!!!!```Ç`!!""##$$%%&&''(())**++,,--..//00112233445566778887766554433221100//..--,,++**))((''''&&%%$$#$$$%%&&''(())**++,,,,++**))((''&&%%$$##""!!``̐`!!!``!!""!!!"""!a`a!!""#""!!!!!`ĉ`!!""""###$$$$##""!!``!aa!""""##$$%%&&&&&&&'''''&&''(((((()))))))*****++++,,,,--....--,,++******++,,,--..//00111112223233445566778899::;;<<==>>???????????????????????????>>???????????????????????????????????????????????????>>==<=<<;;::9988899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>==<<;;::998887776666655544433221100//..--,,++**))((''&''(())**+***))((''&&%%$$##""!!```!!""##$$%%&&&''''(()()))))))))****++,,------..//001122334455667788999887766554433221100//..--,,++**))((''&&&&%%$$$##"""""""""########""""####$$$$$$%%%%%$$##""!!"""!a`a!`Ə`!!""##$$%%&&''(())**++,,--..//0011223344556677889887766554433221100//..--,,++**))((''''&&%%$$$$%%&&''(())**++,,-,,++**))((''&&%%$$##""!!!!`́``!!`ŋ`!!"!!`aa"""!!!`!!"""!!!!``ć`a!"""#######$$##""!!`a!"!"""!""##$$%%&&&%&&&&'&&&&&''(''((((()))))******+++,,,,--.---,,++**))*)**++,,,--..//00010111222233445566778899::;;<<==>>?????????????????????>??>>>>>???????????????????????????????????????????????????>>====<<;;::99999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????>??>>==<<;;::9998877777666554433221100//..--,,++**))((''&&&''(())****))((''&&%%$$##""!!``Ǔ`!!""##$$%%&&&&'''((((()))))))))***++,,,,,,--..//001122334455667788999887766554433221100//..--,,++**))(('''&&&%%%$$###""""#################$$$$$%%%%%%%%%$$##"""""""!a!!`ɔ`!!""##$$%%&&''(())**++,,--..//001122334455667788999887766554433221100//..--,,++**))((((''&&%%$%%%&&''(())**++,,-,,++**))((''&&%%$$##""!!`!!``!`‡`!a!!``a!""a!``!!"!!```ƅ`!!!""###"########""!a!"""""!!!""##$$e%e%%%%&&&&&%%&&''''''((((((()))))****++++,,----,,++**))))))**+++,,--..//00000111212233445566778899::;;<<==>>???????????????????>>>>>>==>>???????????????????????????????????????????????????>>=>==<<;;::999::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99988877766554433221100//..--,,++**))((''&&%&&''(())***))((''&&%%$$##""!!`›`!!""##$$%%%%&&&&''('((((((((())))**++,,,,,,--..//001122334455667788999887766554433221100//..--,,++**))((''''&&%%%$$#########$$$$$$$$####$$$$%%%%%%&&&&&%%$$##""###""!!!`Ў`!!""##$$%%&&''(())**++,,--..//00112233445566778899:99887766554433221100//..--,,++**))((((''&&%%%%&&''(())**++,,-,,++**))((''&&%%$$##""!!``a!`Ŗ`!```a!!!`aa"""a!``!!!!`ŋ`!`!!""""""""####""!!`!!"""!!`a!""##$d%e%$%%%%&%%%%%&&'&&'''''((((())))))***++++,,-,,,++**))(()())**+++,,--..///0/00011112233445566778899::;;<<==>>?????????????????>>=>>=====>>???????????????????????????????????????????????????>>>>==<<;;:::::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;:::99887766554433221100//..--,,++**))((''&&%%%&&''(())*))((''&&%%$$##""!!`Ą``!!""##$$%%%%%&&&'''''((((((((()))**++++++,,--..//001122334455667788999887766554433221100//..--,,++**))((('''&&&%%$$$####$$$$$$$$$$$$$$$$$%%%%%&&&&&&&&&%%$$######""!!``a!""##$$%%&&''(())**++,,--..//00112233445566778899:::99887766554433221100//..--,,++**))))((''&&%&&&''(())**++,,---,,++**))((''&&%%$$##""!!``a`ɔ```ć`!!!!!"""""!!`a`!!!`ƒ``!!"""!""""""""!!``!!"!a``a!""##$$$$$$$%%%%%$$%%&&&&&&'''''''((((())))****++,,,,++**))(((((())***++,,--../////00010112233445566778899::;;<<==>>???????????????>>======<<==>>???????????????????????????????????????????????????>?>>==<<;;:::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$%%&&''(())))((''&&%%$$##""!!``!!""##$$$$%%%%&&'&'''''''''(((())**++++++,,--..//001122334455667788999887766554433221100//..--,,++**))((((''&&&%%$$$$$$$$$%%%%%%%%$$$$%%%%&&&&&&'''''&&%%$$##$##""!!`ō`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;::99887766554433221100//..--,,++**))))((''&&&&''(())**++,,--.--,,++**))((''&&%%$$##""!!`aaa``„``„`!!"!""""!""!!`````ƈ``!!""!!!!!!"""""!!``!!"!!```!!""###$$$#$$$$%$$$$$%%&%%&&&&&'''''(((((()))****++,+++**))((''('(())***++,,--..././//0000112233445566778899::;;<<==>>?????????????>>==<==<<<<<==>>?????????????????????????????????????????????????????>>==<<;;;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%&&''(())((''&&%%$$##""!!``!!""###$$$$$%%%&&&&&'''''''''((())******++,,--..//001122334455667788999887766554433221100//..--,,++**)))((('''&&%%%$$$$%%%%%%%%%%%%%%%%%&&&&&'''''''''&&%%$$$$cc""!!`˔``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;::99887766554433221100//..--,,++****))((''&'''(())**++,,--...--,,++**))((''&&%%$$##""!!a``!````!!""""!!!!!`À`!!"!!!`!!!!!!!!!``!!!!```!!""########$$$$$##$$%%%%%%&&&&&&&'''''(((())))**++++**))((''''''(()))**++,,--.....///0/00112233445566778899::;;<<==>>???????????>>==<<<<<<;;<<==>>?????????????????????????????????????????????????????>>==<<;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#$$%%&&''((((''&&%%$$##""!!```͚`!!""#####$$$$%%&%&&&&&&&&&''''(())******++,,--..//001122334455667788999887766554433221100//..--,,++**))))(('''&&%%%%%%%%%&&&&&&&&%%%%&&&&''''''(((((''&&%%$$$#c""!!`ɏ`!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<;;::99887766554433221100//..--,,++****))((''''(())**++,,--....--,,++**))((''&&%%$$##""!!``!`Ǎ```!!"""!!`!!!`Ć`!!!`````!!!!!``a!ba!`ǀ`!!""""###"####$#####$$%$$%%%%%&&&&&''''''((())))**+***))((''&&'&''(()))**++,,---.-...////00112233445566778899::;;<<==>>?????????>>==<<;<<;;;;;<<==>>?????????????????????????????????????????????????????>>==<<<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###$$%%&&''((''&&%%$$##""!!`ț`a!"""""#####$$$%%%%%&&&&&&&&&'''(())))))**++,,--..//001122334455667788999887766554433221100//..--,,++***)))(((''&&&%%%%&&&&&&&&&&&&&&&&&'''''((((((((''&&%%$$##""!!``!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<;;::99887766554433221100//..--,,++++**))(('((())**++,,--..//..--,,++**))((''&&%%$$##""!!``!`ב```!!"!!``!`É`!`ˏ``````!!"a!``!!"""bb"""""#####""##$$$$$$%%%%%%%&&&&&''''(((())****))((''&&&&&&''((())**++,,-----..././/00112233445566778899::;;<<==>>???????>>==<<;;;;;;::;;<<==>>?????????????????????????????????????????????????????>>==<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"##$$%%&&''''&&%%$$##""!!`‰`!!!!""""""####$$%$%%%%%%%%%&&&&''(())))))**++,,--..//001122334455667788999887766554433221100//..--,,++****))(((''&&&&&&&&&''''''''&&&&''''(((((()))((''&&%%$$##""!!``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;::99887766554433221100//..--,,++++**))(((())**++,,--..////..--,,++**))((''&&%%$$##""!!``!`ɏ```a!"""!!`!!`````!``a!""!!`͋`!!""!!!"""!""""c"""""##$##$$$$$%%%%%&&&&&&'''(((())*)))((''&&%%&%&&''((())**++,,,-,---....//00112233445566778899::;;<<==>>?????>>==<<;;:;;:::::;;<<==>>?????????????????????????????????????????????????????>>=====>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$%%&&'''&&%%$$##""!!`Ä`!!!!!!"""""###$$$$$%%%%%%%%%&&&''(((((())**++,,--..//001122334455667788999887766554433221100//..--,,+++***)))(('''&&&&'''''''''''''''''((((())))))((''&&%%$$##""!!``!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<===<<;;::99887766554433221100//..--,,,,++**))()))**++,,--..//00//..--,,++**))((''&&%%$$##""!!`a````a!""#""!!!!``!!!!`````````a!"""!!``!!!!!!!!!!!!"""""!!""######$$$$$$$%%%%%&&&&''''(())))((''&&%%%%%%&&'''(())**++,,,,,---.-..//00112233445566778899::;;<<==>>???>>==<<;;::::::99::;;<<==>>?????????????????????????????????????????????????????>>===>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!""##$$%%&&''&&%%$$##""!!`͉```!!!!!!""""##$#$$$$$$$$$%%%%&&''(((((())**++,,--..//001122334455667788999887766554433221100//..--,,++++**)))(('''''''''((((((((''''(((())))))*))((''&&%%$$##""!!`ń`!!""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>==<<;;::99887766554433221100//..--,,,,++**))))**++,,--..//0000//..--,,++**))((''&&%%$$##""!!````!!"""##""!"!!`Ã`!!!!``!`!``!!```a!""""!!````aaa!```!!!`!!!!"!!!!!""#""#####$$$$$%%%%%%&&&''''(()(((''&&%%$$%$%%&&'''(())**+++,+,,,----..//00112233445566778899::;;<<==>>?>>==<<;;::9::99999::;;<<==>>?????????????????????????????????????????????????????>>>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&&&%%$$##""!!`͊```!!!!!"""#####$$$$$$$$$%%%&&''''''(())**++,,--..//001122334455667788999887766554433221100//..--,,,+++***))(((''''((((((((((((((((()))))***))((''&&%%$$##""!!``Ɇ`!!""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>==<<;;::99887766554433221100//..----,,++**)***++,,--..//00100//..--,,++**))((''&&%%$$##""!!``!`ɒ`aabb""##"""!!`Ã`!!!``!!````!!!""""!!``!!aa``````!!!!!``!!""""""#######$$$$$%%%%&&&&''((((''&&%%$$$$$$%%&&&''(())**+++++,,,-,--..//00112233445566778899::;;<<==>>>==<<;;::9999998899::;;<<==>>?????????????????????????????????????????????????????>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`a!""##$$%%&&&%%$$##""!!`ŋ````!!!!""#"#########$$$$%%&&''''''(())**++,,--..//001122334455667788999887766554433221100//..--,,,,++***))((((((((())))))))(((())))*****))((''&&%%$$##""!!`†`a!""##$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?>>==<<;;::99887766554433221100//..----,,++****++,,--..//0011100//..--,,++**))((''&&%%$$##""!a``!!`Ѝ``aab"!""##""!!``!!!``!!`````!!!"""!!``!!!a```ʓ``!```!!"!!"""""#####$$$$$$%%%&&&&''('''&&%%$$##$#$$%%&&&''(())***+*+++,,,,--..//00112233445566778899::;;<<==>==<<;;::998998888899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&%%$$##""!!`ɌĄ``!!!"""""#########$$$%%&&&&&&''(())**++,,--..//001122334455667788999887766554433221100//..---,,,+++**)))(((()))))))))))))))))*****+**))((''&&%%$$##""!!`Ã`a!""##$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???>>==<<;;::99887766554433221100//....--,,++*+++,,--..//00111100//..--,,++**))((''&&%%$$##""!!``!`Ė`a!!!!""##""!!``a!!!`Ҍ```!!!!!!!!!````!!!`ƈ````!!!!!!!"""""""#####$$$$%%%%&&''''&&%%$$######$$%%%&&''(())*****+++,+,,--..//00112233445566778899::;;<<===<<;;::99888888778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!!""##$$%%&&%%$$##""!!`ˇ``!!"!"""""""""####$$%%&&&&&&''(())**++,,--..//001122334455667788999887766554433221100//..----,,+++**)))))))))********))))****++++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????>>==<<;;::99887766554433221100//....--,,++++,,--..//001121100//..--,,++**))((''&&%%$$##""!!``!!`Љ`!!`a!""""!!```a!!!`ŏӇ`!``!!!!!!```!!!aa`‡``a```a!!``!!!!!"""""######$$$%%%%&&'&&&%%$$##""#"##$$%%%&&''(()))*)***++++,,--..//00112233445566778899::;;<<=<<;;::9988788777778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!""##$$%%&&&%%$$##""!!`Ά`!!!!!"""""""""###$$%%%%%%&&''(())**++,,--..//001122334455667788999887766554433221100//...---,,,++***))))*****************+++++++**))((''&&%%$$##""!!`…`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????>>==<<;;::99887766554433221100////..--,,+,,,--..//0011221100//..--,,++**))((''&&%%$$##""!!``!`Ò`!``!!""!!````!!"!!`ʓ``````a!``!!!``a````!``a```!!!!!!!"""""####$$$$%%&&&&%%$$##""""""##$$$%%&&''(()))))***+*++,,--..//00112233445566778899::;;<<<;;::998877777766778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!""##$$%%&&&&%%$$##""!!``!`!!!!!!!!!""""##$$%%%%%%&&''(())**++,,--..//001122334455667788999887766554433221100//....--,,,++*********++++++++****++++,,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????>>==<<;;::99887766554433221100////..--,,,,--..//001122221100//..--,,++**))((''&&%%$$##""!!```!!`̋`ƒ`!!!!!a`!``!!"!!`ʚ``!`````!!``a!!``!!!`Ã`!!```Ą```!!!!!""bb""###$$$$%%&%%%$$##""!!"!""##$$$%%&&''((()()))****++,,--..//00112233445566778899::;;<;;::99887767766666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""##$$%%&&'&&%%$$##""!!`````!!!!!!!!!"""##$$$$$$%%&&''(())**++,,--..//001122334455667788999887766554433221100///...---,,+++****+++++++++++++++++,,,,,,++**))((''&&%%$$##""!!`Ê`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????>>==<<;;::9988776655443322110000//..--,---..//00112233221100//..--,,++**))((''&&%%$$##""!!``!`Ō``!!``!!!!`Ä`!!"!!`Օ`!!!!!a``````!!!!!!!!!``a!!```!!!`̉````!!!!!""""####$$%%%%$$##""!!!!!!""###$$%%&&''((((()))*)**++,,--..//00112233445566778899::;;;::9988776666665566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"##$$%%&&'''&&%%$$##""!!`ą```````!!!!""##$$$$$$%%&&''(())**++,,--..//001122334455667788999887766554433221100////..---,,+++++++++,,,,,,,,++++,,,,--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????>>==<<;;::9988776655443322110000//..----..//0011223333221100//..--,,++**))((''&&%%$$##""!!``````!!!`Ã`a!"!!`Ԙ`!!!!!!!!!aa!!!!``````!!!````Ń`!!`Ǝ`!!!!!!"""####$$%$$$##""!!``!`a!""###$$%%&&'''('((())))**++,,--..//00112233445566778899::;::998877665665555566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###$$%%&&''(''&&%%$$##""!!```!!!""######$$%%&&''(())**++,,--..//0011223344556677889998877665544332211000///...--,,,++++,,,,,,,,,,,,,,,,,-----,,++**))((''&&%%$$##""!!`ȉ`a!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>==<<;;::9988776655443322111100//..-...//001122334433221100//..--,,++**))((''&&%%$$##""!!`````!!!`ƒ`!!"!!`Ҙ``Ր`!!""!!!!!```!```!!````````!!!!""""##$$$$##""!!```a!"""##$$%%&&'''''((()())**++,,--..//00112233445566778899:::99887766555555445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#$$%%&&''((''&&%%$$##""!!`Ò``!!""######$$%%&&''(())**++,,--..//00112233445566778899988776655443322110000//...--,,,,,,,,,--------,,,,----..--,,++**))((''&&%%$$##""!!``̌`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????>>==<<;;::9988776655443322111100//....//0011223344433221100//..--,,++**))((''&&%%$$##""!!``!```a``a!"!!``````!!"!!`Ǐ`ђ`!!""""!!```!!!``Δ``a!!""""##$#####""!!```a!b""bc#$$%%&&&'&'''(((())**++,,--..//00112233445566778899:9988776655455444445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$%%&&''((''&&%%$$##""!!`˒`!!""""""##$$%%&&''(())**++,,--..//00112233445566778899988776655443322111000///..---,,,,-----------------.....--,,++**))((''&&%%$$##""!!``a!""##$$%%&&''(())**++,,---..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988776655443322221100//.///001122334454433221100//..--,,++**))((''&&%%$$##""!!`a!!``!!!!`a!"""!!!!!a```````Ɔ`!!""!!``Ā`Ɉ`aa"""""!!```````!!`ט``a!!!""########""!!!```aa"!bb##$$%%&&&&&'''('(())**++,,--..//0011223344556677889998877665544444433445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$%%&&''((''&&%%$$##""!!`А`!!""""""##$$%%ff''(())**++,,--..//00112233445566778899988776655443322111100///..---------........----....//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,-,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988776655443322221100////00112233445554433221100//..--,,++**))((''&&%%$$##""!!!"!!`ȑ`!!"!!!""#""!!!!!!!!!!!```!!"""!a`Ȅ```a!""#""!!``a!```a!!```aa!!```a!!!""#"""""""""!!````!a!!""##$$%%%&%&&&''''(())**++,,--..//0011223344556677889887766554434433333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%&&''((''&&%%$$##""!!`͊`!!!!!!""##$$%%f&''(())**++,,--..//001122334455667788999887766554433222111000//...----................./////..--,,++**))((''&&%%$$##""!!`‡`!!""##$$%%&&''(())**++,,,,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988776655443333221100/00011223344556554433221100//..--,,++**))((''&&%%$$##""!"""!!`Ō`!!""!""###""""""!!!!!!a```!`a!""""!!``a!`„`a!""#""!!aa!!!!!!`!!aab"!!```````!!""""""""""!!``aa`!!""##$$%%%%%&&&'&''(())**++,,--..//0011223344556677888776655443333332233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%&&''(((''&&%%$$##""!!`τ`!!!!!!""##$$%%&&''(())**++,,--..//001122334455667788999887766554433222211000//.........////////....////00//..--,,++**))((''&&%%$$##""!!`Ɖ`a!""##$$%%&&''(())**++,,,,+,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988776655443333221100001122334455666554433221100//..--,,++**))((''&&%%$$##"""#""!!`Î`!!""""#####"""""""""""!!!!!!!""#""!!`Љ``Ȇ`!!""##""!!""!!!!``!!"bb!!!`a!!````Ã`!!"!!!!!a!!!!`ǐ`!``!!""##$$$%$%%%&&&&''(())**++,,--..//0011223344556677877665544332332222233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&''((((''&&%%$$##""!!`…`````!!""##$$%%&&''(())**++,,--..//001122334455667788999887766554433322211100///..../////////////////0000//..--,,++**))((''&&%%$$##""!!``aa""##$$%%&&''(())**++,,,,+++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988776655444433221101112233445566766554433221100//..--,,++**))((''&&%%$$##"###""!!``!!""""######""##"""""""!!!ba""##""!!`҅`!``a!""###""""""""!!`a!""ba!!!!!!!!!!!````!!!!!!aaaa!a```a!!``!!""###$$$$$%%%&%&&''(())**++,,--..//0011223344556677766554433222222112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&''(()((''&&%%$$##""!!`ƒ`!!""##$$%%&&''(())**++,,--..//001122334455667788999887766554433332211100/////////00000000////0000100//..--,,++**))((''&&%%$$##""!!`Ƈ`aa""##$$%%&&''(())**++,,,++*++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988776655444433221111223344556677766554433221100//..--,,++**))((''&&%%$$###$##"b!!``!!!!""""""#"""""""##"""""""""###""!!``!!```!!""###""##""""!!!"""!a`!`a!!`a!!!!!````!aa``````````֋`!!!!``!!"""###$#$$$%%%%&&''(())**++,,--..//0011223344556676655443322122111112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''(()))((''&&%%$$##""!!`Ç`!!""##$$%%&&''(())**++,,--..//00112233445566778899998877665544433322211000////0000000000000000011100//..--,,++**))((''&&%%$$##""!!`Ɇ`aa""##$$%%&&''(())**++,,++***++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988776655554433221222334455667787766554433221100//..--,,++**))((''&&%%$$#$$$#cbb!!``!!!!!!""""""!!""""b"""""""""####""!!``!!````!!""#########""!"""!!```!``!!"!!!!````ր`a!""!!``!!"""#####$$$%$%%&&''(())**++,,--..//0011223344556665544332211111100112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('(()))((''&&%%$$##""!!`ɂ`!!""##$$%%&&''(())**++,,--..//001122334455667788999988776655444433222110000000001111111100001111100//..--,,++**))((''&&%%$$##""!!`@`!!""##$$%%&&''(())**++++**)**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988776655554433222233445566778887766554433221100//..--,,++**))((''&&%%$$$%$$#c""!!````````!!!!!!"aa!!!!ab"!!"""!""##$##""!!```!!!!``!`a!""###"##$####"""#""!!``!``!!""!!!`Ã``Ǝ`a!"""!!``!!!"""#"###$$$$%%&&''(())**++,,--..//0011223344556554433221101100000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((())*))((''&&%%$$##""!!`Å`!!""##$$%%&&''(())**++,,--..//00112233445566778899:998877665554443332211100001111111111111111121100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++**)))**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988776666554433233344556677889887766554433221100//..--,,++**))((''&&%%$%%%$$##""!!``a```a!!!!!``!!!!a!!!!"!!!""#####""!!``!!!!!!!!ab"##""""####$##"c"""!!!``!``!!"""!!``a``````!!""#""!!``!!!"""""###$#$$%%&&''(())**++,,--..//001122334455544332211000000//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))())***))((''&&%%$$##""!a``Š`!!""##$$%%&&''(())**++,,--..//00112233445566778899::998877665555443332211111111122222222111122221100//..--,,++**))((''&&%%$$##""!!`Ȉ`a!""##$$%%&&''(())**++**))())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988776666554433334455667788999887766554433221100//..--,,++**))((''&&%%%&%%$$##""!!a`đ````!`````!!``!!!`!!""#""##""!!`a!"""!!"!"""""""!""#"###"bb"!!a!!!!!``!!""""!!`ƒ`!!!```a!!!""##""!!````!!!"!"""####$$%%&&''(())**++,,--..//001122334454433221100/00/////00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))**+**))((''&&%%$$##""!!a`Ǖ`!!""##$$%%&&''(())**++,,--..//00112233445566778899:::998877666555444332221111222222222222222223221100//..--,,++**))((''&&%%$$##""!!`ʍ`!!""##$$%%&&''(())**+**))((())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988777766554434445566778899:99887766554433221100//..--,,++**))((''&&%&&%%$$##""!!```ƈ```!``!!"""""""""!!a"""""""""""""!!!!""""#"ba"!!!``!!!!!```a!""#""!!`‚``a!!!!!!!!!""####""!!``!!!!!"""#"##$$%%&&''(())**++,,--..//0011223344433221100//////..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)**+++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899:::99887766665544433222222222333333332222333221100//..--,,++**))((''&&%%$$##""!!`ȍ`a!""##$$%%&&''(())****))(('(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::99887777665544445566778899:::99887766554433221100//..--,,++**))((''&&&&&%%$$##""!!```Бɇ`aaa``!!"!!""!"""abb"b""!""""!!!!!`!!"!"bba!!!```!!"!!aa!""#""!!```!!"""!!!""""######""!!``````!`!!!""""##$$%%&&''(())**++,,--..//00112233433221100//.//.....//00112233445566778899::;;<<==>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***++,++**))((''&&%%$$##""!!`ʌ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::::9988777666555443332222333333333333333333221100//..--,,++**))((''&&%%$$##""!!`É`a!""##$$%%&&''(())***))(('''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::998888776655455566778899::;::99887766554433221100//..--,,++**))((''&''&&%%$$##""!!!!```ƈdž````!!!`!!!!!!!!!!!!!aaaaa!!!"!!!!!```aa!!b!a`a``!!"""!!!""#""!!`Á†`!!""""""!""##"####""aaa!`````!!!"!""##$$%%&&''(())**++,,--..//001122333221100//......--..//00112233445566778899::;;<<==??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*++,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;::9988777766555443333333334444444433334433221100//..--,,++**))((''&&%%$$##""!!`Ɏ`!!""##$$%%&&''(())*))((''&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::9988887766555566778899::;;;::99887766554433221100//..--,,++**))(('''''&&%%$$##""!!!!!!````ˊ```!!!!!``!!`!!!!!!!!!!`!!!!````aa`!!!``!``a!""#"""""##""!!`Ä```!!""""!!!"""""####""!!```!```!!a!""##$$%%&&''(())**++,,--..//0011223221100//..-..-----..//00112233445566778899::;;<<=???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++,,,,++**))((''&&%%$$##""!!`ƍ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;::998887776665544433334444444444444444433221100//..--,,++**))((''&&%%$$##""!!`ǎ`a!""##$$%%&&''(())*))((''&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::99998877665666778899::;;<;;::99887766554433221100//..--,,++**))(('((''&&%%$$##""""!!!!!`a`!`````````````````````a```````a``!a!`a!a`a!""###"""###""!!``ƒ``a!```Ŕ`!!""!!`!!""!""####""!a``!!``!`!!""#c$$%%&&''(())**++,,--..//00112221100//..------,,--..//00112233445566778899::;;<>==<<;;::99887766554433221100//..--,,+,,--,,++**))((''&&%%$$##""!!`ԑ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;;;::99888877666554444444445555555544444433221100//..--,,++**))((''&&%%$$##""!!`È`!!""##$$%%&&''(())))((''&&%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::999988776666778899::;;<<<;;::99887766554433221100//..--,,++**))(((((''&&%%$$##""""""!!!!!!!!!````````ʀʀ```a`a!b!!!baa!""##$#####$##""!a`````!`Ã`!!!!``!!!!!``!!!!!""####""!a``!!````!!""c#$$%%&&''(())**++,,--..//001121100//..--,--,,,,,--..//00112233445566778899::;;>==<<;;::99887766554433221100//..--,,,---,,++**))((''&&%%$$##""!!`ʔ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<;;::9998887776655544445555555555555554433221100//..--,,++**))((''&&%%$$##""!!`Ȇ`!!""##$$%%&&''(()))((''&&%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::::99887767778899::;;<<=<<;;::99887766554433221100//..--,,++**))())((''&&%%$$####"""""!"!"!!!!!!!!!!`````````a```А`a!!!"""!"""!""##$$$###$$$##""!!!!!!!!`Ã`!!"!!!`č``!!!!`a!!a`!!""###""!!```!a````!!""##$$%%&&''(())**++,,--..//00111100//..--,,,,,,++,,--..//00112233445566778899::;;??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,--.--,,++**))((''&&%%$$##""!!`ܙ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<;;::99998877766555555555666666665554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()((''&&%%$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;::::998877778899::;;<<===<<;;::99887766554433221100//..--,,++**)))))((''&&%%$$######"""""""""!!!!!!!!!!!`!```````````````````!a!!!``ք``a!"!""#"""#"""####$$$$$$$$$##""!!!!!"!!```a!""""!!`Ò`!``!!!!``!!""###""!!`a`!aa```!!""##$$%%&&''(())**++,,--..//001100//..--,,+,,+++++,,--..//00112233445566778899::;???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---..--,,++**))((''&&%%$$##""!!`Җ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<<<;;:::9998887766655556666666666666554433221100//..--,,++**))((''&&%%$$##""!!`Ɋ`!!""##$$%%&&''((((''&&%%$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;;;::9988788899::;;<<==>==<<;;::99887766554433221100//..--,,++**)**))((''&&%%$$$$#####"#"#""""""""""!!!!!!!!!!!!!!!``!!!!!!!!`ǃ``!!!""""###"###"#######$$$$$$####""""""""!!`````a!!""#""!!`ɋ```!!!!`a!""##$##""!!!!!!`ʏ```!!""##$$%%&&''(())**++,,--..//0000//..--,,++++++**++,,--..//00112233445566778899::????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..-...--,,++**))((''&&%%$$##""!!`Ǎ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==<<;;::::99888776666666667777777766554433221100//..--,,++**))((''&&%%$$##""!!`Lj`!!""##$$%%&&''(((''&&%%$$#$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<;;;;::99888899::;;<<==>>>==<<;;::99887766554433221100//..--,,++*****))((''&&%%$$$$$$#########"""""""""""!"!!!!!!!!!!``!!!!!!`ψ`!!!!""#"##$###""""#"""#########"###"""""#""!!!!!a!!""###""!!``DŽ```!!!!!"""##$$##""!"!"!!```aa!""##$$%%&&''((())**++,,--..//00//..--,,++*++*****++,,--..//00112233445566778899:????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.../..--,,++**))((''&&%%$$##""!!`ڞ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<====<<;;;:::99988777666677777777777766554433221100//..--,,++**))((''&&%%$$##""!!`ņ`!!""##$$%%&&''(''&&%%$$###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<<<;;::998999::;;<<==>>?>>==<<;;::99887766554433221100//..--,,++*++**))((''&&%%%%$$$$$#$#$##########"""""""""""""""!!```!`!!!``a!!"""####$$##"""""""""""######"""#########""!!aa!"""##$##""!!a```a!""!"""""##$$##""""""!!```aa``!!""##$$%%&&''((())**++,,--..////..--,,++******))**++,,--..//00112233445566778899????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.//..--,,++**))((''&&%%$$##""!!`ƒ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>==<<;;;;::9998877777777788888887766554433221100//..--,,++**))((''&&%%$$##""!!`Ō`!!""##$$%%&&'''&&%%$$##"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>==<<<<;;::9999::;;<<==>>???>>==<<;;::99887766554433221100//..--,,+++++**))((''&&%e%%%%$$$$$$$$$###########"#""""""""""!!!```!``!````!!""""##$#$$##""!!!!"!!!"""""""""!""######$##""!!`!!""##$$##""!!!``````a!""b"!"!""##$$##"#"#""!!!!a``!!""##$$%%&&'''(())**++,,--..//..--,,++**)**)))))**++,,--..//0011223344556677889???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////..--,,++**))((''&&%%$$##""!!`Ս`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>>==<<<;;;:::99888777788888888887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''&&%%$$##"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>====<<;;::9:::;;<<==>>?????>>==<<;;::99887766554433221100//..--,,+,,++**))((''&&f&%%%%%$%$%$$$$$$$$$$###############""!!!!!!a`a``a!!!"""###$$$$##""!!!!!!!!!!!""""""!!!""##$$$##""!!``!!""##$$##"""!!!!!!``aa""bba!!!!""##$$#####""!!!!!a``!!""##$$%%&&&'''(())**++,,--....--,,++**))))))(())**++,,--..//001122334455667788????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/0//..--,,++**))((''&&%%$$##""!!`И`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??>>==<<<<;;:::99888888888999999887766554433221100//..--,,++**))((''&&%%$$##""!!`Ҙ`!!""##$$%%&&'&&%%$$##""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>====<<;;::::;;<<==>>???????>>==<<;;::99887766554433221100//..--,,,,,++**))((''&&&&&&%%%%%%%%%$$$$$$$$$$$#$##########"""!!!"!!!!`a!!!""####$$$$##""!!````a```!!!!!!!!!`a!""##$$##""!!``!!""##$$##"""!!!!!!`!!""""!a`!`!!""##$$###""!!`!!"!!`a!""##$$%%&&&&&&''(())**++,,--..--,,++**))())((((())**++,,--..//00112233445566778?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110000//..--,,++**))((''&&%%$$##""!a`Җ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???>>===<<<;;;::9998888999999999887766554433221100//..--,,++**))((''&&%%$$##""!!`֔`!!""##$$%%&&&&%%$$##""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>>>==<<;;:;;;<<==>>?????????>>==<<;;::99887766554433221100//..--,--,,++**))((''''&&&&&%&%&%%%%%%%%%%$$$$$$$$$$$$$$$##"""""""!"!!!""""###$$#$$##""!!````!!!!!!``!!""##$##""!!``!!""##$$$###""""""!!!""""!!```!!""##$##""!!``!!"!!!""##$$%%&&&%%&&&''(())**++,,----,,++**))((((((''(())**++,,--..//0011223344556677??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322110100//..--,,++**))((''&&%%$$##""!!`͞`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????>>====<<;;;::999999999::::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ޓ`!!""##$$%%&&&%%$$##""!!`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>>>==<<;;;;<<==>>???????????>>==<<;;::99887766554433221100//..-----,,++**))((''''''&&&&&&&&&%%%%%%%%%%%$%$$$$$$$$$$###"""#""""!""""##$$######""!!``!`````````!!""####""!!`†`!!""##$$$$###""""""!""##""!!`a`!!""##$$$##""!!``!!"!""##$$%%&&&%%%%%&&''(())**++,,--,,++**))(('(('''''(())**++,,--..//001122334455667???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????>>>===<<<;;:::9999::::::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϙ`!!""##$$%%&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????>>==<<;<<<==>>?????????????>>==<<;;::99887766554433221100//..-..--,,++**))(((('''''&'&'&&&&&&&&&&%%%%%%%%%%%%%%%$$#######"#"""#####$###"####""!!``````…`!!""####""!!`Ņ`!!""##$$$$$######"""####""!!!!!""##$$%$$##""!!`a!""""##$$%%&&&%%$$%%%&&''(())**++,,,,++**))((''''''&&''(())**++,,--..//00112233445566????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƕ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????>>>>==<<<;;:::::::::::99887766554433221100//..--,,++**))((''&&%%$$##""!!``ٔ`!!""##$$%%&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<<<==>>???????????????>>==<<;;::99887766554433221100//.....--,,++**))(((((('''''''''&&&&&&&&&&&%&%%%%%%%%%%$$$###$####"########""""####""!!`Ã`!!""###""!!``!!""##$$%$$$######"##$$##""!"!""##$$%%%$$##""!!!""#"##$$%%&&&%%$$$$$%%&&''(())**++,,++**))((''&''&&&&&''(())**++,,--..//0011223344556?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ό`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????>>>===<<;;;::::;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ӑ`!!""##$$%%%%%$$##""!!`Ɖ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<===>>?????????????????>>==<<;;::99887766554433221100//.//..--,,++**))))((((('('(''''''''''&&&&&&&&&&&&&&&%%$$$$$$$#$###$$##"#"""!""##""!!`…`!!""####""!!`Æ`!!""##$$%%%$$$$$$###$$$$##"""""##$$%%&%%$$##""!""####$$%%&&&%%$$##$$$%%&&''(())**++++**))((''&&&&&&%%&&''(())**++,,--..//001122334455?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????>>===<<;;;;;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ԑ`!!""##$$%%%ed$##""!!``ʼn`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>====>>???????????????????>>==<<;;::99887766554433221100/////..--,,++**))))))((((((((('''''''''''&'&&&&&&&&&&%%%$$$%$$$$#$$##""""!!!!""""!!``a!""####""!!`…`!!""##$$%%%$$$$$$#$$%%$$##"#"##$$%%&&&%%$$##"""##$#$$%%&&&%%$$#####$$%%&&''(())**++**))((''&&%&&%%%%%&&''(())**++,,--..//00112233445??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`З`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????>>>==<<<;;;;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ԕ`!!""##$$%%$$$##""!!`Œ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????>>=>>>?????????????????????>>==<<;;::99887766554433221100/00//..--,,++****)))))()()(((((((((('''''''''''''''&&%%%%%%%$%$$$##""!"!!!`!!"""!!``!!""####""!!`Å`!!""##$$%%%%%%%%$$$%%%%$$#####$$%%&&'&&%%$$##"##$$$$%%&&&%%$$##""###$$%%&&''(())****))((''&&%%%%%%$$%%&&''(())**++,,--..//0011223344??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϔ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????>>>==<<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ӑ`!!""##$$%$$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????>>>>???????????????????????>>==<<;;::99887766554433221100000//..--,,++******)))))))))((((((((((('(''''''''''&&&%%%&%%%$$##""!!!!```!!!!!`†`!!""###""!!`Æ`!!!""##$$%%%%%%%%$%%&&%%$$#$#$$%%&&'''&&%%$$###$$%$%%&&&%%$$##"""""##$$%%&&''(())**))((''&&%%$%%$$$$$%%&&''(())**++,,--..//001122334??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ӎ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????>>===<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ғ`!!""##$$$$####"""!!`Ε`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????>??????????????????????????>>==<<;;::99887766554433221101100//..--,,++++*****)*)*))))))))))(((((((((((((((''&&&&&&%%$$##""!!`!``!!!```!!""###""!!`Å```!!""##$$%%&&&&%%%&&&&%%$$$$$%%&&''(''&&%%$$#$$%%%%&&&%%$$##""!!b""##$$%%&&''(())))((''&&%%$$$$$$##$$%%&&''(())**++,,--..//00112233??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʐ`!!""##$$###""""!!`Ĕ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????>>==<<;;::99887766554433221111100//..--,,++++++*********)))))))))))()(((((((((('''&&&%%$$##""!!````!``a`a!""####""!!`Å`!!""##$$%%&&&&%&&''&&%%$%$%%&&''(((''&&%%$$$%%&%&&&%%$$##""!!!aa""##$$%%&&''(())((''&&%%$$#$$#####$$%%&&''(())**++,,--..//0011223???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ώ`!!""##$##""""!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????>>==<<;;::99887766554433221221100//..--,,,,+++++*+*+**********))))))))))))))((('''&&%%$$##""!!`ˊ````!!!""####"""!!`Ä`!!""##$$%%&&&&&''''&&%%%%%&&''(()((''&&%%$%%&&&&&%%$$##""!a``!!!""##$$%%&&''((((''&&%%$$######""##$$%%&&''(())**++,,--..//001122????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ò`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`͋`!!""####"""!!!!`Ê`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????>>==<<;;::99887766554433222221100//..--,,,,,,+++++++++***********)*))))(()((((''&&%%$$##""!!``ċ`!!!!""##""""!!``!!""##$$%%&&&''((''&&%&%&&''(()))((''&&%%%&&'&&%%$$##""!!```a!""##$$%%&&''((''&&%%$$##"##"""""##$$%%&&''(())**++,,--..//00112?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ύ`a!""####""!!!!``ƀ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::99887766554433233221100//..----,,,,,+,+,++++++++++******)))(((((''''&&%%$$##""!!`Ƈ```!!""""!""!!`Ã`!!""##$$%%&&''((((''&&&&&''(())*))((''&&%&&''&&%%$$##""!!```!!""##$$%%&&''''&&%%$$##""""""!!""##$$%%&&''(())**++,,--..//0011??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`–`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ǎ`!!""###""!!!``DŽ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433333221100//..------,,,,,,,,,+++++++**)*)))(((''(''''&&%%$$##""!!!``!!""!!!"!!`Ä`!!""##$$%%&&''(()((''&'&''(())*))((''&&%&&'''&&%%$$##""!!````!!""##$$%%&&''&&%%$$##""!""!!!!!""##$$%%&&''(())**++,,--..//001???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``˒`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????>>==<<;;::9yxx7766554433221100//..--,,++**))((''&&%%$$##""!!`ː`!!""###""!!``Å``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????>>==<<;;::99887766554434433221100//....-----,-,-,,,,,,,++**)))))((('''''&&&&%%$$##""!!!```ˍ``!!!!`!!!!`Ä`!!""##$$%%&&''(())(('''''(())*))((''&&%%%&&'''&&%%$$##""!!````!!""##$$%%&&'&&%%$$##""!!!!!!``a!""##$$%%&&''(())**++,,--..//00????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``ʔ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????>>==<<;;::99x87766554433221100//..--,,++**))((''&&%%$$##""!!`ː`a!""###""!!`Ɖ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????>>==<<;;::99887766554444433221100//......---------,,,++**))()((('''&&'&&&&%%$$##""!!``†`!!``!!!`Ã`!!""##$$%%&&''(()))(('('(())*))((''&&%%$%%&&'''&&%%$$##""!!``a!""##$$%%&&'&&%%$$##""!!`!!```!!""##$$%%&&''(())**++,,--..//0?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ѓ`!!""###""!!`nj`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????>>==<<;;::99887766554554433221100////.....-.-.---,,++**))((((('''&&&&&%%%%$$##""!!`````a!!`Ã`!!""##$$%%&&''(()))((((())*))((''&&%%$$$%%&&'''&&%%$$##""!!``a!""##$$%%&&'&&%%$$##""!!````!!""##$$%%&&''(())**++,,--..//??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!!`ʙ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Δ``!!""###"b!!`Ƌ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????>>==<<;;::99887766555554433221100//////......--,,++**))(('('''&&&%%&%%%%$$##""!!`ȆÀ`!!`Ä`!!""##$$%%&&''(()))()())*))((''&&%%$$#$$%%&&''&&%%%$$##""!!!!""##$$%%&&'''&&%%$$##""!a```````a!""##$$%%&&''(())**++,,--..//0???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""""!!!``ː`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ғ```a!!""####"b!!`ƌ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::9988776656655443322110000/////...--,,++**))(('''''&&&%%%%%$$$$##""!!`ʈ```Ã`!!""##$$%%&&''(()))))))*))((''&&%%$$###$$%%&&&&%%$%%$$##""!!""##$$%%&&''''&&%%$$##""!a````a!bb##$$%%&&''(())**++,,--..//00????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""""!!!`ƌ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ԗ`a!!!!""####""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????>>==<<;;::998877666665544332211000000//..--,,++**))((''&'&&&%%%$$%$$$$$##""!!`у`!!""##$$%%&&''(())*)*)*))((''&&%%$$##"##$$%%&&%%$$$%%$$##""""##$$%%&&''''&&%%$$##""!!`Α`!!""##$$%%&&''(())**++,,--..//001?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$####"""!!!`Ǝ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ˑ``!!!!"""##$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>==<<;;::9988776776655443322111100//..--,,++**))((''&&&&&%%%$$$$$######""!!``!!""###$$%%&&''(())***))((''&&%%$$##"""##$$%%%%$$#$$$%$$##""##$$%%&&''(''&&%%$$##""!!```!!""##$$%%&&''(())**++,,--..//0011??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$####"""!!`Κ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ϗ`!!"""""##$$$##""!!`ȍ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????>>==<<;;::99887777766554433221100//..--,,++**))((''&&%&%%%$$$##$#####""""!!`lj`!!""###$$%%&&''(())*))((''&&%%$$##""!""##$$%%$$###$$$%$$####$$%%&&''(((''&&%%$$##""!a```a!!""##$$%%&&''(())**++,,--..//00112???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$###""!!`Ҟ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`đ`!!""""###$$$$##""!!`‹`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????>>==<<;;::998877766554433221100//..--,,++**))((''&&%%%%%$$$#####"""""""!!`ƈ`!!!"""##$$%%&&''(()))((''&&%%$$##""!!!""##$$$$##"###$$%$$##$$%%&&''(()((''&&%%$$##""!aa!!!""##$$%%&&''(())**++,,--..//001122????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$$##""!!`͖`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Д`!!""#####$$%$$##""!!``a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$%$$$###""#"""""!!!!!`ƈ``!!"""##$$%%&&''(()((''&&%%$$##""!!`!!""##$$##"""###$$%$$$$%%&&''(()))((''&&%%$$##""!!!"""##$$%%&&''(())**++,,--..//0011223?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%$$##""!!`؝`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`͘``a!""####$$$%%%$$##""!!`ǎ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$###"""""!!!!!!!!`Ņ`!!!""##$$%%&&''(((''&&%%$$##""!!``!!""####""!"""##$$%$$%%&&''(())*))((''&&%%$$##""""""##$$%%&&''(())**++,,--..//00112233??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%$$##""!!`֝`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Δ`a!!""##$$$$$%%%%$$##""!!`ň`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#$###"""!!"!!!!!````ą``!!!""##$$%%&&''(((''&&%%$$##""!!`!!""####"ba!!"""##$$%%%&&''(())***))((''&&%%$$##"""###$$%%&&''(())**++,,--..//001122334???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`י`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``a!!""##$$$$%%%&%%$$##""!!`ȍ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#####"""!!!!!````Ȉ``a!""##$$%%&&''(((''&&%%$$##""!!!""####""aa`!!!""##$$%%&&''(())****))((''&&%%$$######$$%%&&''(())**++,,--..//0011223344???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`֔`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ε`!!""##$$%%%%%&&%%$$##""!!`ȉ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"#"""!!!``!`Ň`!!""##$$%%&&''(((''&&%%$$##""!""####""!!``!!!""##$$%%&&''(())****))((''&&%%$$###$$$%%&&''(())**++,,--..//00112233445???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Օ`!!""##$$%%&&''(())**++,,--../op0112233445566778899::;;<<==>>???????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȉ`!!""##$$%%&&&%%$$##""!!`Nj`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""a!!``ą`a!!""##$$%%&&''(((''&&%%$$##"""##$##""!!```!!""##$$%%&&''(())****))((''&&%%$$$$$$%%&&''(())**++,,--..//001122334455???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ց`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɐ`!!""##$$%%&&%%$$##""!!`ƍ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!"!!a``LjƇ`!!!!""##$$%%&&''(((''&&%%$$##"##$$$##""!!``!ab"##$$%%&&''(())****))((''&&%%$$$%%%&&''(())**++,,--..//0011223344556???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ה`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&%%$$##""!!`Ɏ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!`Ȋ`!`!!""##$$%%&&''(((''&&%%$$###$$%$$##""!!``!!""##$$%%&&''(())****))((''&&%%%%%%&&''(())**++,,--..//00112233445566???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ޔ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɏ`!!""##$$%%%%$$##""!!`Ĉ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`!``ć``!!""##$$%%&&''(((''&&%%$$#$$%%%$$##""!!``!!""##$$%%&&''(())****))((''&&%%%&&&''(())**++,,--..//001122334455667???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ה`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%$$##""!!`ō`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``Æ````!!""##$$%%&&''((((''&&%%$$$%%&%%$$##""!!```!!""##$$%%&&''(())**+**))((''&&&&&&''(())**++,,--..//0011223344556677???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ٗ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ǒ`!!""##$$%%%%dd##""!!`ʗ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&''((((''&&%%$%%&&&%%$$##""!!!`a!""##$$%%&&''(())**+++**))((''&&&'''(())**++,,--..//00112233445566778???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`՘`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`͑`!!""##$$%%%%d$##""!!`Ȗ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ă`!!""##$$%%&&''(()((''&&%%%&&'&&%%$$##""!!!!""##$$%%&&''(())**++,++**))((''''''(())**++,,--..//001122334455667788???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ؗ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`‘`!!""##$$%%%$$##""!!`Ȍ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȅ`!!""##$$%%&&''(())((''&&%&&'''&&%%$$##"""!""##$$%%&&''(())**++,,,++**))(('''((())**++,,--..//0011223344556677889??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ܒ```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Д`!!""##$$%%&%%$$##""!!`̈`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ą`!!""###$$%%&&''(())((''&&&''(''&&%%$$##""""##$$%%&&''(())**++,,-,,++**))(((((())**++,,--..//00112233445566778899??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ώ``!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɏ`!!""##$$%%&%%$$##""!!`ʋ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Æ`!!"""##$$%%&&''(())((''&''(((''&&%%$$###"##$$%%&&''(())**++,,---,,++**))((()))**++,,--..//00112233445566778899:??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ۑ`!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Γ`!!""##$$%%&%%$$##""!!`ʎ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƒ`!!"""##$$%%&&''(())(('''(()((''&&%%$$####$$%%&&''(())**++,,--.--,,++**))))))**++,,--..//00112233445566778899::??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ޕ````a!!""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϕ`!!""##$$%%&%%$$##""!!`ˋ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`„`!!!""##$$%%&&''(())(('(()))((''&&%%$$$#$$%%&&''(())**++,,--...--,,++**)))***++,,--..//00112233445566778899::;??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ޕ`a!!!!"""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϓ`a!""##$$%%&&%%$$##""!!`Ŋ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`…`!!a""##$$%%&&''(())((())*))((''&&%%$$$$%%&&''(())**++,,--../..--,,++******++,,--..//00112233445566778899::;;??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ݙ`a!!!!"""########$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʔ`a!""##$$%%&&&%%$$##""!!`Ȇ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```a!""##$$%%&&''(())())***))((''&&%%%$%%&&''(())**++,,--..///..--,,++***+++,,--..//00112233445566778899::;;>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`מ`!!"""""#########$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʓ```!!""##$$%%&&'&&%%$$##""!!``Ȇ``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""aa`Å``!!""##$$%%&&''(()))**+**))((''&&%%%%&&''(())**++,,--...////..--,,++++++,,--..//00112233445566778899::;;<>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`؛`!!"""""###$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ĕ``!!!!""##$$%%&&'''&&%%$$##""!!!`````a!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""aa``!!""##$$%%&&''(())**+++**))((''&&&%&&''(())**++,,--..-..////..--,,+++,,,--..//00112233445566778899::;;<<=?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʓ`a!""#####$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!""##$$%%&&''(''&&%%$$##""!!!!`a!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!a``!!""##$$%%&&''(())**++,++**))((''&&&&''(())**++,,--..---...///..--,,,,,,--..//00112233445566778899::;;<<==?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʔ`!!""####$$$%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϋ`!!"""##$$%%&&''(((''&&%%$$##"""!!!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,++**))(('''&''(())**++,,--..--,--...///..--,,,---..//00112233445566778899::;;<<==>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`۞`!!""##$$$%%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʔ`!!""##$$%%&&''(()((''&&%%$$##""""!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,,++**))((''''(())**++,,--..--,,,---..///..------..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`֖`!!""##$$%%%&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Đ`!!""##$$%%&&''(())((''&&%%$$###""""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`lj`!!""##$$%%&&''(())**++,,,++**))((('(())**++,,--..--,,+,,---..///..---...//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ӎ`!!""##$$%%&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Г`!!""##$$%%&&''(()))((''&&%%$$####"#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ĉ`!!""##$$%%&&''(())**++,,,++**))(((())**++,,--..--,,+++,,,--..///......//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`З`!!""##$$%%&&''''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɍ`!!""##$$%%&&''(())*))((''&&%%$$$######$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʊ`!!""##$$%%&&''(())**++,,,,++**)))())**++,,--..--,,++*++,,,--..///...///00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϑ`a!""##$$%%&&''''''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̏`!!""##$$%%&&''(())**))((''&&%%$$$$#$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ˋ`!!""##$$%%&&''(())**++,,-,,++**))))**++,,--..--,,++***+++,,--..///////00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`җ`!!""##$$%%&&''((((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())***))((''&&%%%$$$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ƌ`!!""##$$%%&&''(())**++,,--,,++***)**++,,--..--,,++**)**+++,,--..//..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϛ`!!""##$$%%&&''(((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())****))((''&&%%%%$%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""aa`ʉ`!!""##$$%%&&''(())**++,,---,,++****++,,--..--,,++**)))***++,,--......//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ҍ`a!""##$$%%&&''(())))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ð`!!""##$$%%&&''(())**++**))((''&&&%%%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ō`!!""##$$%%&&''(())**++,,----,,+++*++,,--..--,,++**))())***++,,--..--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ː`!!""##$$%%&&''(())))**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɏ``!!""##$$%%&&''(())**++++**))((''&&&&%&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`NJ`!!""##$$%%&&''(())**++,,--.--,,++++,,-mn.--,,++**))((()))**++,,------..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ڞ`!!""##$$%%&&''(())****++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`‹`a!!""##$$%%&&''(())**++,,++**))(('''&&&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƌ`!!""##$$%%&&''(())**++,,--...--,,,+,,--..--,,++**))(('(()))**++,,--,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ї`a!""##$$%%&&''(())****++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Α`!!""##$$%%&&''(())**++,,,,++**))((''''&'''''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƍ`!!""##$$%%&&''(())**++,,--....--,,,,--..--,,++**))(('''((())**++,,,,,,--..//00112233445566778899::;;<<==>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ٞ`!!""##$$%%&&''(())**+++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɓ`a!""##$$%%&&''(())**++,,--,,++**))(((''''''((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȋ`!!""##$$%%&&''(())**++,,--../..---,--..--,,++**))((''&''((())**++,,++,,--..//00112233445566778899::;;<<==???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϗ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̎`!!""##$$%%&&''(())**++,,---,,++**))(((('((((())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʉ`a!""##$$%%&&''(())**++,,--..///..----..--,,++**))((''&&&'''(())**++++++,,--..//00112233445566778899::;;<<=???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ԕ@`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɍ`a!""##$$%%&&''(())**++,,--.--,,++**)))(((((()))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɖ`!!""##$$%%&&''(())**++,,--..////...-..--,,++**))((''&&%&&'''(())**++**++,,--..//00112233445566778899::;;<>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ٝ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ˊ`a!""##$$%%&&''(())**++,,--...--,,++**))))()))))**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`‰`!!""##$$%%&&''(())**++,,--..//0//....--,,++**))((''&&%%%&&&''(())******++,,--..//00112233445566778899::;;>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ҕ``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`†`!!""##$$%%&&''(())**++,,--....--,,++***))))))***++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƍƅ`!!""##$$%%&&''((i)**++,,--..//00//..--,,++**))((''&&%%$%%&&&''(())**))**++,,--..//00112233445566778899::;;???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϔ`a`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʋ``!!""##$$%%&&''(())**++,,--..//..--,,++****)*****++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`č``````ą`!!""##$$%%&&''((i)**++,,--..//0//..--,,++**))((''&&%%$$$%%%&&''(())))))**++,,--..//00112233445566778899::;???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϑ`a!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ȋ`a!!""##$$%%&&''(())**++,,--..////..--,,+++******+++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Í````!!!!!!```„`!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$#$$%%%&&''(())(())**++,,--..//00112233445566778899::???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ɍ`!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ȋ`a!!""##$$%%&&''(())**++,,--..//00//..--,,++++*+++++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`č``````!!!!!!!!!!!!!````!!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$###$$$%%&&''(((((())**++,,--..//00112233445566778899:???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ϊ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0000//..--,,,++++++,,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƍ``!!!!!!!!!!""""""!!!!!``!!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##"##$$$%%&&''((''(())**++,,--..//00112233445566778899???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ҍ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`†``!!""##$$%%&&''(())**++,,--..//001100//..--,,,,+,,,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Nj```!!!!!!!!"""""""""""""!!!``a!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##"""###$$%%&&''''''(())**++,,--..//0011223344556677889???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`͈`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ȉ`a!!""##$$%%&&''(())**++,,--..//00111100//..---,,,,,,---..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``ˊ`a!!!!""""""""""######"""""!!`…`ȍ`a!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##""!""###$$%%&&''&&''(())**++,,--..//001122334455667788???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʏ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ό``!!!""##$$%%&&''(())**++,,--..//0011221100//..----,-----..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʋĄÄ`!!!""""""""#############""!!```ʍ`!!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!!"""##$$%%&&&&&&''(())**++,,--..//00112233445566778??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̉ą`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````!!!"""##$$%%&&''(())**++,,--..//001122221100//...------...//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ņ```````!!""""##########$$$$$$####""!a````Ɂ`!!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!`!!"""##$$%%&&%%&&''(())**++,,--..//0011223344556677??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Nj@ƒ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`É``!````````!!!!!"""##$$%%&&''(())**++,,--..//00112233221100//....-.....//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Lj`!`a!!!``!`!!"""########$$$$$$$$$$$$$##""!!``a!`Ċ`a!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!``!!!""##$$%%%%%%&&''(())**++,,--..//001122334455667??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̋```Ã`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````a!!!!!!!!!!!!!"""###$$%%&&''(())**++,,--..//0011223333221100///......///00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``Æ``a!!!!!!!!!!!""####$$$$$$$$$$%%%%%%$$##""!!``!````҅`a!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!```!!!""##$$%%$$%%&&''(())**++,,--..//00112233445566?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ˊ`a```````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!```!!!!!!"!!!!!!!!"""""###$$%%&&''(())**++,,--..//001122334433221100////./////00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``!!!"!""""!!"!""###$$$$$$$$%%%%%%%%%%%$$##""!!`````!!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$##""!!```!!""##$$$$$$%%&&''(())**++,,--..//0011223344556?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ʌ`!!a!!`!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!!!!!!!""""""""""""""###$$$%%&&''(())**++,,--..//001122334444332211000//////000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!``````!!!""""""""""""##$$$$%%%%%%%%%%&&&&&&%%$$##""!!!``a`````a!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!``!!""##$$##$$%%&&''(())**++,,--..//001122334455????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`І`!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!""""""#""""""""#####$$$%%&&''(())**++,,--..//001122334455443322110000/00000112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!!!!!!"""#"####""#"##$$$%%%%%%%%&&&&&&&&&&&%%$$##""!!!!`````!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$##""!!`ą`!!!""######$$%%&&''(())**++,,--..//00112233445????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`LJ`!!"""!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""""""""##############$$$%%%&&''(())**++,,--..//001122334455554433221110000001112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!!!!"""############$$%%%%&&&&&&&&&&''''''&&%%$$##""!!``a``!!""##$$%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%$$##""!!``!`!!""##""##$$%%&&''(())**++,,--..//0011223344???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̆`!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###"""######$########$$$$$%%%&&''(())**++,,--..//001122334455665544332211110111112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""""""""###$#$$$$##$#$$%%%&&&&&&&&'''''''''''&&%%$$##""!!`````!!!`Ä`!!""##$$%%&&''(())**++,,--..//00100//..--,,++**))((''&&%%$$##""!!```!!""""""##$$%%&&''(())**++,,--..//001122334???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʅ`!!""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$#########$$$$$$$$$$$$$$%%%&&&''(())**++,,--..//001122334455666655443322211111122233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$###""""""###$$$$$$$$$$$$%%&&&&''''''''''((((((''&&%%$$##""!!!!!!!!!``!!""##$$%%&&''(())**++,,--..//00100//..--,,++**))((''&&%%$$##""!!```!!""!!""##$$%%&&''(())**++,,--..//00112233??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ċ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$###$$$$$$%$$$$$$$$%%%%%&&&''(())**++,,--..//001122334455667766554433222212222233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$########$$$%$%%%%$$%$%%&&&''''''''(((((((((((''&&%%$$##""!!!!!"!!`Ä`!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!`̀`!!!!!!!""##$$%%&&''(())**++,,--..//0011223?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ǖ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$$$$$$$%%%%%%%%%%%%%%&&&'''(())**++,,--..//001122334455667777665544333222222333445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$$######$$$%%%%%%%%%%%%&&''''(((((((((())))))((''&&%%$$##"""""""!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``!!!!``!!""##$$%%&&''(())**++,,--..//001122?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ŕ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$$%%%%%%&%%%%%%%%&&&&&'''(())**++,,--..//001122334455667788776655443333233333445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$$$$$$$%%%&%&&&&%%&%&&'''(((((((()))))))))))((''&&%%$$##"""""""!!``a!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!`ć`````!!""##$$%%&&''(())**++,,--..//00112??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ˇ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%%%%%%%&&&&&&&&&&&&&&'''((())**++,,--..//001122334455667788887766554443333334445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%%$$$$$$%%%&&&&&&&&&&&&''(((())))))))))******))((''&&%%$$#######""!!`Dž````a!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!`ԉ`!!""##$$%%&&''(())**++,,--..//00112??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!a`Έ`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%%&&&&&&'&&&&&&&&'''''((())**++,,--..//001122334455667788998877665544443444445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%%%%%%%&&&'&''''&&'&''((())))))))***********))((''&&%%$$#######""!!```Ň```!!!!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))((''&&%%$$##""!!`̉`!!""##$$%%&&''(())**++,,--..//00112??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!a`Ç``a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&&&&&&&''''''''''''''((()))**++,,--..//001122334455667788999988776655544444455566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&&%%%%%%&&&''''''''''''(())))**********++++++**))((''&&%%$$$$$$$##""!!!a````````!!!!!!""##$$%%&&''(())**++,,--..//001121100//..--,,++**))(((''&&%%$$##""!!`̎`a!""##$$%%&&''(())**++,,--..//001122??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ƈ```a!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''&&&''''''(''''''''((((()))**++,,--..//00112233445566778899::99887766555545555566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''&&&&&&&&'''('((((''('(()))********+++++++++++**))((''&&%%$$$$$$$##""!!!!!!!```a!!````!!!"""""##$$%%&&''(())**++,,--..//001121100//..--,,++**))(((''&&%%$$##""!!``̏`!!""##$$%%&&''(())**++,,--..//001122??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ɉ``````a!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''''''''(((((((((((((()))***++,,--..//00112233445566778899::::998877666555555666778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(('''&&&&&&'''(((((((((((())****++++++++++,,,,,,++**))((''&&%%%%%%%$$##""""!!!!!!a!!!!!``a!!!!!"""##$$%%&&''(())**++,,--..//001121100//..--,,++**))(('''&&%%$$##""!!`ɏ```!!""##$$%%&&''(())**++,,--..//001122??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ë`!!!!!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((('''(((((()(((((((()))))***++,,--..//00112233445566778899::;;::9988776666566666778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((''''''''((()())))(()())***++++++++,,,,,,,,,,,++**))((''&&%%%%%%%$$##"""""""!!`a!!!!!!!!!!`!!""##$$%%&&''(())**++,,--..//00111100//..--,,++**))(('''&&%%$$##""!!!a`‰`!`!!""##$$%%&&''(())**++,,--..//0011223?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ҍ`a!!!!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((((((((())))))))))))))***+++,,--..//00112233445566778899::;;;;::99887776666667778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))(((''''''((())))))))))))**++++,,,,,,,,,,------,,++**))((''&&&&&&&%%$$####"""!!``!!!!!!"!!``!!""##$$%%&&''(())**++,,--..//001100//..--,,++**))((''&&&%%$$##""!!!!!!``!!!""##$$%%&&''(())**++,,--..//00112233?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ń`!!""""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))((())))))*))))))))*****+++,,--..//00112233445566778899::;;<<;;::998877776777778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))(((((((()))*)****))*)**+++,,,,,,,,-----------,,++**))((''&&&&&&&%%$$#####""!!`a!`!!!!!!!``!!""##$$%%&&''(())**++,,--..//00100//..--,,++**))((''&&&%%$$##""!!``!!!!``ĉ`a!!""##$$%%&&''(())**++,,--..//001122334?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ʌ`!!"""#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))))))))**************+++,,,--..//00112233445566778899::;;<<<<;;::9988877777788899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**)))(((((()))************++,,,,----------......--,,++**))(('''''''&&%%$$$$###""!!!```!!!!!``a!""##$$%%&&''(())**++,,--..//0000//..--,,++**))((''&&%%%$$##""!!``!`!!`֋`!!""##$$%%&&''(())**++,,--..//0011223344????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`χ`!!""#####$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***)))******+********+++++,,,--..//00112233445566778899::;;<<==<<;;::99888878888899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***))))))))***+*++++**+*++,,,--------...........--,,++**))(('''''''&&%%$$$$$##""!!```````!!""##$$%%&&''(())**++,,--..//000//..--,,++**))((''&&%%%$$##""!!`ړ````Ҁ`!!""##$$%%&&''(())**++,,--..//00112233445????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````````!!""###$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++*********++++++++++++++,,,---..//00112233445566778899::;;<<====<<;;::999888888999::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++***))))))***++++++++++++,,----..........//////..--,,++**))(((((((''&&%%%%$$##""!!`͓Ԑ`!!""##$$%%&&''(())**++,,--..//00//..--,,++**))((''&&%%$$$$##""!!`֐```a!""##$$%%&&''(())**++,,--..//001122334455?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ā`!!!!!!!!""##$$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++***++++++,++++++++,,,,,---..//00112233445566778899::;;<<==>>==<<;;::9999899999::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++********+++,+,,,,++,+,,---........///////////..--,,++**))(((((((''&&%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$$$##""!!``̋`a``a!""##$$%%&&''(())**++,,--..//0011223344556????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ā````!!!!""##$$$%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++++++++,,,,,,,,,,,,,,---...//00112233445566778899::;;<<==>>>>==<<;;:::999999:::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,+++******+++,,,,,,,,,,,,--....//////////000000//..--,,++**)))))))((''&&&%%$$##""!!`Ő`!!""##$$%%&&''(())**++,,--..////..--,,++**))((''&&%%$$####""!!`ˎ`a!`a!""##$$%%&&''(())**++,,--..//00112233445566????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`ʁ`Ɏ`!!""##$$%%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,+++,,,,,,-,,,,,,,,-----...//00112233445566778899::;;<<==>>??>>==<<;;::::9:::::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,++++++++,,,-,----,,-,--...////////00000000000//..--,,++**)))))))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$####"""!!`Õ`a!!!!""##$$%%&&''(())**++,,--..//001122334455667????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```͐`!!""##$$%%&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,,,,,,,--------------...///00112233445566778899::;;<<==>>????>>==<<;;;::::::;;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,,++++++,,,------------..////000000000011111100//..--,,++******))((''&&%%$$##""!!``!!""##$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""""!!!`Ǎ`!!"!""##$$%%&&''(())**++,,--..//0011223344556677????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!""##$$%%&&&'''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,,,------.--------.....///00112233445566778899::;;<<==>>??????>>==<<;;;;:;;;;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,,,,,,,,---.-....--.-..///000000001111111111100//..--,,++******))((''&&%%$$##""!!`ċ`a!""##$$%%&&''(())**++,,--..//..--,,++**))((''&&%%$$##""""!!!``ې`!!""""##$$%%&&''(())**++,,--..//00112233445566778???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``ʇ```a!""##$$%%&&''''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---------..............///000112233445566778899::;;<<==>>????????>>==<<<;;;;;;<<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..---,,,,,,---............//000011111111112222221100//..--,,++++++**))((''&&%%$$##""!!`Ɗ`!!""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!!!``Յ``a!""#"##$$%%&&''(())**++,,--..//001122334455667788??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`````ʊ`!!!!""##$$%%&&'''((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...---....../......../////000112233445566778899::;;<<==>>??????????>>==<<<<;<<<<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...--------..././///.././/00011111111222222222221100//..--,,++++++**))((''&&%%$$##""!!```a!""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!!!`ۏ`a!""####$$%%&&''(())**++,,--..//0011223344556677889???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````Ȅ`!!!""##$$%%&&''(((())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//.........//////////////0001112233445566778899::;;<<==>>????????????>>===<<<<<<===>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//...------...////////////0011112222222222333333221100//..--,,,,,,++**))((''&&%%$$##""!!```a!!""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!```̓`!!""##$$%%&&''(())**++,,--..//00112233445566778899???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''((()))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///...//////0////////000001112233445566778899::;;<<==>>??????????????>>====<=====>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///........///0/0000//0/001112222222233333333333221100//..--,,,,,,++**))((''&&%%$$##""!!!!!!""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!`ΐ````a!""##$$%%&&''(())**++,,--..//00112233445566778899:??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&''(()))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100/////////0000000000000011122233445566778899::;;<<==>>????????????????>>>======>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100///......///000000000000112222333333333344444433221100//..------,,++**))((''&&%%$$##""!!!"""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!`Ք`!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``ǀ`!!""##$$%%&&''(())***++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000///0000001000000001111122233445566778899::;;<<==>>??????????????????>>>>=>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000////////000101111001011222333333334444444444433221100//..------,,++**))((''&&%%$$##""""""##$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!`ҏ`!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````a!""##$$%%&&''(()))))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100000000011111111111111222333445566778899::;;<<==>>?????????????????????>>>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211000//////00011111111111122333344444444445555554433221100//......--,,++**))((''&&%%$$##"""###$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!`э`a!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!""##$$%%&&''(()))))))**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332211100011111121111111122222333445566778899::;;<<==>>????????????????????????>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>?????>??????>>==<<;;::99887766554433221110000000011121222211212233344444444555555555554433221100//......--,,++**))((''&&%%$$######$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!`ː`!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`̋`!!!!""##$$%%&&''((((((((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443322111111111222222222222223334445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>?????????????????????>>>>???>>>??????>>==<<;;::99887766554433221110000001112222222222223344445555555555666666554433221100//////..--,,++**))((''&&%%$$###$$$%%&&''(())**++,,--../..--,,++**))((''&&%%$$##""!!`ċ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Ċ`a!!!""##$$%%&&''((((((((((())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433222111222222322222222333334445566778899::;;<<==>>????????????????????????????????????????????>>>>>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????>>>?????????>>????????>>==>>>>>=>>>?????>>==<<;;::99887766554433222111111112223233332232334445555555566666666666554433221100//////..--,,++**))((''&&%%$$$$$$%%&&''(())**++,,--..///..--,,++**))((''&&%%$$##""!!`Ã``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`LJ`!!!!""##$$%%&&''(''''''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544332222222223333333333333344455566778899::;;<<==>>?????????????????????????????????????????>>>>>>>>>>>>>>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????>>=>>????>>?>>>>??>>>?>>====>>>===>>>>>>>>>>==<<;;::998877665544332221111112223333333333334455556666666666777777665544332211000000//..--,,++**))((''&&%%$$$%%%&&''(())**++,,--..//0//..--,,++**))((''&&%%$$##""!!`````a!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&'''''''''''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655443332223333334333333334444455566778899::;;<<==>>?????????????????????????????????????>???>>>>>============>>>>??????????????????????????????????????????????????????????????????????????????>?>>???>>>??>?>>>>===>>>>>>>>>==>>>>>>>>==<<=====<===>>>>>>>>>==<<;;::998877665544333222222223334344443343445556666666677777777777665544332211000000//..--,,++**))((''&&%%%%%%&&''(())**++,,--..//000//..--,,++**))((''&&%%$$##""!!!`````a!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!````!!""##$$%%&&'&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433333333344444444444444555666778899::;;<<==>>?????????????????????????????????????>>>>>>===================>>>??????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>>>==<==>>>>==>====>>===>==<<<<===<<<==========>>==<<;;::998877665544333222222333444444444444556666777777777788888877665544332211111100//..--,,++**))((''&&%%%&&&''(())**++,,--..//0000//..--,,++**))((''&&%%$$##""!!``a!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``ɋ`!!""##$$%%&&&&&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665544433344444454444444455555666778899::;;<<==>>?????????????????????????????????>>>?>>=>>>=====<<<<<<<<<<<<====>>>>>?>>>>??????????????????????????????????????????????????????????????>>>>>>=>==>>>===>>=>====<<<=========<<========<<;;<<<<<;<<<=============<<;;::998877665544433333333444545555445455666777777778888888888877665544332211111100//..--,,++**))((''&&&&&&''(())**++,,--..//001100//..--,,++**))((''&&%%$$##""!!``a!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&&%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776655444444444555555555555556667778899::;;<<==>>??????????????????????????????>>>>>>>>>======<<<<<<<<<<<<<<<<<<<===>>>>>>>>>>>>>>>>>>>>>>>>?>?????>?????????????????????????????????>>>>>>>>>===================<<;<<====<<=<<<<==<<<=<<;;;;<<<;;;<<<<<<<<<<======<<;;::998877665544433333344455555555555566777788888888889999998877665544332222221100//..--,,++**))((''&&&'''(())**++,,--..//00111100//..--,,++**))((''&&%%$$##""!!!!"""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`Å`!!""##$$%%&&%%%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766555444555555655555555666667778899::;;<<==>>??????????????????????????>>>>>>>>>===>==<===<<<<<;;;;;;;;;;;;<<<<=====>====>>>>>>>>>>>>>>>>>>>>>>>>>???????????????????????????>>>>>>>>>>======<=<<===<<<==<=<<<<;;;<<<<<<<<<;;<<<<<<<<;;::;;;;;:;;;<<<<<<<<<<<====<<;;::998877665554444444455565666655656677788888888999999999998877665544332222221100//..--,,++**))((''''''(())**++,,--..//0011221100//..--,,++**))((''&&%%$$#cb"!!"""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```a!""##$$%%&&%%$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877665555555556666666666666677788899::;;<<==>>???????????????????????>>>>>>>>>=========<<<<<<;;;;;;;;;;;;;;;;;;;<<<========================>=>>>>>=>>???????????????????????>>>>>>>>=========<<<<<<<<<<<<<<<<<<<;;:;;<<<<;;<;;;;<<;;;<;;::::;;;:::;;;;;;;;;;<<<<<<<<<;;;::998877665554444445556666666666667788889999999999::::::998877665544333333221100//..--,,++**))(('''((())**++,,--..//001122221100//..--,,++**))((''&&%%$$##""""#####$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``a!!""##$$%%&&%%$$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::9988776665556666667666666667777788899::;;<<==>>>>>>?????????????????>>>>>>>=========<<<=<<;<<<;;;;;::::::::::::;;;;<<<<<=<<<<=========================>>?????????????????????>>>>==========<<<<<<;<;;<<<;;;<<;<;;;;:::;;;;;;;;;::;;;;;;;;::99:::::9:::;;;;;;;;;;;<<<<;;;:::::9988776665555555566676777766767788899999999:::::::::::998877665544333333221100//..--,,++**))(((((())**++,,--..//00112233221100//..--,,++**))((''&&%%$$##""#####$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!""##$$%%&&%%$$########$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766666666677777777777777888999::;;<<==>>>>>>>>??????????????>>>>>=========<<<<<<<<<;;;;;;:::::::::::::::::::;;;<<<<<<<<<<<<<<<<<<<<<<<<=<=====<==>>???????????????????>>========<<<<<<<<<;;;;;;;;;;;;;;;;;;;::9::;;;;::;::::;;:::;::9999:::999::::::::::;;;;;;;;;::::::9998877666555555666777777777777889999::::::::::::::::::998877665544444433221100//..--,,++**))((()))**++,,--..//0011223333221100//..--,,++**))((''&&%%$$####$$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!"""##$$%%&&%%$$##########$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877766677777787777777788888999::;;<<==>>>>====>>????????????>>>=======<<<<<<<<<;;;<;;:;;;:::::999999999999::::;;;;;<;;;;<<<<<<<<<<<<<<<<<<<<<<<<<==>>?????????????>>>>>>====<<<<<<<<<<;;;;;;:;::;;;:::;;:;::::999:::::::::99::::::::9988999998999:::::::::::;;;;:::9999999998877766666666777878888778788999::::::::;;;::::::::::998877665544444433221100//..--,,++**))))))**++,,--..//001122334433221100//..--,,++**))((''&&%%$$##$$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&%%$$##""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::998877777777788888888888888999:::;;<<==>>>>======>>>>>>?>>>??>>=====<<<<<<<<<;;;;;;;;;::::::9999999999999999999:::;;;;;;;;;;;;;;;;;;;;;;;;<;<<<<<;<<==>>??????>????>>>>>>==<<<<<<<<;;;;;;;;;:::::::::::::::::::99899::::99:9999::999:9988889998889999999999:::::::::999999889998877766666677788888888888899::9999::::::::9999999999998877665555554433221100//..--,,++**)))***++,,--..//00112233444433221100//..--,,++**))((''&&%%$$$$%%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``a!""##$$%%&&%%$$##""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????>??????????????????????????>????????>>==<<;;::9988877788888898888888899999:::;;<<==>>>>==<<<<==>>>>>>>>>>>>===<<<<<<<;;;;;;;;;:::;::9:::999998888888888889999:::::;::::;;;;;;;;;;;;;;;;;;;;;;;;;<<==>>?>>>>>>>>>>======<<<<;;;;;;;;;;::::::9:99:::999::9:99998889999999998899999999887788888788899999999999::::999888888888998887777777788898999988989999999999::::::999999999998998877665555554433221100//..--,,++******++,,--..//0011223344554433221100//..--,,++**))((''&&%%$$%%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```a!""##$$%%&&%%$$##""!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????>>???????>>?????????>>>???>>??>???>????>>??>>>?>>>???>>>>>>>==<<;;::9988888888899999999999999:::;;;<<==>>>>==<<<<<<======>===>>==<<<<<;;;;;;;;;:::::::::9999998888888888888888888999::::::::::::::::::::::::;:;;;;;:;;<<==>>>>>>=>>>>======<<;;;;;;;;:::::::::99999999999999999998878899998898888998889887777888777888888888899999999988888877888888887777778889999999999999999888899999999888888888888888877666666554433221100//..--,,++***+++,,--..//001122334455554433221100//..--,,++**))((''&&%%%%&&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!""##$$%%&&%%$$##""!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????>>>>?????>>>>???????>>=>>?>>>>>>>>>>>>>>>>>>>>>>>=>>?>>>>>>>>>==<<;;::999888999999:99999999:::::;;;<<==>>>>==<<;;;;<<============<<<;;;;;;;:::::::::999:99899988888777777777777888899999:9999:::::::::::::::::::::::::;;<<==>==========<<<<<<;;;;::::::::::9999998988999888998988887778888888887788888888776677777677788888888888999988877777777788888888888889999998999988888888888899999988888888888788888877666666554433221100//..--,,++++++,,--..//00112233445566554433221100//..--,,++**))((''&&%%&&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%&&%%$$##""!a````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????>>?????>>>>==>>???>>==>>?????>>===>>>==>>=>>>=>>>>==>>===>===>>>=========<<<<;;::999999999::::::::::::::;;;<<<========<<;;;;;;<<<<<<=<<<==<<;;;;;:::::::::9999999998888887777777777777777777888999999999999999999999999:9:::::9::;;<<======<====<<<<<<;;::::::::9999999998888888888888888888776778888778777788777877666677766677777777778888888887777776677777888888888999888888888888888877778888888877777777777777777777777766554433221100//..--,,+++,,,--..//0011223344556666554433221100//..--,,++**))((''&&&&'''''((())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$%%%%%$$##""!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????>>>?>>>>>??>>>>====>>>>>====>>>>?>>==<==>=======================<==>=========<<<<<<;;:::999::::::;::::::::;;;;;<<<========<<;;::::;;<<<<<<<<<<<<;;;:::::::999999999888988788877777666666666666777788888988889999999999999999999999999::;;<<=<<<<<<<<<<;;;;;;::::9999999999888888787788877788787777666777777777667777777766556666656667777777777788887776666666667777788888888888888788887777777777778888887777777777767777777777777766554433221100//..--,,,,,,--..//001122334455667766554433221100//..--,,++**))((''&&'''''((())**++,,--..//00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`€`!!""##$$$%%%$$##""!a`ƀ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>>>>>==>>>>>====<<==>>>==<<==>>>>>==<<<===<<==<===<====<<==<<<=<<<===<<<<<<<<<;;;<<<;;:::::::::;;;;;;;;;;;;;;<<<====<<<<<<<;;::::::;;;;;;<;;;<<;;:::::99999999988888888877777766666666666666666667778888888888888888888888889899999899::;;<<<<<<;<<<<;;;;;;::99999999888888888777777777777777777766566777766766667766676655556665556666666666777777777666666556666677787887788877777777777777776666777777776666666666666666666666667766554433221100//..--,,,---..//00112233445566777766554433221100//..--,,++**))((''''((((()))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""##$$$$$$$##""!!````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>===>=====>>====<<<<=====<<<<====>==<<;<<=<<<<<<<<<<<<<<<<<<<<<<<;<<=<<<<<<<<<;;;;;<<<;;;:::;;;;;;<;;;;;;;;<<<<<=<<<<<<<<<<;;::9999::;;;;;;;;;;;;:::999999988888888877787767776666655555555555566667777787777888888888888888888888888899::;;<;;;;;;;;;;::::::9999888888888877777767667776667767666655566666666655666666665544555554555666666666667777666555555555666667777777777777767777666666666666777777666666666665666666666666666666554433221100//..------..//0011223344556677887766554433221100//..--,,++**))((''((((()))**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@@`!!""####$$$$$##""!!```a````!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????>>======<<=====<<<<;;<<===<<;;<<=====<<;;;<<<;;<<;<<<;<<<<;;<<;;;<;;;<<<;;;;;;;;;:::;;<<;;;;;;;;;;;<<<<;;<<<<;;;<<<<<<<;;;;;;;::999999::::::;:::;;::999998888888887777777776666665555555555555555555666777777777777777777777777878888878899::;;;;;;:;;;;::::::998888888877777777766666666666666666665545566665565555665556554444555444555555555566666666655555544555556667677667776666666666666666555566666666555555555555555555555555666666554433221100//..---...//001122334455667788887766554433221100//..--,,++**))(((()))))***++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>===================<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!""######$$$$##""!!!!!aa!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????>>??????>>==<<<=<<<<<==<<<<;;;;<<<<<;;;;<<<<=<<;;:;;<;;;;;;;;;;;;;;;;;;;;;;;:;;<;;;;;;;;;:::::;;;;;;;;;<<;;;;<<;;;;<<;;;;;<<;;;;;;;;;;::99888899::::::::::::99988888887777777776667665666555554444444444445555666667666677777777777777777777777778899::;::::::::::999999888877777777776666665655666555665655554445555555554455555555443344444344455555555555666655544444444455555666666666666665666655555555555566666655555555555455555555555555555555554433221100//......//00112233445566778899887766554433221100//..--,,++**))(()))))***++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>=====================<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!`@`!!""""""###$$$$##""!!!"!!!!"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????>>>>???>>>==<<<<<<;;<<<<<;;;;::;;<<<;;::;;<<<<<;;:::;;;::;;:;;;:;;;;::;;:::;:::;;;:::::::::999::;;:::;;;;;;::;;;;::;;;;:::;;;;;;;:::::::99888888999999:999::9988888777777777666666666555555444444444444444444455566666666666666666666666676777776778899::::::9::::99999988777777776666666665555555555555555555443445555445444455444544333344433344444444445555555554444443344444555656655666555555555555555544445555555544444444444444444444444455555555554433221100//...///0011223344556677778889887766554433221100//..--,,++**))))*****+++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>??????????????????????????????????????????????????????????????>>==<<<<<<<<<<<<<<<<<====<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``@ǀ`!!!""""""##$$$$##"""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????>>==>>>>>>==<<;;;<;;;;;<<;;;;::::;;;;;::::;;;;<;;::9::;:::::::::::::::::::::::9::;:::::::::99999:::::::;;;;::::;;::::;;:::::;;::::::::::99887777889999999999998887777777666666666555655455544444333333333333444455555655556666666666666666666666666778899:999999999988888877776666666666555555454455544455454444333444444444334444444433223333323334444444444455554443333333334444455555555555555455554444444444445555554444444444434444444444444444444445454433221100//////001122334455667777778888887766554433221100//..--,,++**))*****+++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>??????>>???????????????????????????????????????????????????>>==<<<<<<<<<<<<<<<<<<<<===<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``!!!!!!"""##$$$$##"""#""""###$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????>????????>>====>>>===<<;;;;;;::;;;;;::::99::;;;::99::;;;;;::999:::99::9:::9::::99::999:999:::99999999988899::999::::::99::::99::::999:::::::9999999887777778888889888998877777666666666555555555444444333333333333333333344455555555555555555555555565666665667788999999899998888887766666666555555555444444444444444444433233444433433334433343322223332223333333333444444444333333223333344454554455544444444444444443333444444443333333333333333333333334444444444444433221100///000112233445566777666777888887766554433221100//..--,,++****+++++,,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>====>>>>>??>>>>>>>>>?>>??????>>????>>???????????????????????????>>==<<;;;;;;;;;;;;;;;;;<<<<<=<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!```!!!!!!""##$$$$###########$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????>>>??????>>==<<======<<;;:::;:::::;;::::9999:::::9999::::;::99899:99999999999999999999999899:999999999888889999999::::9999::9999::99999::999999999988776666778888888888887776666666555555555444544344433333222222222222333344444544445555555555555555555555555667788988888888887777776666555555555544444434334443334434333322233333333322333333332211222221222333333333334444333222222222333334444444444444434444333333333333444444333333333332333333333333333333333434444433221100000011223344556666766666777777777766554433221100//..--,,++**+++++,,,--..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>????????>>=======>>>>>>==>>>>>>>>>>>>??>>>>??>>>>>????>>>>????????????????>>==<<;;;;;;;;;;;;;;;;;;;;<<<<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!``````!!!""##$$$$###$####$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????>>=>>????>>==<<<<===<<<;;::::::99:::::99998899:::998899:::::9988899988998999899998899888988899988888888877788998889999998899998899998889999999888888877666666777777877788776666655555555544444444433333322222222222222222223334444444444444444444444445455555455667788888878888777777665555555544444444433333333333333333332212233332232222332223221111222111222222222233333333322222211222223334344334443333333333333333222233333333222222222222222222222222333333333333333333221100011122334455666666655566677777777766554433221100//..--,,++++,,,,,---..//00112233445566778899::;;<<==>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>?????>>>>>??????>>==<<<<=====>>=========>==>>>>>>==>>>>==>>>??>>>>>>??????????????>>==<<;;:::::::::::::::::;;;;;<<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!aa````aa""##$$$$$$$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????>>===>>??>>==<<;;<<<<<<;;::999:99999::999988889999988889999:998878898888888888888888888888878898888888887777788888889999888899888899888889988888888887766555566777777777777666555555544444444433343323332222211111111111122223333343333444444444444444444444444455667787777777777666666555544444444443333332322333222332322221112222222221122222222110011111011122222222222333322211111111122222333333333333332333322222222222233333322222222222122222222222222222222232333333333221111112233445555555565555566666666666666554433221100//..--,,++,,,,,---..//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>==>>>>>>>>==<<<<<<<======<<============>>====>>=====>>>>====>>????????????>>==<<;;::::::::::::::::::::;;;;;<<<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!!a``````aa""##$$$$$%$$$$%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????>>==<==>>>>==<<;;;;<<<;;;::99999988999998888778899988778899999887778887788788878888778877787778887777777776667788777888888778888778888777888888877777776655555566666676667766555554444444443333333332222221111111111111111111222333333333333333333333333434444434455667777776777766666655444444443333333332222222222222222222110112222112111122111211000011100011111111112222222221111110011111222323322333222222222222222211112222222211111111111111111111111122222222222222222233221112223344444455555554445556666666666666554433221100//..--,,,,-----...//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>===>>>>>=====>>>>>>==<<;;;;<<<<<==<<<<<<<<<=<<======<<====<<===>>======>>>>>>>>>>>>>>==<<;;::99999999999999999:::::;;;;;;;::::99887766554433221100//..--,,++**))((''&&%%$$##"""!!!!!`````a!`!!""##$$%%%%%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????>>==<<<==>>==<<;;::;;;;;;::9988898888899888877778888877778888988776778777777777777777777777776778777777777666667777777888877778877778877777887777777777665544445566666666666655544444443333333332223221222111110000000000001111222223222233333333333333333333333334455667666666666655555544443333333333222222121122211122121111000111111111001111111100//00000/0001111111111122221110000000001111122222222222222122221111111111112222221111111111101111111111111111111112122222222233222222334444444444445444445555555555556666554433221100//..--,,-----...//00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????>>>???>>>>>>>?>>>>>>>>>>>>==============<<========<<;;;;;;;<<<<<<;;<<<<<<<<<<<<==<<<<==<<<<<====<<<<==>>>>>>>>>>>>==<<;;::99999999999999999999:::::;;;;::::::99887766554433221100//..--,,++**))((''&&%%$$##""""!!!!!```````a!!!!!!""##$$%%%%%&%%%%&&&''(())**++,,--..//00112233445566778899::;;<<==>>???????????????????????????????????????????????>>==<<;<<====<<;;::::;;;:::998888887788888777766778887766778888877666777667767776777766776667666777666666666555667766677777766777766777766677777776666666554444445555556555665544444333333333222222222111111000000000000000000011122222222222222222222222232333332334455666666566665555554433333333222222222111111111111111111100/001111001000011000100////000///0000000000111111111000000//0000011121221122211111111111111110000111111110000000000000000000000001111111111111111112222222333333333334444444333444555555555555666554433221100//..----.....///00112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>>=============<<<=====<<<<<======<<;;::::;;;;;<<;;;;;;;;;<;;<<<<<<;;<<<<;;<<<==<<<<<<==============<<;;::998888888888888888899999:::::::999:::99887766554433221100//..--,,++**))((''&&%%$$###"""""!!!!!!!```a!!!""!""##$$%%&&&&&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>????????????????????????????????????????>>>>>>>>>==<<;;;<<==<<;;::99::::::99887778777778877776666777776666777787766566766666666666666666666666566766666666655555666666677776666776666776666677666666666655443333445555555555554443333333222222222111211011100000////////////0000111112111122222222222222222222222223344556555555555544444433332222222222111111010011100011010000///000000000//00000000//../////.///000000000001111000/////////00000111111111111110111100000000000011111100000000000/000000000000000000000101111111112222223333333333333333433333444444444444555666554433221100//..--.....///00112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????>>>>>>>>>===>>>=======>============<<<<<<<<<<<<<<;;<<<<<<<<;;:::::::;;;;;;::;;;;;;;;;;;;<<;;;;<<;;;;;<<<<;;;;<<============<<;;::998888888888888888888899999::::9999999999887766554433221100//..--,,++**))((''&&%%$$####"""""!!!!!!!`a!"""""""##$$%%&&&&&'&&&&'''(())**++,,--..//00112233445566778899::;;<<==>>?????????????????????????????????>>>>>>>>>>>>>>>>==<<;;:;;<<<<;;::9999:::999887777776677777666655667776655667777766555666556656665666655665556555666555555555444556655566666655666655666655566666665555555443333334444445444554433333222222222111111111000000///////////////////000111111111111111111111111212222212233445555554555544444433222222221111111110000000000000000000//.//0000//0////00///0//....///...//////////000000000//////../////0001011001110000000000000000////00000000////////////////////////000000000000000000111112222222222222333333322233344444444444455566554433221100//..../////000112233445566778899::;;<<==>>??????????????????????????????????????????????????????????????????????????????>>>>>>>>>==================<<<<<<<<<<<<<;;;<<<<<;;;;;<<<<<<;;::9999:::::;;:::::::::;::;;;;;;::;;;;::;;;<<;;;;;;<<<<<<<<<<<<<<;;::9988777777777777777778888899999998889999889887766554433221100//..--,,++**))((''&&%%$$$#####"""""""!!!!""""##"##$$%%&&'''''''''''(())****++,,--..//00112233445566778899::;;<<==>>????????????????????????????>>>>>>>>>>>>=========<<;;:::;;<<;;::998899999988776667666667766665555666665555666676655455655555555555555555555555455655555555544444555555566665555665555665555566555555555544332222334444444444443332222222111111111000100/000/////............////000001000011111111111111111111111112233445444444444433333322221111111111000000/0//000///00/0////.../////////..////////..--.....-...///////////0000///........./////00000000000000/0000////////////000000///////////./////////////////////0/000000000111111222222222222222232222233333333333344455555554433221100//../////000112233445566778899::;;<<==>>?????????????????????????????????????????????????????????????????????????????>>>=========<<<===<<<<<<<=<<<<<<<<<<<<;;;;;;;;;;;;;;::;;;;;;;;::9999999::::::99::::::::::::;;::::;;:::::;;;;::::;;<<<<<<<<<<<<;;::998877777777777777777777888889999888888888889887766554433221100//..--,,++**))((''&&%%$$$$#####"""""""!""#######$$%%&&'''''(''''((())))))**++,,--..//00112233445566778899::;;<<==>>????????????????????????>>>>>>>================<<;;::9::;;;;::998888999888776666665566666555544556665544556666655444555445545554555544554445444555444444444333445544455555544555544555544455555554444444332222223333334333443322222111111111000000000//////...................///00000000000000000000000010111110112233444444344443333332211111111000000000///////////////////..-..////../....//.../..----...---........../////////......--.....///0/00//000////////////////....////////........................//////////////////00000111111111111122222221112223333333333334445544454433221100////000001112233445566778899::;;<<==>>?????????????????????????????????????????????????????????>>>?>>>>>>>>>>??>??>>>>=========<<<<<<<<<<<<<<<<<<;;;;;;;;;;;;;:::;;;;;:::::;;;;;;::99888899999::999999999:99::::::99::::99:::;;::::::;;;;;;;;;;;;;;::99887766666666666666666777778888888777888877888887766554433221100//..--,,++**))((''&&%%%$$$$$#######""""####$$#$$%%&&''((((((('''(()))))))**++,,--..//00112233445566778899::;;<<==>>????????????????>>>>>>>>>>============<<<<<<<<<;;::999::;;::99887788888877665556555556655554444555554444555565544344544444444444444444444444344544444444433333444444455554444554444554444455444444444433221111223333333333332221111111000000000///0//.///.....------------..../////0////00000000000000000000000001122334333333333322222211110000000000//////./..///...//./....---.........--........--,,-----,---...........////...---------.....//////////////.////............//////...........-....................././////////00000011111111111111112111112222222222223334444444444433221100//000001112233445566778899::;;<<==>>?????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>>>>>>===<<<<<<<<<;;;<<<;;;;;;;<;;;;;;;;;;;;::::::::::::::99::::::::99888888899999988999999999999::9999::99999::::9999::;;;;;;;;;;;;::9988776666666666666666666677777888877777777777888887766554433221100//..--,,++**))((''&&%%%%$$$$$#######"##$$$$$$$%%&&''((('''''''''(()(((())**++,,--..//00112233445566778899::;;<<==>>?????????????>>>>>>>>>=======<<<<<<<<<<<<<<<<;;::99899::::99887777888777665555554455555444433445554433445555544333444334434443444433443334333444333333333222334433344444433444433444433344444443333333221111112222223222332211111000000000/////////......-------------------...////////////////////////0/00000/001122333333233332222221100000000/////////...................--,--....--.----..---.--,,,,---,,,----------.........------,,-----..././/..///................----........------------------------................../////00000000000001111111000111222222222222333443334444433221100001111122233445566778899::;;<<==>>?????????????????????????????????????????????????????????>>===>==========>>=>>====<<<<<<<<<;;;;;;;;;;;;;;;;;;:::::::::::::999:::::99999::::::99887777888889988888888898899999988999988999::999999::::::::::::::998877665555555555555555566666777777766677776677777777766554433221100//..--,,++**))((''&&&%%%%%$$$$$$$####$$$$%%$%%&&''(('''''''&&&''((((((())**++,,--..//00112233445566778899::;;<<==>>??????????>>>>==========<<<<<<<<<<<<;;;;;;;;;::9988899::9988776677777766554445444445544443333444443333444454433233433333333333333333333333233433333333322222333333344443333443333443333344333333333322110000112222222222221110000000/////////.../..-...-----,,,,,,,,,,,,----...../..../////////////////////////001122322222222221111110000//////////......-.--...---..-.----,,,---------,,--------,,++,,,,,+,,,-----------....---,,,,,,,,,-----..............-....------------......-----------,---------------------.-.........//////00000000000000001000001111111111112223333333333333332211001111122233445566778899::;;<<==>>?????????????????????????????????????????????????????????>>======================<<<;;;;;;;;;:::;;;:::::::;::::::::::::9999999999999988999999998877777778888887788888888888899888899888889999888899::::::::::::99887766555555555555555555556666677776666666666677777777766554433221100//..--,,++**))((''&&&&%%%%%$$$$$$$#$$%%%%%%%&&''(('''&&&&&&&&&''(''''(())**++,,--..//00112233445566778899::;;<<==>>???????>>>>=========<<<<<<<;;;;;;;;;;;;;;;;::9988788999988776666777666554444443344444333322334443322334444433222333223323332333322332223222333222222222111223322233333322333322333322233333332222222110000001111112111221100000/////////.........------,,,,,,,,,,,,,,,,,,,---.......................././////.//00112222221222211111100////////.........-------------------,,+,,----,,-,,,,--,,,-,,++++,,,+++,,,,,,,,,,---------,,,,,,++,,,,,---.-..--...----------------,,,,--------,,,,,,,,,,,,,,,,,,,,,,,,------------------...../////////////0000000///0001111111111112223322233333333322111122222333445566778899::;;<<==>>?????????????????????????????????????????????????????????>>==<<<=<<<<<<<<<<==<==<<<<;;;;;;;;;::::::::::::::::::9999999999999888999998888899999988776666777778877777777787788888877888877888998888889999999999999988776655444444444444444445555566666665556666556666666667766554433221100//..--,,++**))(('''&&&&&%%%%%%%$$$$%%%%&&%&&''((''&&&&&&&%%%&&'''''''(())**++,,--..//00112233445566778899::;;<<==>>?????>>>====<<<<<<<<<<;;;;;;;;;;;;:::::::::99887778899887766556666665544333433333443333222233333222233334332212232222222222222222222222212232222222221111122222223333222233222233222223322222222221100////00111111111111000///////.........---.--,---,,,,,++++++++++++,,,,-----.----.........................//001121111111111000000////..........------,-,,---,,,--,-,,,,+++,,,,,,,,,++,,,,,,,,++**+++++*+++,,,,,,,,,,,----,,,+++++++++,,,,,--------------,----,,,,,,,,,,,,------,,,,,,,,,,,+,,,,,,,,,,,,,,,,,,,,,-,---------......////////////////0/////00000000000011122222222222222222221122222333445566778899::;;<<==>>??????????????????????????????????????????????>>>>>>>????>>==<<<<<<<<<<<<<<<<<<<<<<;;;:::::::::999:::9999999:99999999999988888888888888778888888877666666677777766777777777777887777887777788887777889999999999998877665544444444444444444444555556666555555555556666666666666554433221100//..--,,++**))((''''&&&&&%%%%%%%$%%&&&&&&&''((''&&&%%%%%%%%%&&'&&&&''(())**++,,--..//00112233445566778899::;;<<==>>???>>====<<<<<<<<<;;;;;;;::::::::::::::::99887767788887766555566655544333333223333322221122333221122333332211122211221222122221122111211122211111111100011221112222221122221122221112222222111111100//////00000010001100/////.........---------,,,,,,+++++++++++++++++++,,,------------------------.-.....-..//0011111101111000000//........---------,,,,,,,,,,,,,,,,,,,++*++,,,,++,++++,,+++,++****+++***++++++++++,,,,,,,,,++++++**+++++,,,-,--,,---,,,,,,,,,,,,,,,,++++,,,,,,,,++++++++++++++++++++++++,,,,,,,,,,,,,,,,,,-----.............///////...///00000000000011122111222222222222222333333445566778899::;;<<==>>??????????????????????????????????????????????>>>>>>>>>>>>>==<<;;;<;;;;;;;;;;<<;<<;;;;:::::::::999999999999999999888888888888877788888777778888887766555566666776666666667667777776677776677788777777888888888888887766554433333333333333333444445555555444555544555555555666666554433221100//..--,,++**))((('''''&&&&&&&%%%%&&&&''&''((''&&%%%%%%%$$$%%&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?>>===<<<<;;;;;;;;;;::::::::::::999999999887766677887766554455555544332223222223322221111222221111222232211011211111111111111111111111011211111111100000111111122221111221111221111122111111111100//....//000000000000///.......---------,,,-,,+,,,+++++************++++,,,,,-,,,,-------------------------..//0010000000000//////....----------,,,,,,+,++,,,+++,,+,++++***+++++++++**++++++++**))*****)***+++++++++++,,,,+++*********+++++,,,,,,,,,,,,,,+,,,,++++++++++++,,,,,,+++++++++++*+++++++++++++++++++++,+,,,,,,,,,------................/.....////////////00011111111111111111122222223333445566778899::;;<<==>>????????????????????????????????????????????>>=======>>>>==<<;;;;;;;;;;;;;;;;;;;;;;:::999999999888999888888898888888888887777777777777766777777776655555556666665566666666666677666677666667777666677888888888888776655443333333333333333333344444555544444444444555555555555566554433221100//..--,,++**))(((('''''&&&&&&&%&&'''''''''''&&%%%$$$$$$$$$%%&%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>>==<<<<;;;;;;;;;:::::::9999999999999999887766566777766554444555444332222221122222111100112221100112222211000111001101110111100110001000111000000000///001100011111100111100111100011111110000000//......//////0///00//.....---------,,,,,,,,,++++++*******************+++,,,,,,,,,,,,,,,,,,,,,,,,-,-----,--..//000000/0000//////..--------,,,,,,,,,+++++++++++++++++++**)**++++**+****++***+**))))***)))**********+++++++++******))*****+++,+,,++,,,++++++++++++++++****++++++++************************++++++++++++++++++,,,,,-------------.......---...////////////0001100011111111111111222222233445566778899::;;<<==>>??????????????????????????????????????????>>=============<<;;:::;::::::::::;;:;;::::99999999988888888888888888877777777777776667777766666777777665544445555566555555555655666666556666556667766666677777777777777665544332222222222222222233333444444433344443344444444455555555554433221100//..--,,++**)))((((('''''''&&&&''''(('''''&&%%$$$$$$$###$$%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>==<<<;;;;::::::::::999999999999888888888776655566776655443344444433221112111112211110000111110000111121100/00100000000000000000000000/001000000000/////0000000111100001100001100000110000000000//..----..////////////...-------,,,,,,,,,+++,++*+++*****))))))))))))****+++++,++++,,,,,,,,,,,,,,,,,,,,,,,,,--..//0//////////......----,,,,,,,,,,++++++*+**+++***++*+****)))*********))********))(()))))()))***********++++***)))))))))*****++++++++++++++*++++************++++++***********)*********************+*+++++++++,,,,,,----------------.-----............///0000000000000000001111111222233445566778899::;;<<==>>????????????????????????????????????????>>==<<<<<<<====<<;;::::::::::::::::::::::99988888888877788877777778777777777777666666666666665566666666554444444555555445555555555556655556655555666655556677777777777766554433222222222222222222223333344443333333333344444444444445555544433221100//..--,,++**))))((((('''''''&''(((((''&&&&%%$$$#########$$%$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<===<<;;;;:::::::::999999988888888888888887766554556666554433334443332211111100111110000//0011100//001111100///000//00/000/0000//00///0///000/////////...//00///000000//0000//0000///0000000///////..------....../...//..-----,,,,,,,,,+++++++++******)))))))))))))))))))***++++++++++++++++++++++++,+,,,,,+,,--..//////.////......--,,,,,,,,+++++++++*******************))())****))*))))**)))*))(((()))((())))))))))*********))))))(()))))***+*++**+++****************))))********))))))))))))))))))))))))******************+++++,,,,,,,,,,,,,-------,,,---............///00///0000000000000011111112233445566778899::;;<<==>>??????????????????????????????????????>>==<<<<<<<<<<<<<;;::999:9999999999::9::99998888888887777777777777777776666666666666555666665555566666655443333444445544444444454455555544555544555665555556666666666666655443322111111111111111112222233333332223333223333333334444444444433333221100//..--,,++***)))))(((((((''''((('(''&&&&%%$$#######"""##$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<=<<;;;::::999999999988888888888877777777766554445566554433223333332211000100000110000////00000////0000100//.//0///////////////////////.//0/////////.....///////0000////00////00/////00//////////..--,,,,--............---,,,,,,,+++++++++***+**)***)))))(((((((((((())))*****+****+++++++++++++++++++++++++,,--../..........------,,,,++++++++++******)*))***)))**)*))))((()))))))))(())))))))((''((((('((()))))))))))****)))((((((((()))))**************)****))))))))))))******)))))))))))()))))))))))))))))))))*)*********++++++,,,,,,,,,,,,,,,,-,,,,,------------...//////////////////000000011112233445566778899::;;<<==>>????????????????????????????????????>>==<<;;;;;;;<<<<;;::99999999999999999999998887777777776667776666666766666666666655555555555555445555555544333333344444433444444444444554444554444455554444556666666666665544332211111111111111111111222223333222222222223333333333333444443332233221100//..--,,++****)))))((((((('(((''''&&%%%%$$###"""""""""##$####$$%%&&''(())**++,,--..//00112233445566778899::;;<<<;;::::9999999998888888777777777777777766554434455554433222233322211000000//00000////..//000//..//00000//...///..//.///.////..//.../...///.........---..//...//////..////..////...///////.......--,,,,,,------.---..--,,,,,+++++++++*********))))))((((((((((((((((((()))************************+*+++++*++,,--......-....------,,++++++++*********)))))))))))))))))))(('(())))(()(((())((()((''''((('''(((((((((()))))))))((((((''((((()))*)**))***))))))))))))))))(((())))))))(((((((((((((((((((((((())))))))))))))))))*****+++++++++++++,,,,,,,+++,,,------------...//...//////////////0000000112233445566778899::;;<<==>>??????????????????????????????????>>==<<;;;;;;;;;;;;;::99888988888888889989988887777777776666666666666666665555555555555444555554444455555544332222333334433333333343344444433444433444554444445555555555555544332211000000000000000001111122222221112222112222222223333333333322222221100//..----,,+++*****)))))))(((('''&'&&%%%%$$##"""""""!!!""#######$$%%&&''(())**++,,--..//00112233445566778899::;;<;;:::9999888888888877777777777766666666655443334455443322112222221100///0/////00////..../////....////0//..-../.......................-../.........-----.......////....//....//.....//..........--,,++++,,------------,,,+++++++*********)))*))()))(((((''''''''''''(((()))))*))))*************************++,,--.----------,,,,,,++++**********))))))()(()))((())()(((('''(((((((((''((((((((''&&'''''&'''((((((((((())))((('''''''''((((())))))))))))))())))(((((((((((())))))((((((((((('((((((((((((((((((((()()))))))))******++++++++++++++++,+++++,,,,,,,,,,,,---..................///////0000112233445566778899::;;<<==>>????????????????????????????????>>==<<;;:::::::;;;;::99888888888888888888888877766666666655566655555556555555555555444444444444443344444444332222222333333223333333333334433334433333444433334455555555555544332211000000000000000000001111122221111111111122222222222223333322211221100//..---,--,,++++*****))))(((('''&&&&%%$$$$##"""!!!!!!!!!""#""""##$$%%&&''(())**++,,--..//00112233445566778899::;;;::99998888888887777777666666666666666655443323344443322111122211100//////../////....--..///..--../////..---...--..-...-....--..---.---...---------,,,--..---......--....--....---.......-------,,++++++,,,,,,-,,,--,,+++++*********)))))))))(((((('''''''''''''''''''((())))))))))))))))))))))))*)*****)**++,,------,----,,,,,,++********)))))))))(((((((((((((((((((''&''((((''(''''(('''(''&&&&'''&&&''''''''''(((((((((''''''&&'''''((()())(()))((((((((((((((((''''((((((((''''''''''''''''''''''''(((((((((((((((((()))))*************+++++++***+++,,,,,,,,,,,,---..---..............///////00112233445566778899::;;<<==>>??????????????????????????????>>==<<;;:::::::::::::9988777877777777778878877776666666665555555555555555554444444444444333444443333344444433221111222223322222222232233333322333322333443333334444444444444433221100/////////////////00000111111100011110011111111122222222222111111100//..--,,,,--,,++++++***))((''''&&&%&%%$$$$##""!!!!!!!```aa"""""""##$$%%&&''(())**++,,--..//00112233445566778899::;::99988887777777777666666666666555555555443322233443322110011111100//.../.....//....----.....----..../..--,--.-----------------------,--.---------,,,,,-------....----..----..-----..----------,,++****++,,,,,,,,,,,,+++*******)))))))))((()(('((('''''&&&&&&&&&&&&''''((((()(((()))))))))))))))))))))))))**++,,-,,,,,,,,,,++++++****))))))))))(((((('(''((('''(('(''''&&&'''''''''&&''''''''&&%%&&&&&%&&&'''''''''''(((('''&&&&&&&&&'''''(((((((((((((('((((''''''''''''(((((('''''''''''&'''''''''''''''''''''('((((((((())))))****************+*****++++++++++++,,,------------------.......////00112233445566778899::;;<<==>>????????????????????????????>>==<<;;::9999999::::9988777777777777777777777766655555555544455544444445444444444444333333333333332233333333221111111222222112222222222223322223322222333322223344444444444433221100////////////////////00000111100000000000111111111111122222111001100//..--,,,+,,,,++++*****))((''''&&&%%%%$$####""!!!``````a!"!!!!""##$$%%&&''(())**++,,--..//00112233445566778899:::99888877777777766666665555555555555555443322122333322110000111000//......--.....----,,--...--,,--.....--,,,---,,--,---,----,,--,,,-,,,---,,,,,,,,,+++,,--,,,------,,----,,----,,,-------,,,,,,,++******++++++,+++,,++*****)))))))))(((((((((''''''&&&&&&&&&&&&&&&&&&&'''(((((((((((((((((((((((()()))))())**++,,,,,,+,,,,++++++**))))))))((((((((('''''''''''''''''''&&%&&''''&&'&&&&''&&&'&&%%%%&&&%%%&&&&&&&&&&'''''''''&&&&&&%%&&&&&'''('((''(((''''''''''''''''&&&&''''''''&&&&&&&&&&&&&&&&&&&&&&&&''''''''''''''''''((((()))))))))))))*******)))***++++++++++++,,,--,,,--------------.......//00112233445566778899::;;<<==>>??????????????????????????>>==<<;;::999999999999988776667666666666677677666655555555544444444444444444433333333333332223333322222333333221100001111122111111111211222222112222112223322222233333333333333221100//................./////0000000///0000//000000000111111111110000000//..--,,++++,,++*******))((''&&&&%%%$%$$####""!!``````!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899:998887777666666666655555555555544444444433221112233221100//000000//..---.-----..----,,,,-----,,,,----.--,,+,,-,,,,,,,,,,,,,,,,,,,,,,,+,,-,,,,,,,,,+++++,,,,,,,----,,,,--,,,,--,,,,,--,,,,,,,,,,++**))))**++++++++++++***)))))))((((((((('''(''&'''&&&&&%%%%%%%%%%%%&&&&'''''(''''((((((((((((((((((((((((())**++,++++++++++******))))((((((((((''''''&'&&'''&&&''&'&&&&%%%&&&&&&&&&%%&&&&&&&&%%$$%%%%%$%%%&&&&&&&&&&&''''&&&%%%%%%%%%&&&&&''''''''''''''&''''&&&&&&&&&&&&''''''&&&&&&&&&&&%&&&&&&&&&&&&&&&&&&&&&'&'''''''''(((((())))))))))))))))*)))))************+++,,,,,,,,,,,,,,,,,,-------....//00112233445566778899::;;<<==>>?????????????????????????>==<<;;::998888888999988776666666666666666666666555444444444333444333333343333333333332222222222222211222222221100000001111110011111111111122111122111112222111122333333333333221100//..................../////0000///////////000000000000011111000//00//..--,,+++*++++****)))))((''&&&&%%%$$$$##""""a!`````a!!!!`!!````!!""##$$%%&&''(())**++,,--..//0011223344556677889998877776666666665555555444444444444444433221101122221100////000///..------,,-----,,,,++,,---,,++,,-----,,+++,,,++,,+,,,+,,,,++,,+++,+++,,,+++++++++***++,,+++,,,,,,++,,,,++,,,,+++,,,,,,,+++++++**))))))******+***++**)))))((((((((('''''''''&&&&&&%%%%%%%%%%%%%%%%%%%&&&''''''''''''''''''''''''('((((('(())**++++++*++++******))(((((((('''''''''&&&&&&&&&&&&&&&&&&&%%$%%&&&&%%&%%%%&&%%%&%%$$$$%%%$$$%%%%%%%%%%&&&&&&&&&%%%%%%$$%%%%%&&&'&''&&'''&&&&&&&&&&&&&&&&%%%%&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&'''''((((((((((((()))))))((()))************+++,,+++,,,,,,,,,,,,,,-------..//00112233445566778899::;;<<==>>????????????????????????==<<;;::998888888888888776655565555555555665665555444444444333333333333333333222222222222211122222111112222221100////00000110000000001001111110011110011122111111222222222222221100//..-----------------.....///////...////../////////00000000000///////..--,,++****++**)))))))((''&&%%%%$$$#$##""""baa!`!`a!!!```````!!""##$$%%&&''(())**++,,--..//00112233445566778898877766665555555555444444444444333333333221100011221100//..//////..--,,,-,,,,,--,,,,++++,,,,,++++,,,,-,,++*++,+++++++++++++++++++++++*++,+++++++++*****+++++++,,,,++++,,++++,,+++++,,++++++++++**))(((())************)))((((((('''''''''&&&'&&%&&&%%%%%$$$$$$$$$$$$%%%%&&&&&'&&&&'''''''''''''''''''''''''(())**+**********))))))((((''''''''''&&&&&&%&%%&&&%%%&&%&%%%%$$$%%%%%%%%%$$%%%%%%%%$$##$$$$$#$$$%%%%%%%%%%%&&&&%%%$$$$$$$$$%%%%%&&&&&&&&&&&&&&%&&&&%%%%%%%%%%%%&&&&&&%%%%%%%%%%%$%%%%%%%%%%%%%%%%%%%%%&%&&&&&&&&&''''''(((((((((((((((()((((())))))))))))***++++++++++++++++++,,,,,,,----..//00112233445566778899::;;<<==>>???????????????????????=<<;;::998877777778888776655555555555555555555554443333333332223332222222322222222222211111111111111001111111100///////000000//000000000000110000110000011110000112222222222221100//..--------------------.....////.........../////////////00000///..//..--,,++***)****))))(((((''&&%%%%$$$####""!!!!!a`!!`!aa```a!""##$$%%&&''(())**++,,--..//00112233445566778898877666655555555544444443333333333333333221100/00111100//....///...--,,,,,,++,,,,,++++**++,,,++**++,,,,,++***+++**++*+++*++++**++***+***+++*********)))**++***++++++**++++**++++***+++++++*******))(((((())))))*)))**))((((('''''''''&&&&&&&&&%%%%%%$$$$$$$$$$$$$$$$$$$%%%&&&&&&&&&&&&&&&&&&&&&&&&'&'''''&''(())******)****))))))((''''''''&&&&&&&&&%%%%%%%%%%%%%%%%%%%$$#$$%%%%$$%$$$$%%$$$%$$####$$$###$$$$$$$$$$%%%%%%%%%$$$$$$##$$$$$%%%&%&&%%&&&%%%%%%%%%%%%%%%%$$$$%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%&&&&&'''''''''''''((((((('''((())))))))))))***++***++++++++++++++,,,,,,,--..//00112233445566778899::;;<<==>>??????????????????????<<;;::998877777777777776655444544444444445545544443333333332222222222222222221111111111111000111110000011111100//..../////00/////////0//000000//0000//000110000001111111111111100//..--,,,,,,,,,,,,,,,,,-----.......---....--.........///////////.......--,,++**))))**))(((((((''&&%%$$$$###"#""!!!!!```````؀````a!!""##$$%%&&''(())**++,,--..//00112233445566778898877666555544444444443333333333332222222221100///001100//..--......--,,+++,+++++,,++++****+++++****++++,++**)**+***********************)**+*********)))))*******++++****++****++*****++**********))((''''(())))))))))))((('''''''&&&&&&&&&%%%&%%$%%%$$$$$############$$$$%%%%%&%%%%&&&&&&&&&&&&&&&&&&&&&&&&&''(())*))))))))))((((((''''&&&&&&&&&&%%%%%%$%$$%%%$$$%%$%$$$$###$$$$$$$$$##$$$$$$$$##""#####"###$$$$$$$$$$$%%%%$$$#########$$$$$%%%%%%%%%%%%%%$%%%%$$$$$$$$$$$$%%%%%%$$$$$$$$$$$#$$$$$$$$$$$$$$$$$$$$$%$%%%%%%%%%&&&&&&''''''''''''''''('''''(((((((((((()))******************+++++++,,,,--..//00112233445566778899::;;<<==>>?????????????????????<;;::99887766666667777665544444444444444444444443332222222221112221111111211111111111100000000000000//00000000//.......//////..////////////00////00/////0000////0011111111111100//..--,,,,,,,,,,,,,,,,,,,,-----....-----------............./////...--..--,,++**)))())))(((('''''&&%%$$$$###""""!!````````aa!!!""##$$%%&&''(())**++,,--..//00112233445566778898877665555444444444333333322222222222222221100//.//0000//..----...---,,++++++**+++++****))**+++**))**+++++**)))***))**)***)****))**)))*)))***)))))))))((())**)))******))****))****)))*******)))))))((''''''(((((()((())(('''''&&&&&&&&&%%%%%%%%%$$$$$$###################$$$%%%%%%%%%%%%%%%%%%%%%%%%&%&&&&&%&&''(())))))())))((((((''&&&&&&&&%%%%%%%%%$$$$$$$$$$$$$$$$$$$##"##$$$$##$####$$###$##""""###"""##########$$$$$$$$$######""#####$$$%$%%$$%%%$$$$$$$$$$$$$$$$####$$$$$$$$########################$$$$$$$$$$$$$$$$$$%%%%%&&&&&&&&&&&&&'''''''&&&'''(((((((((((()))**)))**************+++++++,,--..//00112233445566778899::;;<<==>>????????????????????;;::99887766666666666665544333433333333334434433332222222221111111111111111110000000000000///00000/////000000//..----.....//........./..//////..////..///00//////00000000000000//..--,,+++++++++++++++++,,,,,-------,,,----,,---------...........-------,,++**))(((())(('''''''&&%%$$####"""!"!!`@````a!"""##$$%%&&''(())**++,,--..//00112233445566778898877665554444333333333322222222222211111111100//...//00//..--,,------,,++***+*****++****))))*****))))****+**))())*)))))))))))))))))))))))())*)))))))))((((()))))))****))))**))))**)))))**))))))))))((''&&&&''(((((((((((('''&&&&&&&%%%%%%%%%$$$%$$#$$$#####""""""""""""####$$$$$%$$$$%%%%%%%%%%%%%%%%%%%%%%%%%&&''(()((((((((((''''''&&&&%%%%%%%%%%$$$$$$#$##$$$###$$#$####"""#########""########""!!"""""!"""###########$$$$###"""""""""#####$$$$$$$$$$$$$$#$$$$############$$$$$$###########"#####################$#$$$$$$$$$%%%%%%&&&&&&&&&&&&&&&&'&&&&&''''''''''''((())))))))))))))))))*******++++,,--..//00112233445566778899::;;<<==>>???????????????????;::99887766555555566665544333333333333333333333322211111111100011100000001000000000000//////////////..////////..-------......--............//....//.....////....//000000000000//..--,,++++++++++++++++++++,,,,,----,,,,,,,,,,,-------------.....---,,--,,++**))((('((((''''&&&&&%%$$####"""!!!!`ą``````a!!``a!"""##$$%%&&''(())**++,,--..//00112233445566778898877665544443333333332222222111111111111111100//..-..////..--,,,,---,,,++******))*****))))(())***))(())*****))((()))(())()))())))(())((()((()))((((((((('''(())((())))))(())))(())))((()))))))(((((((''&&&&&&''''''('''((''&&&&&%%%%%%%%%$$$$$$$$$######"""""""""""""""""""###$$$$$$$$$$$$$$$$$$$$$$$$%$%%%%%$%%&&''(((((('((((''''''&&%%%%%%%%$$$$$$$$$###################""!""####""#""""##"""#""!!!!"""!!!""""""""""#########""""""!!"""""###$#$$##$$$################""""########""""""""""""""""""""""""##################$$$$$%%%%%%%%%%%%%&&&&&&&%%%&&&''''''''''''((())((())))))))))))))*******++,,--..//00112233445566778899::;;<<==>>??????????????????::998877665555555555555443322232222222222332332222111111111000000000000000000/////////////.../////.....//////..--,,,,-----..---------.--......--....--...//......//////////////..--,,++*****************+++++,,,,,,,+++,,,,++,,,,,,,,,-----------,,,,,,,++**))((''''((''&&&&&&&%%$$##""""!!!`!!!`ݛ``a!aaa!!!!!!!""###$$%%&&''(())**++,,--..//00112233445566778898877665544433332222222222111111111111000000000//..---..//..--,,++,,,,,,++**)))*)))))**))))(((()))))(((())))*))(('(()((((((((((((((((((((((('(()((((((((('''''((((((())))(((())(((())((((())((((((((((''&&%%%%&&''''''''''''&&&%%%%%%%$$$$$$$$$###$##"###"""""!!!!!!!!!!!!""""#####$####$$$$$$$$$$$$$$$$$$$$$$$$$%%&&''(''''''''''&&&&&&%%%%$$$$$$$$$$######"#""###"""##"#""""!!!"""""""""!!""""""""!!``!!!!a`!!!"""""""""""####"""!!!!!!!!!"""""##############"####""""""""""""######"""""""""""!"""""""""""""""""""""#"#########$$$$$$%%%%%%%%%%%%%%%%&%%%%%&&&&&&&&&&&&'''(((((((((((((((((()))))))****++,,--..//00112233445566778899::;;<<==>>?????????????????:99887766554444444555544332222222222222222222222111000000000///000///////0////////////..............--........--,,,,,,,------,,------------..----..-----....----..////////////..--,,++********************+++++,,,,+++++++++++,,,,,,,,,,,,,-----,,,++,,++**))(('''&''''&&&&%%%%%$$##""""!!!``!``˓`a!!!!aa!"""!!""###$$%%&&''(())**++,,--..//00112233445566778898877665544333322222222211111110000000000000000//..--,--....--,,++++,,,+++**))))))(()))))((((''(()))((''(()))))(('''(((''(('((('((((''(('''('''((('''''''''&&&''(('''((((((''((((''(((('''((((((('''''''&&%%%%%%&&&&&&'&&&''&&%%%%%$$$$$$$$$#########""""""!!!!!!!!!!!!!!!!!!!"""########################$#$$$$$#$$%%&&''''''&''''&&&&&&%%$$$$$$$$#########"""""""""""""""""""!!`!!""""!!"!!!!""!!!"!!``!!!``!!!!!!!!!!"""""""""!!!!!!``!!!!!"""#"##""###""""""""""""""""!!!!""""""""!!!!!!!!!!!!!!!!!!!!!!!!""""""""""""""""""#####$$$$$$$$$$$$$%%%%%%%$$$%%%&&&&&&&&&&&&'''(('''(((((((((((((()))))))**++,,--..//00112233445566778899::;;<<==>>????????????????99887766554444444444444332211121111111111221221111000000000//////////////////.............---.....-----......--,,++++,,,,,--,,,,,,,,,-,,------,,----,,---..------..............--,,++**)))))))))))))))))*****+++++++***++++**+++++++++,,,,,,,,,,,+++++++**))((''&&&&''&&%%%%%%%$$##""!!!!`````ޗ`````!!"""""""""##$$$%%&&''(())**++,,--..//0011223334455667788887766554433322221111111111000000000000/////////..--,,,--..--,,++**++++++**))((()((((())((((''''(((((''''(((()((''&''('''''''''''''''''''''''&''('''''''''&&&&&'''''''((((''''((''''(('''''((''''''''''&&%%$$$$%%&&&&&&&&&&&&%%%$$$$$$$#########"""#""!"""!!!!!````````````!!!!"""""#""""#########################$$%%&&'&&&&&&&&&&%%%%%%$$$$##########""""""!"!!"""!!!""!"!!!!``!!!!!!!!!``!!!!!!!!!``````````!!!!!!!!!!!""""!!!```````!!!!!""""""""""""""!""""!!!!!!!!!!!!""""""!!!!!!!!!!!`!!!!!!!!!!!!!!!!!!!!!"!"""""""""######$$$$$$$$$$$$$$$$%$$$$$%%%%%%%%%%%%&&&''''''''''''''''''((((((())))**++,,--..//00112233445566778899::;;<<==>>???????????????988776655443333333444433221111111111111111111111000/////////...///......./............--------------,,--------,,+++++++,,,,,,++,,,,,,,,,,,,--,,,,--,,,,,----,,,,--............--,,++**))))))))))))))))))))*****++++***********+++++++++++++,,,,,+++**++**))((''&&&%&&&&%%%%$$$$$##""!!!!```ޝ`!!""###""##$$$%%&&''(())**++,,--..//001122222334455667788776655443322221111111110000000////////////////..--,,+,,----,,++****+++***))((((((''(((((''''&&''(((''&&''(((((''&&&'''&&''&'''&''''&&''&&&'&&&'''&&&&&&&&&%%%&&''&&&''''''&&''''&&''''&&&'''''''&&&&&&&%%$$$$$$%%%%%%&%%%&&%%$$$$$#########"""""""""!!!!!!```````!!!""""""""""""""""""""""""#"#####"##$$%%&&&&&&%&&&&%%%%%%$$########"""""""""!!!!!!!!!!!!!!!!!!!!``a!!!!!``!``a!```!!```````````!!!!!!!!!`٘```!!!"!""!!"""!!!!!!!!!!!!!!!!````!!!!!!!!```````````````````````!!!!!!!!!!!!!!!!!!"""""#############$$$$$$$###$$$%%%%%%%%%%%%&&&''&&&''''''''''''''((((((())**++,,--..//00112233445566778899::;;<<==>>??????????????88776655443333333333333221100010000000000110110000/////////..................-------------,,,-----,,,,,------,,++****+++++,,+++++++++,++,,,,,,++,,,,++,,,--,,,,,,--------------,,++**))((((((((((((((((()))))*******)))****))*********+++++++++++*******))((''&&%%%%&&%%$$$$$$$##""!!``````Ҟ```````!!""#######$$%%%&&''(())**++,,--..//001111222223344556677776655443322211110000000000////////////.........--,,+++,,--,,++**))******))(('''('''''((''''&&&&'''''&&&&''''(''&&%&&'&&&&&&&&&&&&&&&&&&&&&&&%&&'&&&&&&&&&%%%%%&&&&&&&''''&&&&''&&&&''&&&&&''&&&&&&&&&&%%$$####$$%%%%%%%%%%%%$$$#######"""""""""!!!"!!`!!!`ٜ`!!!!!"!!!!"""""""""""""""""""""""""##$$%%&%%%%%%%%%%$$$$$$####""""""""""!!!!!a`!``!!!```!!`!```````````````````֙```!!!!``͒``!!!!!!!!!!!!!!`!!!!````````!!!!!!`֑````````!`!!!!!!!!!""""""################$#####$$$$$$$$$$$$%%%&&&&&&&&&&&&&&&&&&'''''''(((())**++,,--..//00112233445566778899::;;<<==>>?????????????877665544332222222333322110000000000000000000000///.........---...-------.------------,,,,,,,,,,,,,,++,,,,,,,,++*******++++++**++++++++++++,,++++,,+++++,,,,++++,,------------,,++**))(((((((((((((((((((()))))****)))))))))))*************+++++***))**))((''&&%%%$%%%%$$$$#####""!!```ޞ`!`a!`!!!!""##$$$##$$%%%&&''(())**++,,--..//0011111111122334455667766554433221111000000000///////................--,,++*++,,,,++**))))***)))((''''''&&'''''&&&&%%&&'''&&%%&&'''''&&%%%&&&%%&&%&&&%&&&&%%&&%%%&%%%&&&%%%%%%%%%$$$%%&&%%%&&&&&&%%&&&&%%&&&&%%%&&&&&&&%%%%%%%$$######$$$$$$%$$$%%$$#####"""""""""!!!!!!!!!```````!!!!!!!!!!!!!!!!!!!!!!!!"!"""""!""##$$%%%%%%$%%%%$$$$$$##""""""""!!!!!!!!!`````````ٙؕڙؖԕ````Ύ`!`!!``!!!````````٘```````ɕ`````````!!!!!"""""""""""""#######"""###$$$$$$$$$$$$%%%&&%%%&&&&&&&&&&&&&&'''''''(())**++,,--..//00112233445566778899::;;<<==>>????????????776655443322222222222221100///0//////////00/00////.........------------------,,,,,,,,,,,,,+++,,,,,+++++,,,,,,++**))))*****++*********+**++++++**++++**+++,,++++++,,,,,,,,,,,,,,++**))(('''''''''''''''''((((()))))))((())))(()))))))))***********)))))))((''&&%%$$$$%%$$#######""!!`͋```a!!a!!!!!""##$$$$$$$%%&&&''(())**++,,--..//0000000011111223344556666554433221110000//////////............---------,,++***++,,++**))(())))))((''&&&'&&&&&''&&&&%%%%&&&&&%%%%&&&&'&&%%$%%&%%%%%%%%%%%%%%%%%%%%%%%$%%&%%%%%%%%%$$$$$%%%%%%%&&&&%%%%&&%%%%&&%%%%%&&%%%%%%%%%%$$##""""##$$$$$$$$$$$$###"""""""!!!!!!!!!```!!`````!````!!!!!!!!!!!!!!!!!!!!!!!!!""##$$%$$$$$$$$$$######""""!!!!!!!!!!````ё֗ٙٙՖ```````ǐښ˘٘`!!!!!!""""""""""""""""#"""""############$$$%%%%%%%%%%%%%%%%%%&&&&&&&''''(())**++,,--..//00112233445566778899::;;<<==>>???????????76655443322111111122221100//////////////////////...---------,,,---,,,,,,,-,,,,,,,,,,,,++++++++++++++**++++++++**)))))))******))************++****++*****++++****++,,,,,,,,,,,,++**))((''''''''''''''''''''((((())))((((((((((()))))))))))))*****)))(())((''&&%%$$$#$$$$####"""""!!`͊``a!!!!!""!""""##$$%%%$$%%&&&''(())**++,,--..//000000000000011223344556655443322110000/////////.......----------------,,++**)**++++**))(((()))(((''&&&&&&%%&&&&&%%%%$$%%&&&%%$$%%&&&&&%%$$$%%%$$%%$%%%$%%%%$$%%$$$%$$$%%%$$$$$$$$$###$$%%$$$%%%%%%$$%%%%$$%%%%$$$%%%%%%%$$$$$$$##""""""######$###$$##"""""!!!!!!!!!````````җڛ`````````````````!`!!!!!`!!""##$$$$$$#$$$$######""!!!!!!!!`````חԕԒ՗``````!!!!!!!!!!!!!"""""""!!!"""############$$$%%$$$%%%%%%%%%%%%%%&&&&&&&''(())**++,,--..//00112233445566778899::;;<<==>>??????????6655443322111111111111100//.../..........//.//....---------,,,,,,,,,,,,,,,,,,+++++++++++++***+++++*****++++++**))(((()))))**)))))))))*))******))****))***++******++++++++++++++**))((''&&&&&&&&&&&&&&&&&'''''((((((('''((((''((((((((()))))))))))(((((((''&&%%$$####$$##""""""""!!````aa!!!!"""""!""##$$%%%%%&&'''(())**++,,--..///0////////0000011223344555544332211000////..........------------,,,,,,,,,++**)))**++**))((''((((((''&&%%%&%%%%%&&%%%%$$$$%%%%%$$$$%%%%&%%$$#$$%$$$$$$$$$$$$$$$$$$$$$$$#$$%$$$$$$$$$#####$$$$$$$%%%%$$$$%%$$$$%%$$$$$%%$$$$$$$$$$##""!!!!""############"""!!!!!!!`````ѕŖؚ```````!!""##$##########""""""!!!!`````֗``!!!!!!!!!!!!!!!!"!!!!!""""""""""""###$$$$$$$$$$$$$$$$$$%%%%%%%&&&&''(())**++,,--..//00112233445566778899::;;<<==>>?????????655443322110000000111100//......................---,,,,,,,,,+++,,,+++++++,++++++++++++**************))********))((((((())))))(())))))))))))**))))**)))))****))))**++++++++++++**))((''&&&&&&&&&&&&&&&&&&&&'''''(((('''''''''''((((((((((((()))))(((''((''&&%%$$###"####""""!!!!!"!!``!!``!```!!"""!!!""##$$%%%&&'''(())**++,,--../////////////////0011223344554433221100////.........-------,,,,,,,,,,,,,,,,++**))())****))((''''((('''&&%%%%%%$$%%%%%$$$$##$$%%%$$##$$%%%%%$$###$$$##$$#$$$#$$$$##$$###$###$$$#########"""##$$###$$$$$$##$$$$##$$$$###$$$$$$$#######""!!!!!!""""""#"""##""!!!!!````ڛ֖`!!""#######"####""""""!!```ٙ```````````!!!!!!!```!!!""""""""""""###$$###$$$$$$$$$$$$$$%%%%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????????55443322110000000000000//..---.----------..-..----,,,,,,,,,++++++++++++++++++*************)))*****)))))******))((''''((((())((((((((()(())))))(())))(()))**))))))**************))((''&&%%%%%%%%%%%%%%%%%&&&&&'''''''&&&''''&&'''''''''((((((((((('''''''&&%%$$##""""##""!!!!!!!!!!!!!!!`````!!"!!`!!""##$$%%&&''(())**++,,--..///../......../////00112233444433221100///....----------,,,,,,,,,,,,+++++++++**))((())**))((''&&''''''&&%%$$$%$$$$$%%$$$$####$$$$$####$$$$%$$##"##$#######################"##$#########"""""#######$$$$####$$####$$#####$$##########""!!````!!""""""""""""!!!```ڙ`!!""##""""""""""!!!!!!`י`````!``!!!!!!!!!!!!"""##################$$$$$$$%%%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???????54433221100///////0000//..----------------------,,,+++++++++***+++*******+************))))))))))))))(())))))))(('''''''((((((''(((((((((((())(((())((((())))(((())************))((''&&%%%%%%%%%%%%%%%%%%%%&&&&&''''&&&&&&&&&&&'''''''''''''((((('''&&''&&%%$$##"""!""""!!!!`````a!!!!!!`Βʏ`a!!!!``!!""##$$%%&&''(())**++,,--../................//001122334433221100//....---------,,,,,,,++++++++++++++++**))(('(())))((''&&&&'''&&&%%$$$$$$##$$$$$####""##$$$##""##$$$$$##"""###""##"###"####""##"""#"""###"""""""""!!!""##"""######""####""####"""#######"""""""!!``!!!!!!"!!!""!!``ښ`a!""""""""!""""!!!!!!`՘``Ց``!!!!!!!!!!!!"""##"""##############$$$$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????4433221100/////////////..--,,,-,,,,,,,,,,--,--,,,,+++++++++******************)))))))))))))((()))))((((())))))((''&&&&'''''(('''''''''(''((((((''((((''((())(((((())))))))))))))((''&&%%$$$$$$$$$$$$$$$$$%%%%%&&&&&&&%%%&&&&%%&&&&&&&&&'''''''''''&&&&&&&%%$$##""!!!!""!!`````!!````````!!!`!!""##$$%%&&''(())**++,,--.....--.--------.....//0011223333221100//...----,,,,,,,,,,++++++++++++*********))(('''(())((''&&%%&&&&&&%%$$###$#####$$####""""#####""""####$##""!""#"""""""""""""""""""""""!""#"""""""""!!!!!"""""""####""""##""""##"""""##""""""""""!!`ʍ``a!!!!!!!!!!!`֘`!!""""!!!!!!!!!!`````ٙח``````````!!!""""""""""""""""""#######$$$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????433221100//.......////..--,,,,,,,,,,,,,,,,,,,,,,+++*********)))***)))))))*))))))))))))((((((((((((((''((((((((''&&&&&&&''''''&&''''''''''''((''''(('''''((((''''(())))))))))))((''&&%%$$$$$$$$$$$$$$$$$$$$%%%%%&&&&%%%%%%%%%%%&&&&&&&&&&&&&'''''&&&%%&&%%$$##""!!!`!!!!```ŗ`!!!!""##$$%%&&''(())**++,,--.....----------------..//00112233221100//..----,,,,,,,,,+++++++****************))((''&''((((''&&%%%%&&&%%%$$######""#####""""!!""###""!!""#####""!!!"""!!""!"""!""""!!""!!!"!!!"""!!!!!!!!!```!!""!!!""""""!!""""!!""""!!!"""""""!!!!!!!!!`ː`````!```!!``ԗ`a!"""!!!!!!`!!!!`ښ``!!!""!!!""""""""""""""#######$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????33221100//.............--,,+++,++++++++++,,+,,++++*********))))))))))))))))))((((((((((((('''((((('''''((((((''&&%%%%&&&&&''&&&&&&&&&'&&''''''&&''''&&'''((''''''((((((((((((((''&&%%$$#################$$$$$%%%%%%%$$$%%%%$$%%%%%%%%%&&&&&&&&&&&%%%%%%%$$##""!!```!!!!```ϖ`aa!""##$$%%&&''(())**++,,--....---,,-,,,,,,,,-----..//001122221100//..---,,,,++++++++++************)))))))))((''&&&''((''&&%%$$%%%%%%$$##"""#"""""##""""!!!!"""""!!!!""""#""!!`!!"!!!!!!!!!!!!!!!!!!!!!!!`!!"!!!!!!!!!``!!!!!!!""""!!!!""!!!!""!!!!!""!!!!!!!!!!!!!`ϒ```ט`a!"""!!!````````՘`!!!!!!!!!!!!!!!!!!"""""""####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???3221100//..-------....--,,++++++++++++++++++++++***)))))))))((()))((((((()((((((((((((''''''''''''''&&''''''''&&%%%%%%%&&&&&&%%&&&&&&&&&&&&''&&&&''&&&&&''''&&&&''((((((((((((''&&%%$$####################$$$$$%%%%$$$$$$$$$$$%%%%%%%%%%%%%&&&&&%%%$$%%$$##""!!``!!!!````ʕ`aa!!""##$$%%&&''(())**++,,--..---,,,,,,,,,,,,,,,,--..//0011221100//..--,,,,+++++++++*******))))))))))))))))((''&&%&&''''&&%%$$$$%%%$$$##""""""!!"""""!!!!``!!"""!!``!!"""""!!``!!!``!!`!!!`!a!!``!!```!``!!!``````````!!!```!!!!!!``!!!!``!!!!```!!!!!!!`````````ԕښđ@@@`!!""!!``ٙښ``!!```!!!!!!!!!!!!!!"""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??221100//..-------------,,++***+**********++*++****)))))))))(((((((((((((((((('''''''''''''&&&'''''&&&&&''''''&&%%$$$$%%%%%&&%%%%%%%%%&%%&&&&&&%%&&&&%%&&&''&&&&&&''''''''''''''&&%%$$##"""""""""""""""""#####$$$$$$$###$$$$##$$$$$$$$$%%%%%%%%%%%$$$$$$$$##""!!!``````!!!```ΐ``!`a!""##$$%%&&''(())**++,,----,,,++,++++++++,,,,,--..//00111100//..--,,,++++**********))))))))))))(((((((((''&&%%%&&''&&%%$$##$$$$$$##""!!!"!!!!!""!!!!``!!!!!``!!!!"""!a`a!!````````````````!!`̐`````!!!!``a!``!!``!!````֗@@`!!"!!```````````````!!!!!!!""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?21100//..--,,,,,,,----,,++**********************)))((((((((('''((('''''''(''''''''''''&&&&&&&&&&&&&&%%&&&&&&&&%%$$$$$$$%%%%%%$$%%%%%%%%%%%%&&%%%%&&%%%%%&&&&%%%%&&''''''''''''&&%%$$##""""""""""""""""""""#####$$$$###########$$$$$$$$$$$$$%%%%%$$$##$$$##""!!`````!!!````͒``!!""##$$%%&&''(())**++,,--,,,++++++++++++++++,,--..//001100//..--,,++++*********)))))))((((((((((((((((''&&%%$%%&&&&%%$$####$$$###""!!!!!!``!!!!!`````!!!!``a!!!!!!!!!!``````ϏӔՕ``ѓӎ`````͍``ʏ``````````ԔƋ`!!"!!`Ж`͖```!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>1100//..--,,,,,,,,,,,,,++**)))*))))))))))**)**))))(((((((((''''''''''''''''''&&&&&&&&&&&&&%%%&&&&&%%%%%&&&&&&%%$$####$$$$$%%$$$$$$$$$%$$%%%%%%$$%%%%$$%%%&&%%%%%%&&&&&&&&&&&&&&%%$$##""!!!!!!!!!!!!!!!!!"""""#######"""####""#########$$$$$$$$$$$########""!!```````````В``Ǒ`!!""##$$%%&&''(())**++,,-,,+++**+********+++++,,--..//0000//..--,,+++****))))))))))(((((((((((('''''''''&&%%$$$%%&&%%$$##""######""!!```!```a!`ԋ```````a``!!!````ԕՖ֖Քӓ`Ֆ`a!"!!`̔ƀ````!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>100//..--,,+++++++,,,,++**))))))))))))))))))))))((('''''''''&&&'''&&&&&&&'&&&&&&&&&&&&%%%%%%%%%%%%%%$$%%%%%%%%$$#######$$$$$$##$$$$$$$$$$$$%%$$$$%%$$$$$%%%%$$$$%%&&&&&&&&&&&&%%$$##""!!!!!!!!!!!!!!!!!!!!"""""####"""""""""""#############$$$$$###""#####""!!``````ӓ``ғ`!!""##$$%%&&''(())**++,,-,,+++****************++,,--..//00//..--,,++****)))))))))(((((((''''''''''''''''&&%%$$#$$%%%%$$##""""###"""!!``Ȓ````Џ`ʑ````Ֆ֕``a!!!!!`Е```!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==00//..--,,+++++++++++++**))((()(((((((((())())(((('''''''''&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%$$$%%%%%$$$$$%%%%%%$$##""""#####$$#########$##$$$$$$##$$$$##$$$%%$$$$$$%%%%%%%%%%%%%%$$##""!!`````````````````!!!!!"""""""!!!""""!!"""""""""###########"""""""###""!!!`ώ``ŋ`!!""##$$%%&&''(())**++,,,,++***))*))))))))*****++,,--..////..--,,++***))))((((((((((''''''''''''&&&&&&&&&%%$$###$$%%$$##""!!""""""!!``ϔ֖ֈؙ`a!!!`!``͕`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<=0//..--,,++*******++++**))(((((((((((((((((((((('''&&&&&&&&&%%%&&&%%%%%%%&%%%%%%%%%%%%$$$$$$$$$$$$$$##$$$$$$$$##"""""""######""############$$####$$#####$$$$####$$%%%%%%%%%%%%$$##""!!```!!!!!""""!!!!!!!!!!!"""""""""""""#####"""!!"""""""""!!!``````!!`͔`!!""##$$%%&&''(())**++,,,++***))))))))))))))))**++,,--..//..--,,++**))))((((((((('''''''&&&&&&&&&&&&&&&&%%$$##"##$$$$##""!!!!"""!!!`````ɑ`a!````֗`aa""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==//..--,,++*************))(('''(''''''''''(('((''''&&&&&&&&&%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$###$$$$$#####$$$$$$##""!!!!"""""##"""""""""#""######""####""###$$######$$$$$$$$$$$$$$##""!!!a`````ƌ̎```!!!a!!!```!!!!``!!!!!!!!!"""""""""""!!!!!!!"""""""!!!``````ˇ`a!`Ɩ`a!""##$$%%&&''(())**++,++**)))(()(((((((()))))**++,,--....--,,++**)))((((''''''''''&&&&&&&&&&&&%%%%%%%%%$$##"""##$$##""!!``!!!!!!!!````Ɛ```Օ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==/..--,,++**)))))))****))((''''''''''''''''''''''&&&%%%%%%%%%$$$%%%$$$$$$$%$$$$$$$$$$$$##############""########""!!!!!!!""""""!!""""""""""""##""""##"""""####""""##$$$$$$$$$$$$##""!a````!``!````````````aa!!``````a!!!!!!!!!!!!"""""!!!``!!!!!!!!!!!`````!!```!```֖``!!""##$$%%&&''(())**+++**)))(((((((((((((((())**++,,--..--,,++**))(((('''''''''&&&&&&&%%%%%%%%%%%%%%%%$$##""!""####""!!``!!!````ђ``Ԗ`!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==..--,,++**)))))))))))))((''&&&'&&&&&&&&&&''&''&&&&%%%%%%%%%$$$$$$$$$$$$$$$$$$#############"""#####"""""######""!!````!!!!!""!!!!!!!!!"!!""""""!!""""!!"""##""""""#############cbb!!``````````````````````````````````!!!!!!!!!!!`````!!!!!!!``a!`````````````ٙ`!!""##$$%%&&''(())**+**))(((''(''''''''((((())**++,,----,,++**))(((''''&&&&&&&&&&%%%%%%%%%%%%$$$$$$$$$##""!!!""####""!!``````ϓ``ʘ``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>.--,,++**))((((((())))((''&&&&&&&&&&&&&&&&&&&&&&%%%$$$$$$$$$###$$$#######$############""""""""""""""!!""""""""!!```!!!!!!``!!!!!!!!!!!!""!!!!""!!!!!""""!!!!""#############cb"!a`В֚Ԕؙ`````!!!!!`̇``````!`````ٙ`!!""##$$%%&&''(())****))(((''''''''''''''''(())**++,,--,,++**))((''''&&&&&&&&&%%%%%%%$$$$$$$$$$$$$$$$##""!!`!!""##""!!!`ט֖`````a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>--,,++**))(((((((((((((''&&%%%&%%%%%%%%%%&&%&&%%%%$$$$$$$$$##################"""""""""""""!!!"""""!!!!!"""""""!!`Ň```!!```````!``a!!!!!``!!!!``!!!""!!!!!!"""""""""""""""""!!`ϋ@@@@@̏``````Д```̌@@Ֆ```!!""##$$%%&&''(())****))(('''&&'&&&&&&&&'''''(())**++,,,,++**))(('''&&&&%%%%%%%%%%$$$$$$$$$$$$#########""!!``!!""""!!!`Ʉ@````!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>-,,++**))(('''''''((((''&&%%%%%%%%%%%%%%%%%%%%%%$$$#########"""###"""""""#""""""""""""!!!!!!!!!!!!!a``!!!!!!!!!`a`````````!!``!!```!!!!````!!""""""""""""""""!!``Ӕזؘؗ`!!!""##$$%%&&''(())****))(('''&&&&&&&&&&&&&&&&''(())**++,,++**))((''&&&&%%%%%%%%%$$$$$$$################""!a``!!"""!!``````````!a!!!!!!`a!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>,,++**))(('''''''''''''&&%%$$$%$$$$$$$$$$%%$%%$$$$#########""""""""""""""""""!!!!!!!!!!!!!```!!!!!```!!!!!!!```!!``````aa`À````````````ɐ`!!``!!!!!!!!!!!!!!!!!!!!`a``ȋć`!!""##$$%%&&''(())***))((''&&&%%&%%%%%%%%&&&&&''(())**++++**))((''&&&%%%%$$$$$$$$$$############""""""""""baa``!!"!!``ɒɏ`a!!!!!!"""!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?,++**))((''&&&&&&&''''&&%%$$$$$$$$$$$$$$$$$$$$$$###"""""""""!!!"""!!!!!!!"!!!!!!!!!!!!`````````````````Å`````````````````ϒԕԓ`````ȏ`!!!!!!!!!!!!!!!!!!!!!!a```ґ````!!""##$$%%&&''(())***))((''&&&%%%%%%%%%%%%%%%%&&''(())**++**))((''&&%%%%$$$$$$$$$#######"""""""""""""""""!""!!``a!!!!`ēڛ``!!""""""""!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??++**))((''&&&&&&&&&&&&&%%$$###$##########$$#$$####"""""""""!!!!!!!!!!!!!!!!!!`````````ӓ֗זؘٙח@Dž````````````````````````!``@Ɋ``a!!!!""##$$%%&&''(())***))((''&&%%%$$%$$$$$$$$%%%%%&&''(())****))((''&&%%%$$$$##########""""""""""""!!!!!!!!!!!!!!!!!!!!`Β```````!!"""""###"""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???+**))((''&&%%%%%%%&&&&%%$$######################"""!!!!!!!!!```!!!```````!```֘ӓ``Dž``aa!!!""##$$%%&&''(())***))((''&&%%%$$$$$$$$$$$$$$$$%%&&''(())**))((''&&%%$$$$#########"""""""!!!!!!!!!!!!!!!!!`!!!!``````Ǎ`!!`!!!!!""########"##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????**))((''&&%%%%%%%%%%%%%$$##"""#""""""""""##"##""""!!!!!!!!!`````Ҕח``a!!"""""##$$%%&&''(())***))((''&&%%$$$##$########$$$$$%%&&''(())))((''&&%%$$$####""""""""""!!!!!!!!!!!!`````````````֖`!!!!!!""""#########$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????*))((''&&%%$$$$$$$%%%%$$##""""""""""""""""""""""!!!`````````Д֗ؗ`````!!!!"""""##$$%%&&''(())***))((''&&%%$$$################$$%%&&''(())((''&&%%$$####"""""""""!!!!!!!````````ٙٙ`!!"""""""""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????))((''&&%%$$$$$$$$$$$$$##""!!!"!!!!!!!!!!""!""!!!!````````a!!!!!!"""#####$$%%&&''(())***))((''&&%%$$###""#""""""""#####$$%%&&''((((''&&%%$$###""""!!!!!!!!!!````ؙ`!!"""""""!!""""""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????)((''&&%%$$#######$$$$##""!!!!!!!!!!!!!!!!!!!!!a```@`````!!!!!!!!!!!!""""#####$$%%&&''(())***))((''&&%%$$###""""""""""""""""##$$%%&&''((''&&%%$$##""""!!!!!!!!!```ؘ`!!"""""!!!!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???((''&&%%$$#############""!!```!``````````!!`!!``À@@```````````````````a!!!!!!!!!!!"""""""###$$$$$$%%&&''(())**))((''&&%%$$##"""!!"!!!!!!!!"""""##$$%%&&''''&&%%$$##"""!!!!```````ٙ`!!!"""!!``a!!!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??(''&&%%$$##"""""""####""!!``````@@@`````````!!!!!!!!!!!!!""!!""""""""####$$$$$$$$%%&&''(())))((''&&%%$$##"""!!!!!!!!!!!!!!!!""##$$%%&&''&&%%$$##""!!!!``٘`a!!!!!````````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?''&&%%$$##""""""""""""""!!`ϓԕԔҎ@@Փ`!!!!!!!""!!!!!!!!""#######$$$$#####$$%%&&''(())((''&&%%$$##""!!!``!````````!!!!!""##$$%%&&&&%%$$##""!!!``ח``!!!!``!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>'&&%%$$##""!!!!!!!"""""!!`ɊȊʇԕɉ`a!""""!!!!!!!!!``!!""####$$$$$#######$$%%&&''((((''&&%%$$##""!!!``````!!""##$$%%&&%%$$##""!!``ך```a``@`````!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?&&%%$$##""!!!!!!!!!!!!""!!````@ˍ`````````````a!""!!!!!!!``````!!""##$$$$$##"""""##$$%%&&''((''&&%%$$##""!!``ÎБ`!!""##$$%%%%$$##""!!`ט`À`!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??&%%$$##""!!```````!!!!!!"!!!!```Čϑ@ˌ`!!!!a`!!!!!!""!!!!`````a!""##$$%$$##"""""""##$$%%&&''''&&%%$$##""!!`ˌ`a!""##$$%%%$$##""!!`ˌ€`!!!!!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>???%%$$##""!!`````!!!"!!!!!a`LJ@@@@@````!!aa!!!!!!""!!```Ā``!!!!""##$$$##""!!!!!""##$$%%&&'''&&%%$$##""!!`Ɍ`!!""##$$%%$$##""!!`ŀLJ```````````a!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>????%$$##""!!`ɋ``!!"""!!!!``````````Ɋ@@``!a!""""""!!`̉``!!!!""##$##""!!!!!!!""##$$%%&&'&&%%$$##""!!``!!""##$$$$##""!!`@@@``````a`!!!!!!!!!!!"""""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>?????%%$$##""!!``Ɋ`!!"""""!!``!!!!!!!````ȏ`!!"""""!!``a`````!!""###""!!`````!!""##$$%%&&&%%$$##""!!```ˎ`!!""##$$$$##""!a````````````@@@@͎Ώ`!!!!!!!!!!!!!!!!""#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????&%%$$##""!!!`@@@@`!!"""!!``aaa!!!!!!!``````a!""###""!!```````!!!`````!!""#""!!``!!""##$$%%&%%$$##""!!`А`!!""##$$%$$##""!!!!!!!!!!!!a`@@@@@@@@@@@@`a!!!!"!"""""""""""#####$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??????? \ No newline at end of file diff --git a/tests/testdata/maps/world/thumbnail.webp b/tests/testdata/maps/world/thumbnail.webp new file mode 100644 index 0000000000000000000000000000000000000000..0e178d327e9f024f0bd80bdbe9b16f950e240b32 GIT binary patch literal 10250 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 {}; - // Load the specified map - const mapPath = path.join(__dirname, "..", "testdata", `${mapName}.png`); - const imageBuffer = await fs.readFile(mapPath); - const { map, miniMap } = await generateMap(imageBuffer, false); - const gameMap = await genTerrainFromBin(String.fromCharCode.apply(null, map)); - const miniGameMap = await genTerrainFromBin( - String.fromCharCode.apply(null, miniMap), - ); + // Try binary map format first (tests/testdata/maps/{mapName}/) + const binMapDir = path.join(__dirname, "..", "testdata", "maps", mapName); + const mapBinPath = path.join(binMapDir, "map.bin"); + const miniMapBinPath = path.join(binMapDir, "map4x.bin"); + + let gameMap, miniGameMap; + + if (fsSync.existsSync(mapBinPath) && fsSync.existsSync(miniMapBinPath)) { + // Binary map format + const mapBinBuffer = fsSync.readFileSync(mapBinPath); + const miniMapBinBuffer = fsSync.readFileSync(miniMapBinPath); + const mapBinString = String.fromCharCode(...new Uint8Array(mapBinBuffer)); + const miniMapBinString = String.fromCharCode( + ...new Uint8Array(miniMapBinBuffer), + ); + gameMap = await genTerrainFromBin(mapBinString); + miniGameMap = await genTerrainFromBin(miniMapBinString); + } else { + // Legacy PNG map format + const mapPath = path.join(__dirname, "..", "testdata", `${mapName}.png`); + const imageBuffer = await fs.readFile(mapPath); + const { map, miniMap } = await generateMap(imageBuffer, false); + gameMap = await genTerrainFromBin(String.fromCharCode.apply(null, map)); + miniGameMap = await genTerrainFromBin( + String.fromCharCode.apply(null, miniMap), + ); + } // Configure the game const serverConfig = new TestServerConfig(); diff --git a/tests/util/TestConfig.ts b/tests/util/TestConfig.ts index f8f180793..debb15cd0 100644 --- a/tests/util/TestConfig.ts +++ b/tests/util/TestConfig.ts @@ -21,6 +21,10 @@ export class TestConfig extends DefaultConfig { return 1; } + disableNavMesh(): boolean { + return this.gameConfig().disableNavMesh ?? true; + } + radiusPortSpawn(): number { return 1; } From 25a44f732b3c7ba7d8f9a632adf6d51cc4415766 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 04:23:04 +0100 Subject: [PATCH 22/34] Refactor pathfinding UI and backend for HPA* integration - Updated HTML structure to replace references from "Gateways" to "Nodes" and "Used Gateways" to "Used Nodes". - Changed button IDs and labels to reflect the new pathfinding algorithm (HPA*). - Removed unused PF.Mini pathfinding API endpoint and adjusted the main pathfinding endpoint to accept comparison adapters. - Enhanced CSS styles for comparison rows in the UI. - Updated pathfinding utility functions to support new pathfinding algorithms and configurations. - Deleted obsolete performance test for A* pathfinding. --- src/core/execution/BomberExecution.ts | 2 +- src/core/execution/CargoPlaneExecution.ts | 2 +- src/core/execution/CityAABulletExecution.ts | 2 +- src/core/execution/FighterJetExecution.ts | 2 +- src/core/execution/MIRVExecution.ts | 29 +- src/core/execution/NukeExecution.ts | 28 +- .../execution/ParatrooperAttackExecution.ts | 2 +- src/core/execution/SAMMissileExecution.ts | 16 +- src/core/execution/ShellExecution.ts | 15 +- src/core/execution/SubmarineExecution.ts | 25 +- src/core/execution/TradeManagerExecution.ts | 20 +- src/core/execution/TradeShipExecution.ts | 7 +- src/core/execution/TransportShipExecution.ts | 49 +- src/core/execution/WarshipExecution.ts | 180 +--- src/core/game/Game.ts | 12 +- src/core/game/GameImpl.ts | 95 +- src/core/game/PlayerImpl.ts | 2 +- src/core/game/TransportShipUtils.ts | 233 +---- src/core/pathfinding/AStar.ts | 31 - src/core/pathfinding/MiniAStar.ts | 256 ------ src/core/pathfinding/PathFinder.Air.ts | 66 ++ src/core/pathfinding/PathFinder.Parabola.ts | 88 ++ src/core/pathfinding/PathFinder.Straight.ts | 44 + src/core/pathfinding/PathFinder.ts | 104 ++- src/core/pathfinding/PathFinderBuilder.ts | 42 + src/core/pathfinding/PathFinderStepper.ts | 119 +++ src/core/pathfinding/PathFinding.ts | 285 ------ src/core/pathfinding/SerialAStar.ts | 219 ----- .../pathfinding/adapters/MiniAStarAdapter.ts | 66 -- .../pathfinding/adapters/NavMeshAdapter.ts | 99 --- .../algorithms/AStar.AbstractGraph.ts | 249 ++++++ .../pathfinding/algorithms/AStar.Bounded.ts | 289 ++++++ .../pathfinding/algorithms/AStar.Water.ts | 203 +++++ .../algorithms/AStar.WaterHierarchical.ts | 562 ++++++++++++ src/core/pathfinding/algorithms/AStar.ts | 127 +++ .../pathfinding/algorithms/AbstractGraph.ts | 682 +++++++++++++++ .../FastBFS.ts => algorithms/BFS.Grid.ts} | 62 +- src/core/pathfinding/algorithms/BFS.ts | 64 ++ .../ConnectedComponents.ts} | 10 +- .../pathfinding/algorithms/PriorityQueue.ts | 154 ++++ src/core/pathfinding/navmesh/FastAStar.ts | 202 ----- .../pathfinding/navmesh/FastAStarAdapter.ts | 120 --- src/core/pathfinding/navmesh/GatewayGraph.ts | 587 ------------- src/core/pathfinding/navmesh/NavMesh.ts | 819 ------------------ .../smoothing/BresenhamPathSmoother.ts | 168 ++++ .../pathfinding/smoothing/PathSmoother.ts | 7 + .../smoothing/SmoothingTransformer.ts | 18 + src/core/pathfinding/spatial/SpatialQuery.ts | 90 ++ .../transformers/ComponentCheckTransformer.ts | 35 + .../transformers/MiniMapTransformer.ts | 128 +++ .../transformers/ShoreCoercingTransformer.ts | 91 ++ src/core/pathfinding/types.ts | 34 + .../executions/TradeShipExecution.test.ts | 2 +- tests/core/pathfinding/PathFinder.test.ts | 332 ------- .../pathfinding/PathFinderStepper.test.ts | 178 ++++ .../core/pathfinding/PathFinding.Air.test.ts | 183 ++++ .../pathfinding/PathFinding.Water.test.ts | 276 ++++++ tests/core/pathfinding/SpatialQuery.test.ts | 235 +++++ .../UniversalPathFinding.Parabola.test.ts | 319 +++++++ .../core/pathfinding/WaterComponents.test.ts | 144 +++ tests/core/pathfinding/_fixtures.ts | 179 ++++ .../ComponentCheckTransformer.test.ts | 168 ++++ .../transformers/MiniMapTransformer.test.ts | 178 ++++ .../ShoreCoercingTransformer.test.ts | 244 ++++++ tests/pathfinding/benchmark/compare.ts | 180 ++++ tests/pathfinding/playground/api/maps.ts | 118 ++- .../pathfinding/playground/api/pathfinding.ts | 264 ++++-- tests/pathfinding/playground/public/client.js | 682 +++++++-------- .../pathfinding/playground/public/index.html | 79 +- .../pathfinding/playground/public/styles.css | 61 ++ tests/pathfinding/playground/server.ts | 78 +- tests/pathfinding/utils.ts | 74 +- tests/perf/AstarPerf.ts | 29 - 73 files changed, 6591 insertions(+), 4253 deletions(-) delete mode 100644 src/core/pathfinding/AStar.ts delete mode 100644 src/core/pathfinding/MiniAStar.ts create mode 100644 src/core/pathfinding/PathFinder.Air.ts create mode 100644 src/core/pathfinding/PathFinder.Parabola.ts create mode 100644 src/core/pathfinding/PathFinder.Straight.ts create mode 100644 src/core/pathfinding/PathFinderBuilder.ts create mode 100644 src/core/pathfinding/PathFinderStepper.ts delete mode 100644 src/core/pathfinding/PathFinding.ts delete mode 100644 src/core/pathfinding/SerialAStar.ts delete mode 100644 src/core/pathfinding/adapters/MiniAStarAdapter.ts delete mode 100644 src/core/pathfinding/adapters/NavMeshAdapter.ts create mode 100644 src/core/pathfinding/algorithms/AStar.AbstractGraph.ts create mode 100644 src/core/pathfinding/algorithms/AStar.Bounded.ts create mode 100644 src/core/pathfinding/algorithms/AStar.Water.ts create mode 100644 src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts create mode 100644 src/core/pathfinding/algorithms/AStar.ts create mode 100644 src/core/pathfinding/algorithms/AbstractGraph.ts rename src/core/pathfinding/{navmesh/FastBFS.ts => algorithms/BFS.Grid.ts} (66%) create mode 100644 src/core/pathfinding/algorithms/BFS.ts rename src/core/pathfinding/{navmesh/WaterComponents.ts => algorithms/ConnectedComponents.ts} (95%) create mode 100644 src/core/pathfinding/algorithms/PriorityQueue.ts delete mode 100644 src/core/pathfinding/navmesh/FastAStar.ts delete mode 100644 src/core/pathfinding/navmesh/FastAStarAdapter.ts delete mode 100644 src/core/pathfinding/navmesh/GatewayGraph.ts delete mode 100644 src/core/pathfinding/navmesh/NavMesh.ts create mode 100644 src/core/pathfinding/smoothing/BresenhamPathSmoother.ts create mode 100644 src/core/pathfinding/smoothing/PathSmoother.ts create mode 100644 src/core/pathfinding/smoothing/SmoothingTransformer.ts create mode 100644 src/core/pathfinding/spatial/SpatialQuery.ts create mode 100644 src/core/pathfinding/transformers/ComponentCheckTransformer.ts create mode 100644 src/core/pathfinding/transformers/MiniMapTransformer.ts create mode 100644 src/core/pathfinding/transformers/ShoreCoercingTransformer.ts create mode 100644 src/core/pathfinding/types.ts delete mode 100644 tests/core/pathfinding/PathFinder.test.ts create mode 100644 tests/core/pathfinding/PathFinderStepper.test.ts create mode 100644 tests/core/pathfinding/PathFinding.Air.test.ts create mode 100644 tests/core/pathfinding/PathFinding.Water.test.ts create mode 100644 tests/core/pathfinding/SpatialQuery.test.ts create mode 100644 tests/core/pathfinding/UniversalPathFinding.Parabola.test.ts create mode 100644 tests/core/pathfinding/WaterComponents.test.ts create mode 100644 tests/core/pathfinding/_fixtures.ts create mode 100644 tests/core/pathfinding/transformers/ComponentCheckTransformer.test.ts create mode 100644 tests/core/pathfinding/transformers/MiniMapTransformer.test.ts create mode 100644 tests/core/pathfinding/transformers/ShoreCoercingTransformer.test.ts create mode 100644 tests/pathfinding/benchmark/compare.ts delete mode 100644 tests/perf/AstarPerf.ts diff --git a/src/core/execution/BomberExecution.ts b/src/core/execution/BomberExecution.ts index e981e8cda..7df0c31fa 100644 --- a/src/core/execution/BomberExecution.ts +++ b/src/core/execution/BomberExecution.ts @@ -1,7 +1,7 @@ import type { Execution, Game, Player, Unit } from "../game/Game"; import { UnitType } from "../game/Game"; import type { TileRef } from "../game/GameMap"; -import { StraightPathFinder } from "../pathfinding/PathFinding"; +import { StraightPathFinder } from "../pathfinding/PathFinder.Straight"; import { roadEffectModifiers } from "../tech/TechEffects"; export class BomberExecution implements Execution { diff --git a/src/core/execution/CargoPlaneExecution.ts b/src/core/execution/CargoPlaneExecution.ts index 0ecb1c2ac..2b18bb839 100644 --- a/src/core/execution/CargoPlaneExecution.ts +++ b/src/core/execution/CargoPlaneExecution.ts @@ -8,7 +8,7 @@ import { UnitType, } from "../game/Game"; import { TileRef } from "../game/GameMap"; -import { StraightPathFinder } from "../pathfinding/PathFinding"; +import { StraightPathFinder } from "../pathfinding/PathFinder.Straight"; export class CargoPlaneExecution implements Execution { executionName = "CargoPlaneExecution"; diff --git a/src/core/execution/CityAABulletExecution.ts b/src/core/execution/CityAABulletExecution.ts index 11371fe2e..d1a5f54f3 100644 --- a/src/core/execution/CityAABulletExecution.ts +++ b/src/core/execution/CityAABulletExecution.ts @@ -1,6 +1,6 @@ import { Execution, Game, Player, Unit, UnitType } from "../game/Game"; import { TileRef } from "../game/GameMap"; -import { StraightPathFinder } from "../pathfinding/PathFinding"; +import { StraightPathFinder } from "../pathfinding/PathFinder.Straight"; /** * Execution for a single AA bullet fired from a city at an enemy plane. diff --git a/src/core/execution/FighterJetExecution.ts b/src/core/execution/FighterJetExecution.ts index e7c25997d..c75899453 100644 --- a/src/core/execution/FighterJetExecution.ts +++ b/src/core/execution/FighterJetExecution.ts @@ -9,7 +9,7 @@ import { import { GameImpl } from "../game/GameImpl"; import { TileRef } from "../game/GameMap"; -import { StraightPathFinder } from "../pathfinding/PathFinding"; +import { StraightPathFinder } from "../pathfinding/PathFinder.Straight"; import { PseudoRandom } from "../PseudoRandom"; import { ShellExecution } from "./ShellExecution"; diff --git a/src/core/execution/MIRVExecution.ts b/src/core/execution/MIRVExecution.ts index c0b576c7b..0c3938464 100644 --- a/src/core/execution/MIRVExecution.ts +++ b/src/core/execution/MIRVExecution.ts @@ -8,7 +8,9 @@ import { UnitType, } from "../game/Game"; import { TileRef } from "../game/GameMap"; -import { ParabolaPathFinder } from "../pathfinding/PathFinding"; +import { UniversalPathFinding } from "../pathfinding/PathFinder"; +import { ParabolaUniversalPathFinder } from "../pathfinding/PathFinder.Parabola"; +import { PathStatus } from "../pathfinding/types"; import { PseudoRandom } from "../PseudoRandom"; import { simpleHash } from "../Util"; import { NukeExecution } from "./NukeExecution"; @@ -26,11 +28,12 @@ export class MirvExecution implements Execution { private random: PseudoRandom; - private pathFinder: ParabolaPathFinder; + private pathFinder: ParabolaUniversalPathFinder; private targetPlayer: Player; private separateDst: TileRef; + private spawnTile: TileRef; private speed: number = -1; @@ -42,7 +45,6 @@ export class MirvExecution implements Execution { init(mg: Game, ticks: number): void { this.random = new PseudoRandom(mg.ticks() + simpleHash(this.player.id())); this.mg = mg; - this.pathFinder = new ParabolaPathFinder(mg); const target = this.mg.owner(this.dst); if (!target.isPlayer()) { console.warn(`cannot MIRV unowned land`); @@ -51,6 +53,9 @@ export class MirvExecution implements Execution { } this.targetPlayer = target as Player; this.speed = this.mg.config().defaultNukeSpeed(); + this.pathFinder = UniversalPathFinding.Parabola(mg, { + increment: this.speed, + }); // Record stats this.mg.stats().bombLaunch(this.player, this.targetPlayer, UnitType.MIRV); @@ -81,13 +86,15 @@ export class MirvExecution implements Execution { this.active = false; return; } - this.nuke = this.player.buildUnit(UnitType.MIRV, spawn, {}); + this.spawnTile = spawn; + this.nuke = this.player.buildUnit(UnitType.MIRV, spawn, { + targetTile: this.dst, + }); const x = Math.floor( (this.mg.x(this.dst) + this.mg.x(this.mg.x(this.nuke.tile()))) / 2, ); const y = Math.max(0, this.mg.y(this.dst) - 500) + 50; this.separateDst = this.mg.ref(x, y); - this.pathFinder.computeControlPoints(spawn, this.separateDst); this.mg.displayIncomingUnit( this.nuke.id(), @@ -98,15 +105,19 @@ export class MirvExecution implements Execution { ); } - const result = this.pathFinder.nextTile(this.speed); - if (result === true) { + const result = this.pathFinder.next( + this.spawnTile, + this.separateDst, + this.speed, + ); + if (result.status === PathStatus.COMPLETE) { this.separate(); this.active = false; // Record stats this.mg.stats().bombLand(this.player, this.targetPlayer, UnitType.MIRV); return; - } else { - this.nuke.move(result); + } else if (result.status === PathStatus.NEXT) { + this.nuke.move(result.node); } } diff --git a/src/core/execution/NukeExecution.ts b/src/core/execution/NukeExecution.ts index a9e47c9c7..968d3c605 100644 --- a/src/core/execution/NukeExecution.ts +++ b/src/core/execution/NukeExecution.ts @@ -10,7 +10,9 @@ import { UnitType, } from "../game/Game"; import { TileRef } from "../game/GameMap"; -import { ParabolaPathFinder } from "../pathfinding/PathFinding"; +import { UniversalPathFinding } from "../pathfinding/PathFinder"; +import { ParabolaUniversalPathFinder } from "../pathfinding/PathFinder.Parabola"; +import { PathStatus } from "../pathfinding/types"; import { PseudoRandom } from "../PseudoRandom"; import { NukeType } from "../StatsSchemas"; import { DoomsdayActivationExecution } from "./DoomsdayActivationExecution"; @@ -28,7 +30,7 @@ export class NukeExecution implements Execution { private nuke: Unit | null = null; private tilesToDestroyCache: Set | undefined; private eligibleCities: Unit[] = []; - private pathFinder: ParabolaPathFinder; + private pathFinder: ParabolaUniversalPathFinder; constructor( private nukeType: NukeType, @@ -44,7 +46,11 @@ export class NukeExecution implements Execution { if (this.speed === -1) { this.speed = this.mg.config().defaultNukeSpeed(); } - this.pathFinder = new ParabolaPathFinder(mg); + this.pathFinder = UniversalPathFinding.Parabola(mg, { + increment: this.speed, + distanceBasedHeight: this.nukeType !== UnitType.MIRVWarhead, + directionUp: this.nukeType !== UnitType.MIRVWarhead, + }); } public target(): Player | TerraNullius { @@ -109,12 +115,6 @@ export class NukeExecution implements Execution { return; } this.src = spawn; - this.pathFinder.computeControlPoints( - spawn, - this.dst, - this.speed, - this.nukeType !== UnitType.MIRVWarhead, - ); this.nuke = this.player.buildUnit(this.nukeType, spawn, { targetTile: this.dst, trajectory: this.getTrajectory(this.dst), @@ -186,13 +186,13 @@ export class NukeExecution implements Execution { } // Move to next tile - const nextTile = this.pathFinder.nextTile(this.speed); - if (nextTile === true) { + const result = this.pathFinder.next(this.src!, this.dst, this.speed); + if (result.status === PathStatus.COMPLETE) { this.detonate(); return; - } else { + } else if (result.status === PathStatus.NEXT) { this.updateNukeTargetable(); - this.nuke.move(nextTile); + this.nuke.move(result.node); // Update index so SAM can interpolate future position this.nuke.setTrajectoryIndex(this.pathFinder.currentIndex()); @@ -229,7 +229,7 @@ export class NukeExecution implements Execution { const trajectoryTiles: TrajectoryTile[] = []; const targetRangeSquared = this.mg.config().defaultNukeTargetableRange() ** 2; - const allTiles: TileRef[] = this.pathFinder.allTiles(); + const allTiles = this.pathFinder.findPath(this.src!, target) ?? []; for (const tile of allTiles) { trajectoryTiles.push({ tile, diff --git a/src/core/execution/ParatrooperAttackExecution.ts b/src/core/execution/ParatrooperAttackExecution.ts index c7c530507..0fd1f67d3 100644 --- a/src/core/execution/ParatrooperAttackExecution.ts +++ b/src/core/execution/ParatrooperAttackExecution.ts @@ -10,7 +10,7 @@ import { } from "../game/Game"; import { TerrainType, TileRef } from "../game/GameMap"; -import { StraightPathFinder } from "../pathfinding/PathFinding"; +import { StraightPathFinder } from "../pathfinding/PathFinder.Straight"; import { AttackExecution } from "./AttackExecution"; export class ParatrooperAttackExecution implements Execution { diff --git a/src/core/execution/SAMMissileExecution.ts b/src/core/execution/SAMMissileExecution.ts index 001ffc1d2..32448475d 100644 --- a/src/core/execution/SAMMissileExecution.ts +++ b/src/core/execution/SAMMissileExecution.ts @@ -7,14 +7,14 @@ import { UnitType, } from "../game/Game"; import { TileRef } from "../game/GameMap"; -import { AirPathFinder } from "../pathfinding/PathFinding"; -import { PseudoRandom } from "../PseudoRandom"; +import { PathFinding } from "../pathfinding/PathFinder"; +import { PathStatus, SteppingPathFinder } from "../pathfinding/types"; import { NukeType } from "../StatsSchemas"; export class SAMMissileExecution implements Execution { executionName = "SAMMissileExecution"; private active = true; - private pathFinder: AirPathFinder; + private pathFinder: SteppingPathFinder; private SAMMissile: Unit | undefined; private mg: Game; private speed: number = 0; @@ -28,7 +28,7 @@ export class SAMMissileExecution implements Execution { ) {} init(mg: Game, ticks: number): void { - this.pathFinder = new AirPathFinder(mg, new PseudoRandom(mg.ticks())); + this.pathFinder = PathFinding.Air(mg); this.mg = mg; this.speed = this.mg.config().defaultSamMissileSpeed(); } @@ -72,11 +72,11 @@ export class SAMMissileExecution implements Execution { } for (let i = 0; i < this.speed; i++) { - const result = this.pathFinder.nextTile( + const result = this.pathFinder.next( this.SAMMissile.tile(), this.targetTile, ); - if (result === true) { + if (result.status === PathStatus.COMPLETE) { if ( this.target.type() === UnitType.AtomBomb || this.target.type() === UnitType.HydrogenBomb @@ -96,8 +96,8 @@ export class SAMMissileExecution implements Execution { this.SAMMissile.delete(false); return; - } else { - this.SAMMissile.move(result); + } else if (result.status === PathStatus.NEXT) { + this.SAMMissile.move(result.node); } } } diff --git a/src/core/execution/ShellExecution.ts b/src/core/execution/ShellExecution.ts index 84248d201..4035b838e 100644 --- a/src/core/execution/ShellExecution.ts +++ b/src/core/execution/ShellExecution.ts @@ -1,12 +1,13 @@ import { Execution, Game, Player, Unit, UnitType } from "../game/Game"; import { TileRef } from "../game/GameMap"; -import { AirPathFinder } from "../pathfinding/PathFinding"; +import { PathFinding } from "../pathfinding/PathFinder"; +import { PathStatus, SteppingPathFinder } from "../pathfinding/types"; import { PseudoRandom } from "../PseudoRandom"; export class ShellExecution implements Execution { executionName = "ShellExecution"; private active = true; - private pathFinder: AirPathFinder; + private pathFinder: SteppingPathFinder; private shell: Unit | undefined; private mg: Game; private destroyAtTick: number = -1; @@ -20,7 +21,7 @@ export class ShellExecution implements Execution { ) {} init(mg: Game, ticks: number): void { - this.pathFinder = new AirPathFinder(mg, new PseudoRandom(mg.ticks())); + this.pathFinder = PathFinding.Air(mg); this.mg = mg; this.random = new PseudoRandom(mg.ticks()); } @@ -53,11 +54,11 @@ export class ShellExecution implements Execution { } for (let i = 0; i < bulletSpeed; i++) { - const result = this.pathFinder.nextTile( + const result = this.pathFinder.next( this.shell.tile(), this.target.tile(), ); - if (result === true) { + if (result.status === PathStatus.COMPLETE) { this.active = false; // Don't damage bombers that have landed at their airfield if (!this.target.isAtSourceAirfield()) { @@ -74,8 +75,8 @@ export class ShellExecution implements Execution { this.shell.setReachedTarget(); this.shell.delete(false); return; - } else { - this.shell.move(result); + } else if (result.status === PathStatus.NEXT) { + this.shell.move(result.node); } } } diff --git a/src/core/execution/SubmarineExecution.ts b/src/core/execution/SubmarineExecution.ts index 070c20dd5..d28e998f8 100644 --- a/src/core/execution/SubmarineExecution.ts +++ b/src/core/execution/SubmarineExecution.ts @@ -7,10 +7,9 @@ import { UnitParams, UnitType, } from "../game/Game"; -import { GameImpl } from "../game/GameImpl"; import { TileRef } from "../game/GameMap"; -import { PathFindResultType } from "../pathfinding/AStar"; -import { MiniPathFinder } from "../pathfinding/PathFinding"; +import { PathFinding } from "../pathfinding/PathFinder"; +import { PathStatus, SteppingPathFinder } from "../pathfinding/types"; import { PseudoRandom } from "../PseudoRandom"; import { ShellExecution } from "./ShellExecution"; @@ -18,8 +17,8 @@ export class SubmarineExecution implements Execution { executionName = "SubmarineExecution"; private random: PseudoRandom; private submarine: Unit; - private mg: GameImpl; - private pathfinder: MiniPathFinder; + private mg: Game; + private pathfinder: SteppingPathFinder; private lastShellAttack = 0; private alreadySentShell = new Set(); @@ -39,8 +38,8 @@ export class SubmarineExecution implements Execution { ) {} init(mg: Game, ticks: number): void { - this.mg = mg as GameImpl; - this.pathfinder = new MiniPathFinder(mg, 10_000, true, 100); + this.mg = mg; + this.pathfinder = PathFinding.Water(mg); this.random = new PseudoRandom(mg.ticks()); if (isUnit(this.input)) { this.submarine = this.input; @@ -299,22 +298,22 @@ export class SubmarineExecution implements Execution { } } - const result = this.pathfinder.nextTile( + const result = this.pathfinder.next( this.submarine.tile(), this.submarine.targetTile()!, ); - switch (result.type) { - case PathFindResultType.Completed: + switch (result.status) { + case PathStatus.COMPLETE: this.submarine.setTargetTile(undefined); this.submarine.move(result.node); break; - case PathFindResultType.NextTile: + case PathStatus.NEXT: this.submarine.move(result.node); break; - case PathFindResultType.Pending: + case PathStatus.PENDING: this.submarine.touch(); return; - case PathFindResultType.PathNotFound: + case PathStatus.NOT_FOUND: console.warn(`path not found to target tile`); this.submarine.setTargetTile(undefined); break; diff --git a/src/core/execution/TradeManagerExecution.ts b/src/core/execution/TradeManagerExecution.ts index 6b249ff8e..42ac3c646 100644 --- a/src/core/execution/TradeManagerExecution.ts +++ b/src/core/execution/TradeManagerExecution.ts @@ -11,8 +11,8 @@ import { UpgradeType, } from "../game/Game"; import { TileRef } from "../game/GameMap"; -import { PathFindResultType } from "../pathfinding/AStar"; -import { MiniPathFinder } from "../pathfinding/PathFinding"; +import { PathFinding } from "../pathfinding/PathFinder"; +import { PathStatus, SteppingPathFinder } from "../pathfinding/types"; import { PseudoRandom } from "../PseudoRandom"; import { roadEffectModifiers, tradeIncomeModifiers } from "../tech/TechEffects"; @@ -693,7 +693,7 @@ export class TradeManagerExecution implements Execution { export class AssignedTradeRouteExecution implements Execution { private mg!: Game; - private path!: MiniPathFinder; + private path!: SteppingPathFinder; private active = true; private phase: "toStart" | "toEnd" = "toStart"; private lastMoveTick = 0; @@ -708,7 +708,7 @@ export class AssignedTradeRouteExecution implements Execution { init(mg: Game, ticks: number): void { this.mg = mg; - this.path = new MiniPathFinder(mg, 30000, true, 100); + this.path = PathFinding.Water(mg); this.lastMoveTick = ticks; // Ensure ship is not in a stale 'returning' state from a prior turnaround this.ship.setReturning(false); @@ -1050,18 +1050,18 @@ export class AssignedTradeRouteExecution implements Execution { return; } - const res = this.path.nextTile(this.ship.tile(), navTarget); - switch (res.type) { - case PathFindResultType.Completed: + const res = this.path.next(this.ship.tile(), navTarget); + switch (res.status) { + case PathStatus.COMPLETE: this.ship.move(navTarget); // silent per-tick break; - case PathFindResultType.Pending: + case PathStatus.PENDING: this.ship.move(this.ship.tile()); // no movement break; - case PathFindResultType.NextTile: + case PathStatus.NEXT: this.ship.move(res.node); // silent step break; - case PathFindResultType.PathNotFound: + case PathStatus.NOT_FOUND: // Path cannot be found; try another port of the same owner before giving up if (!this.ship.returning()) { if (this.phase === "toEnd") { diff --git a/src/core/execution/TradeShipExecution.ts b/src/core/execution/TradeShipExecution.ts index f1230c6f4..334f2dca4 100644 --- a/src/core/execution/TradeShipExecution.ts +++ b/src/core/execution/TradeShipExecution.ts @@ -8,7 +8,8 @@ import { UnitType, } from "../game/Game"; import { TileRef } from "../game/GameMap"; -import { PathFinder, PathFinders, PathStatus } from "../pathfinding/PathFinder"; +import { PathFinding } from "../pathfinding/PathFinder"; +import { PathStatus, SteppingPathFinder } from "../pathfinding/types"; import { distSortUnit } from "../Util"; export class TradeShipExecution implements Execution { @@ -16,7 +17,7 @@ export class TradeShipExecution implements Execution { private mg: Game; private tradeShip: Unit | undefined; private wasCaptured = false; - private pathFinder: PathFinder; + private pathFinder: SteppingPathFinder; private tilesTraveled = 0; constructor( @@ -27,7 +28,7 @@ export class TradeShipExecution implements Execution { init(mg: Game, ticks: number): void { this.mg = mg; - this.pathFinder = PathFinders.Water(mg); + this.pathFinder = PathFinding.Water(mg); } tick(ticks: number): void { diff --git a/src/core/execution/TransportShipExecution.ts b/src/core/execution/TransportShipExecution.ts index 3c6cc73f3..6b5403a99 100644 --- a/src/core/execution/TransportShipExecution.ts +++ b/src/core/execution/TransportShipExecution.ts @@ -11,7 +11,8 @@ import { } from "../game/Game"; import { TileRef } from "../game/GameMap"; import { targetTransportTile } from "../game/TransportShipUtils"; -import { PathFinder, PathFinders, PathStatus } from "../pathfinding/PathFinder"; +import { PathFinding } from "../pathfinding/PathFinder"; +import { PathStatus, SteppingPathFinder } from "../pathfinding/types"; import { AttackExecution } from "./AttackExecution"; export class TransportShipExecution implements Execution { @@ -32,7 +33,7 @@ export class TransportShipExecution implements Execution { private boat: Unit; - private pathFinder: PathFinder; + private pathFinder: SteppingPathFinder; constructor( private attacker: Player, @@ -78,7 +79,7 @@ export class TransportShipExecution implements Execution { this.lastMove = ticks; this.mg = mg; - this.pathFinder = PathFinders.Water(mg); + this.pathFinder = PathFinding.Water(mg); if ( this.attacker.unitCount(UnitType.TransportShip) >= @@ -149,6 +150,12 @@ export class TransportShipExecution implements Execution { // Track intended target player on the boat for selective cancellation on peace (this.boat as any).setBoatTargetPlayerID?.(this.targetID); + if (this.dst !== null) { + this.boat.setTargetTile(this.dst); + } else { + this.boat.setTargetTile(undefined); + } + // Notify the target player about the incoming naval invasion if (this.targetID && this.targetID !== mg.terraNullius().id()) { mg.displayIncomingUnit( @@ -184,7 +191,32 @@ export class TransportShipExecution implements Execution { this.lastMove = ticks; if (this.boat.retreating()) { - this.dst = this.src!; // src is guaranteed to be set at this point + // Ensure retreat source is still valid for (new) owner + if (this.mg.owner(this.src!) !== this.attacker) { + // Use bestTransportShipSpawn, not canBuild because of its max boats check etc + const newSrc = this.attacker.bestTransportShipSpawn(this.dst); + if (newSrc === false) { + this.src = null; + } else { + this.src = newSrc; + } + } + + if (this.src === null) { + console.warn( + `TransportShipExecution: retreating but no src found for new attacker`, + ); + this.attacker.addTroops(this.boat.troops()); + this.boat.delete(false); + this.active = false; + return; + } else { + this.dst = this.src; + + if (this.boat.targetTile() !== this.dst) { + this.boat.setTargetTile(this.dst); + } + } } const result = this.pathFinder.next(this.boat.tile(), this.dst); @@ -228,13 +260,18 @@ export class TransportShipExecution implements Execution { break; case PathStatus.PENDING: break; - case PathStatus.NOT_FOUND: + case PathStatus.NOT_FOUND: { // TODO: add to poisoned port list - console.warn(`path not found to dst`); + const map = this.mg.map(); + const boatTile = this.boat.tile(); + console.warn( + `TransportShip path not found: boat@(${map.x(boatTile)},${map.y(boatTile)}) -> dst@(${map.x(this.dst)},${map.y(this.dst)}), attacker=${this.attacker.id()}, target=${this.targetID}`, + ); this.attacker.addTroops(this.boat.troops()); this.boat.delete(false); this.active = false; return; + } } } diff --git a/src/core/execution/WarshipExecution.ts b/src/core/execution/WarshipExecution.ts index 120a75e50..e63d89ca7 100644 --- a/src/core/execution/WarshipExecution.ts +++ b/src/core/execution/WarshipExecution.ts @@ -10,9 +10,8 @@ import { UpgradeType, } from "../game/Game"; import { TileRef } from "../game/GameMap"; -import { PathFindResultType } from "../pathfinding/AStar"; -import { PathFinder, PathFinders, PathStatus } from "../pathfinding/PathFinder"; -import { MiniPathFinder } from "../pathfinding/PathFinding"; +import { PathFinding } from "../pathfinding/PathFinder"; +import { PathStatus, SteppingPathFinder } from "../pathfinding/types"; import { PseudoRandom } from "../PseudoRandom"; import { SAMMissileExecution } from "./SAMMissileExecution"; import { ShellExecution } from "./ShellExecution"; @@ -22,7 +21,7 @@ export class WarshipExecution implements Execution { private random: PseudoRandom; private warship: Unit; private mg: Game; - private pathfinder: PathFinder; + private pathfinder: SteppingPathFinder; private lastShellAttack = 0; private alreadySentShell = new Set(); private nextAAScanTick = 0; @@ -41,7 +40,7 @@ export class WarshipExecution implements Execution { init(mg: Game, ticks: number): void { this.mg = mg; - this.pathfinder = PathFinders.Water(mg); + this.pathfinder = PathFinding.Water(mg); this.random = new PseudoRandom(mg.ticks()); if (isUnit(this.input)) { this.warship = this.input; @@ -380,9 +379,10 @@ export class WarshipExecution implements Execution { case PathStatus.PENDING: this.warship.touch(); break; - case PathStatus.NOT_FOUND: + case PathStatus.NOT_FOUND: { console.log(`path not found to target`); break; + } } } } @@ -410,10 +410,10 @@ export class WarshipExecution implements Execution { case PathStatus.PENDING: this.warship.touch(); return; - case PathStatus.NOT_FOUND: - console.warn(`path not found to target tile`); - this.warship.setTargetTile(undefined); + case PathStatus.NOT_FOUND: { + console.log(`path not found to target`); break; + } } } @@ -430,6 +430,10 @@ export class WarshipExecution implements Execution { const maxAttemptBeforeExpand: number = 500; let attempts: number = 0; let expandCount: number = 0; + + // Get warship's water component for connectivity check + const warshipComponent = this.mg.getWaterComponent(this.warship.tile()); + while (expandCount < 3) { const x = this.mg.x(this.warship.patrolTile()!) + @@ -454,6 +458,20 @@ export class WarshipExecution implements Execution { } continue; } + // Check water component connectivity + if ( + warshipComponent !== null && + !this.mg.hasWaterComponent(tile, warshipComponent) + ) { + attempts++; + if (attempts === maxAttemptBeforeExpand) { + expandCount++; + attempts = 0; + warshipPatrolRange = + warshipPatrolRange + Math.floor(warshipPatrolRange / 2); + } + continue; + } return tile; } console.warn( @@ -570,147 +588,3 @@ export class WarshipExecution implements Execution { return this.mg.owner(targetTile) === this.warship.owner(); } } - -class CapturedTradeShipReturnExecution implements Execution { - executionName = "CapturedTradeShipReturnExecution"; - private mg!: Game; - private pathfinder!: MiniPathFinder; - private active = true; - private lastMoveTick = 0; - private destPort: Unit | null = null; - - constructor(private ship: Unit) {} - - init(mg: Game, ticks: number): void { - this.mg = mg; - this.pathfinder = new MiniPathFinder(mg, 2500, true, 100); - this.lastMoveTick = ticks; - // Pick nearest active port owned by the ship's owner - this.destPort = this.selectNearestPort(this.ship.owner()); - if (this.destPort) { - this.ship.setTargetUnit(this.destPort); - } else { - // No port to return to; cancel - this.active = false; - } - } - - isActive(): boolean { - return this.active; - } - - activeDuringSpawnPhase(): boolean { - return false; - } - - tick(ticks: number): void { - if (!this.active) return; - if (!this.ship.isActive()) { - this.active = false; - return; - } - if (!this.destPort || !this.destPort.isActive()) { - // Destination no longer valid; try to pick another - this.destPort = this.selectNearestPort(this.ship.owner()); - if (!this.destPort) { - this.active = false; - return; - } - this.ship.setTargetUnit(this.destPort); - } - - if (ticks - this.lastMoveTick < 1) return; - this.lastMoveTick = ticks; - - const targetTile = this.destPort.tile(); - if (this.mg.manhattanDist(this.ship.tile(), targetTile) === 1) { - // Dock - this.ship.move(targetTile); - const cargo = this.ship.cargoGold(); - if (cargo > 0n) { - this.ship.owner().addGold(cargo); - this.ship.setCargoGold(0n); - } - this.ship.setTargetUnit(undefined); - this.active = false; - return; - } - - const navTarget = this.navTargetForPort(targetTile); - if (navTarget === null) { - this.active = false; - return; - } - - // If on land (port tile), step into adjacent ocean first - if (!this.mg.isOcean(this.ship.tile())) { - const step = this.stepIntoOceanTowards(navTarget); - if (step !== null) { - this.ship.move(step); - return; - } - this.active = false; - return; - } - - const res = this.pathfinder.nextTile(this.ship.tile(), navTarget); - switch (res.type) { - case PathFindResultType.Completed: - this.ship.move(navTarget); - break; - case PathFindResultType.NextTile: - this.ship.move(res.node); - break; - case PathFindResultType.Pending: - this.ship.touch(); - break; - case PathFindResultType.PathNotFound: - this.active = false; - break; - } - } - - private selectNearestPort(owner: Player): Unit | null { - const ports = this.mg - .units(UnitType.Port) - .filter((p) => p.owner() === owner && p.isActive()); - if (ports.length === 0) return null; - let best: Unit | null = null; - let bestDist = Number.POSITIVE_INFINITY; - for (const p of ports) { - const d = this.mg.euclideanDistSquared(this.ship.tile(), p.tile()); - if (d < bestDist) { - bestDist = d; - best = p; - } - } - return best; - } - - private navTargetForPort(portTile: TileRef): TileRef | null { - if (this.mg.isOcean(portTile)) return portTile; - const candidates = this.mg - .neighbors(portTile) - .filter((t) => this.mg.isOcean(t)); - if (candidates.length === 0) return null; - candidates.sort( - (a, b) => - this.mg.manhattanDist(this.ship.tile(), a) - - this.mg.manhattanDist(this.ship.tile(), b), - ); - return candidates[0]; - } - - private stepIntoOceanTowards(navTarget: TileRef): TileRef | null { - const oceanNeighbors = this.mg - .neighbors(this.ship.tile()) - .filter((t) => this.mg.isOcean(t)); - if (oceanNeighbors.length === 0) return null; - oceanNeighbors.sort( - (a, b) => - this.mg.manhattanDist(a, navTarget) - - this.mg.manhattanDist(b, navTarget), - ); - return oceanNeighbors[0]; - } -} diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index 01b11c95f..76caec2f8 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -1,5 +1,6 @@ import { Config } from "../configuration/Config"; -import { NavMesh } from "../pathfinding/navmesh/NavMesh"; +import { AbstractGraph } from "../pathfinding/algorithms/AbstractGraph"; +import { PathFinder } from "../pathfinding/types"; import { AllPlayersStats, ClientID } from "../Schemas"; import { Category } from "../tech/ResearchTree"; import { Cell, GameMap, MapPos, TerrainType, TileRef } from "./GameMap"; @@ -284,7 +285,9 @@ export interface UnitParamsMap { [UnitType.City]: Record; - [UnitType.MIRV]: Record; + [UnitType.MIRV]: { + targetTile?: number; + }; [UnitType.Hospital]: Record; @@ -882,7 +885,10 @@ export interface Game extends GameMap { conquer(newOwner: Player, tile: TileRef): void; addUpdate(update: GameUpdate): void; - navMesh(): NavMesh | null; + miniWaterHPA(): PathFinder | null; + miniWaterGraph(): AbstractGraph | null; + getWaterComponent(tile: TileRef): number | null; + hasWaterComponent(tile: TileRef, component: number): boolean; } export interface PlayerActions { diff --git a/src/core/game/GameImpl.ts b/src/core/game/GameImpl.ts index 20e810572..02528831b 100644 --- a/src/core/game/GameImpl.ts +++ b/src/core/game/GameImpl.ts @@ -1,6 +1,11 @@ import { Config } from "../configuration/Config"; import { AttackExecution } from "../execution/AttackExecution"; -import { NavMesh } from "../pathfinding/navmesh/NavMesh"; +import { + AbstractGraph, + AbstractGraphBuilder, +} from "../pathfinding/algorithms/AbstractGraph"; +import { AStarWaterHierarchical } from "../pathfinding/algorithms/AStar.WaterHierarchical"; +import { PathFinder } from "../pathfinding/types"; import { AllPlayersStats, ClientID, Winner } from "../Schemas"; import { simpleHash } from "../Util"; import { AllianceImpl } from "./AllianceImpl"; @@ -92,7 +97,8 @@ export class GameImpl implements Game { private botTeam: Team = ColoredTeams.Bot; private _isPaused: boolean = false; - private _navMesh: NavMesh | null = null; + private _miniWaterGraph: AbstractGraph | null = null; + private _miniWaterHPA: AStarWaterHierarchical | null = null; constructor( private _humans: PlayerInfo[], @@ -124,8 +130,14 @@ export class GameImpl implements Game { this.addPlayers(); if (!_config.disableNavMesh()) { - this._navMesh = new NavMesh(this, { cachePaths: true }); - this._navMesh.initialize(); + const graphBuilder = new AbstractGraphBuilder(this.miniGameMap); + this._miniWaterGraph = graphBuilder.build(); + + this._miniWaterHPA = new AStarWaterHierarchical( + this.miniGameMap, + this._miniWaterGraph, + { cachePaths: true }, + ); } } @@ -1223,8 +1235,79 @@ export class GameImpl implements Game { public alliances(): AllianceImpl[] { return this.alliances_; } - navMesh(): NavMesh | null { - return this._navMesh; + miniWaterHPA(): PathFinder | null { + return this._miniWaterHPA; + } + miniWaterGraph(): AbstractGraph | null { + return this._miniWaterGraph; + } + getWaterComponent(tile: TileRef): number | null { + // Permissive fallback for tests with disableNavMesh + if (!this._miniWaterGraph) return 0; + + const miniX = Math.floor(this._map.x(tile) / 2); + const miniY = Math.floor(this._map.y(tile) / 2); + const miniTile = this.miniGameMap.ref(miniX, miniY); + + if (this.miniGameMap.isWater(miniTile)) { + return this._miniWaterGraph.getComponentId(miniTile); + } + + // Shore tile: find water neighbor (expand search for minimap resolution loss) + for (const n of this.miniGameMap.neighbors(miniTile)) { + if (this.miniGameMap.isWater(n)) { + return this._miniWaterGraph.getComponentId(n); + } + } + + // Extended search: check 2-hop neighbors for narrow straits + for (const n of this.miniGameMap.neighbors(miniTile)) { + for (const n2 of this.miniGameMap.neighbors(n)) { + if (this.miniGameMap.isWater(n2)) { + return this._miniWaterGraph.getComponentId(n2); + } + } + } + return null; + } + hasWaterComponent(tile: TileRef, component: number): boolean { + // Permissive fallback for tests with disableNavMesh + if (!this._miniWaterGraph) return true; + + const miniX = Math.floor(this._map.x(tile) / 2); + const miniY = Math.floor(this._map.y(tile) / 2); + const miniTile = this.miniGameMap.ref(miniX, miniY); + + // Check miniTile itself (shore in full map may be water in minimap) + if ( + this.miniGameMap.isWater(miniTile) && + this._miniWaterGraph.getComponentId(miniTile) === component + ) { + return true; + } + + // Check neighbors + for (const n of this.miniGameMap.neighbors(miniTile)) { + if ( + this.miniGameMap.isWater(n) && + this._miniWaterGraph.getComponentId(n) === component + ) { + return true; + } + } + + // Extended search: check 2-hop neighbors for narrow straits + for (const n of this.miniGameMap.neighbors(miniTile)) { + for (const n2 of this.miniGameMap.neighbors(n)) { + if ( + this.miniGameMap.isWater(n2) && + this._miniWaterGraph.getComponentId(n2) === component + ) { + return true; + } + } + } + return false; } public hasRoadOnTile(tile: TileRef): boolean { diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts index 56548a145..d017e14c6 100644 --- a/src/core/game/PlayerImpl.ts +++ b/src/core/game/PlayerImpl.ts @@ -1872,7 +1872,7 @@ export class PlayerImpl implements Player { } bestTransportShipSpawn(targetTile: TileRef): TileRef | false { - return bestShoreDeploymentSource(this.mg, this, targetTile); + return bestShoreDeploymentSource(this.mg, this, targetTile) ?? false; } // It's a probability list, so if an element appears twice it's because it's diff --git a/src/core/game/TransportShipUtils.ts b/src/core/game/TransportShipUtils.ts index b457ad94a..ec8ba7109 100644 --- a/src/core/game/TransportShipUtils.ts +++ b/src/core/game/TransportShipUtils.ts @@ -1,7 +1,6 @@ -import { PathFindResultType } from "../pathfinding/AStar"; -import { MiniAStar } from "../pathfinding/MiniAStar"; +import { SpatialQuery } from "../pathfinding/spatial/SpatialQuery"; import { Game, Player, UnitType } from "./Game"; -import { andFN, GameMap, manhattanDistFN, TileRef } from "./GameMap"; +import { TileRef } from "./GameMap"; export function canBuildTransportShip( game: Game, @@ -27,234 +26,20 @@ export function canBuildTransportShip( return false; } - if (game.isOceanShore(dst)) { - let myPlayerBordersOcean = false; - for (const bt of player.borderTiles()) { - if (game.isOceanShore(bt)) { - myPlayerBordersOcean = true; - break; - } - } - - let otherPlayerBordersOcean = false; - if (!game.hasOwner(tile)) { - otherPlayerBordersOcean = true; - } else { - for (const bt of (other as Player).borderTiles()) { - if (game.isOceanShore(bt)) { - otherPlayerBordersOcean = true; - break; - } - } - } - - if (myPlayerBordersOcean && otherPlayerBordersOcean) { - return transportShipSpawn(game, player, dst); - } else { - return false; - } - } - - // Now we are boating in a lake, so do a bfs from target until we find - // a border tile owned by the player - - const tiles = game.bfs( - dst, - andFN( - manhattanDistFN(dst, 300), - (_, t: TileRef) => game.isLake(t) || game.isShore(t), - ), - ); - - const sorted = Array.from(tiles).sort( - (a, b) => game.manhattanDist(dst, a) - game.manhattanDist(dst, b), - ); - - for (const t of sorted) { - if (game.owner(t) === player) { - return transportShipSpawn(game, player, t); - } - } - return false; -} - -function transportShipSpawn( - game: Game, - player: Player, - targetTile: TileRef, -): TileRef | false { - if (!game.isShore(targetTile)) { - return false; - } - const spawn = closestShoreFromPlayer(game, player, targetTile); - if (spawn === null) { - return false; - } - return spawn; -} - -export function sourceDstOceanShore( - gm: Game, - src: Player, - tile: TileRef, -): [TileRef | null, TileRef | null] { - const dst = gm.owner(tile); - const srcTile = closestShoreFromPlayer(gm, src, tile); - let dstTile: TileRef | null = null; - if (dst.isPlayer()) { - dstTile = closestShoreFromPlayer(gm, dst as Player, tile); - } else { - dstTile = closestShoreTN(gm, tile, 50); - } - return [srcTile, dstTile]; + const spatial = new SpatialQuery(game); + return spatial.closestShoreByWater(player, dst) ?? false; } export function targetTransportTile(gm: Game, tile: TileRef): TileRef | null { - const dst = gm.playerBySmallID(gm.ownerID(tile)); - let dstTile: TileRef | null = null; - if (dst.isPlayer()) { - dstTile = closestShoreFromPlayer(gm, dst as Player, tile); - } else { - dstTile = closestShoreTN(gm, tile, 50); - } - return dstTile; -} - -export function closestShoreFromPlayer( - gm: GameMap, - player: Player, - target: TileRef, -): TileRef | null { - const shoreTiles = Array.from(player.borderTiles()).filter((t) => - gm.isShore(t), - ); - if (shoreTiles.length === 0) { - return null; - } - - return shoreTiles.reduce((closest, current) => { - const closestDistance = gm.manhattanDist(target, closest); - const currentDistance = gm.manhattanDist(target, current); - return currentDistance < closestDistance ? current : closest; - }); + const spatial = new SpatialQuery(gm); + return spatial.closestShore(gm.owner(tile), tile); } export function bestShoreDeploymentSource( gm: Game, player: Player, - target: TileRef, -): TileRef | false { - const t = targetTransportTile(gm, target); - if (t === null) return false; - - const candidates = candidateShoreTiles(gm, player, t); - const aStar = new MiniAStar(gm, gm.miniMap(), candidates, t, 1_000_000, 1); - const result = aStar.compute(); - if (result !== PathFindResultType.Completed) { - console.warn(`bestShoreDeploymentSource: path not found: ${result}`); - return false; - } - const path = aStar.reconstructPath(); - if (path.length === 0) { - return false; - } - const potential = path[0]; - // Since mini a* downscales the map, we need to check the neighbors - // of the potential tile to find a valid deployment point - const neighbors = gm - .neighbors(potential) - .filter((n) => gm.isShore(n) && gm.owner(n) === player); - if (neighbors.length === 0) { - return false; - } - return neighbors[0]; -} - -export function candidateShoreTiles( - gm: Game, - player: Player, - target: TileRef, -): TileRef[] { - let closestManhattanDistance = Infinity; - let minX = Infinity, - minY = Infinity, - maxX = -Infinity, - maxY = -Infinity; - - let bestByManhattan: TileRef | null = null; - const extremumTiles: Record = { - minX: null, - minY: null, - maxX: null, - maxY: null, - }; - - const borderShoreTiles = Array.from(player.borderTiles()).filter((t) => - gm.isShore(t), - ); - - for (const tile of borderShoreTiles) { - const distance = gm.manhattanDist(tile, target); - const cell = gm.cell(tile); - - // Manhattan-closest tile - if (distance < closestManhattanDistance) { - closestManhattanDistance = distance; - bestByManhattan = tile; - } - - // Extremum tiles - if (cell.x < minX) { - minX = cell.x; - extremumTiles.minX = tile; - } else if (cell.y < minY) { - minY = cell.y; - extremumTiles.minY = tile; - } else if (cell.x > maxX) { - maxX = cell.x; - extremumTiles.maxX = tile; - } else if (cell.y > maxY) { - maxY = cell.y; - extremumTiles.maxY = tile; - } - } - - // Calculate sampling interval to ensure we get at most 50 tiles - const samplingInterval = Math.max( - 10, - Math.ceil(borderShoreTiles.length / 50), - ); - const sampledTiles = borderShoreTiles.filter( - (_, index) => index % samplingInterval === 0, - ); - - const candidates = [ - bestByManhattan, - extremumTiles.minX, - extremumTiles.minY, - extremumTiles.maxX, - extremumTiles.maxY, - ...sampledTiles, - ].filter(Boolean) as number[]; - - return candidates; -} - -function closestShoreTN( - gm: GameMap, - tile: TileRef, - searchDist: number, + dst: TileRef, ): TileRef | null { - const tn = Array.from( - gm.bfs( - tile, - andFN((_, t) => !gm.hasOwner(t), manhattanDistFN(tile, searchDist)), - ), - ) - .filter((t) => gm.isShore(t)) - .sort((a, b) => gm.manhattanDist(tile, a) - gm.manhattanDist(tile, b)); - if (tn.length === 0) { - return null; - } - return tn[0]; + const spatial = new SpatialQuery(gm); + return spatial.closestShoreByWater(player, dst); } diff --git a/src/core/pathfinding/AStar.ts b/src/core/pathfinding/AStar.ts deleted file mode 100644 index f16accf4e..000000000 --- a/src/core/pathfinding/AStar.ts +++ /dev/null @@ -1,31 +0,0 @@ -export interface AStar { - compute(): PathFindResultType; - reconstructPath(): NodeType[]; -} - -export enum PathFindResultType { - NextTile, - Pending, - Completed, - PathNotFound, -} -export type AStarResult = - | { - type: PathFindResultType.NextTile; - node: NodeType; - } - | { - type: PathFindResultType.Pending; - } - | { - type: PathFindResultType.Completed; - node: NodeType; - } - | { - type: PathFindResultType.PathNotFound; - }; - -export interface Point { - x: number; - y: number; -} diff --git a/src/core/pathfinding/MiniAStar.ts b/src/core/pathfinding/MiniAStar.ts deleted file mode 100644 index 0573c31a7..000000000 --- a/src/core/pathfinding/MiniAStar.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { Cell, GameMap, TerrainType, TileRef } from "../game/GameMap"; -import { AStar, PathFindResultType } from "./AStar"; -import { GraphAdapter, SerialAStar } from "./SerialAStar"; - -export class GameMapAdapter implements GraphAdapter { - constructor( - private gameMap: GameMap, - private waterPath: boolean, - ) {} - - neighbors(node: TileRef): Iterable { - return this.gameMap.neighbors(node); - } - - cost(node: TileRef): number { - return this.gameMap.cost(node); - } - - position(node: TileRef): { x: number; y: number } { - return { x: this.gameMap.x(node), y: this.gameMap.y(node) }; - } - - isTraversable(from: TileRef, to: TileRef): boolean { - const isWater = this.gameMap.isWater(to); - if (this.gameMap.terrainType(to) === TerrainType.Barrier) { - return false; - } - return this.waterPath ? isWater : !isWater; - } -} -export class MiniAStar implements AStar { - private aStar: AStar; - - constructor( - private gameMap: GameMap, - private miniMap: GameMap, - private src: TileRef | TileRef[], - private dst: TileRef, - iterations: number, - maxTries: number, - waterPath: boolean = true, - directionChangePenalty: number = 0, - ) { - const srcArray: TileRef[] = Array.isArray(src) ? src : [src]; - const miniSrc = srcArray.map((srcPoint) => - this.miniMap.ref( - Math.floor(gameMap.x(srcPoint) / 2), - Math.floor(gameMap.y(srcPoint) / 2), - ), - ); - - const miniDst = this.miniMap.ref( - Math.floor(gameMap.x(dst) / 2), - Math.floor(gameMap.y(dst) / 2), - ); - - this.aStar = new SerialAStar( - miniSrc, - miniDst, - iterations, - maxTries, - new GameMapAdapter(miniMap, waterPath), - directionChangePenalty, - ); - } - - compute(): PathFindResultType { - return this.aStar.compute(); - } - - reconstructPath(): TileRef[] { - // Build start and destination cells at full resolution - let cellSrc: Cell | undefined; - if (!Array.isArray(this.src)) { - cellSrc = new Cell(this.gameMap.x(this.src), this.gameMap.y(this.src)); - } - const cellDst = new Cell( - this.gameMap.x(this.dst), - this.gameMap.y(this.dst), - ); - - // Get path in mini-map coords, upscale to full grid coordinates - const coarseCells = this.aStar - .reconstructPath() - .map((tr) => new Cell(this.miniMap.x(tr), this.miniMap.y(tr))); - const upscaled = fixExtremes(upscalePath(coarseCells), cellDst, cellSrc); - - // Convert to an orthogonal, water-preferred path on the full grid - const waterOrthogonal: Cell[] = []; - if (upscaled.length > 0) { - let curr = upscaled[0]; - waterOrthogonal.push(curr); - for (let i = 1; i < upscaled.length; i++) { - const target = upscaled[i]; - while (curr.x !== target.x || curr.y !== target.y) { - const stepX = Math.sign(target.x - curr.x); - const stepY = Math.sign(target.y - curr.y); - const candidates: Cell[] = []; - if (stepX !== 0) candidates.push(new Cell(curr.x + stepX, curr.y)); - if (stepY !== 0) candidates.push(new Cell(curr.x, curr.y + stepY)); - - // Prefer candidates that are water and reduce manhattan distance - let best: Cell | null = null; - let bestScore = Number.POSITIVE_INFINITY; - for (const cand of candidates) { - const ref = this.gameMap.ref(cand.x, cand.y); - const isWater = this.gameMap.isWater(ref); - const dist = - Math.abs(target.x - cand.x) + Math.abs(target.y - cand.y); - const score = (isWater ? 0 : 1000) + dist; // strong preference for water - if (score < bestScore) { - best = cand; - bestScore = score; - } - } - // If no candidates (shouldn't happen), break to avoid infinite loop - if (best === null) break; - curr = best; - waterOrthogonal.push(curr); - } - } - } - - // Remove any residual non-water cells if present (belt-and-suspenders) - let finalCells = waterOrthogonal.filter((c) => - this.gameMap.isWater(this.gameMap.ref(c.x, c.y)), - ); - - // Robustness: ensure path includes src and dst and has at least 2 cells - const srcCell = cellSrc ?? (upscaled.length > 0 ? upscaled[0] : undefined); - if (finalCells.length === 0) { - // Fallback to upscaled (pre-orthogonal) if filtering removed everything - finalCells = [...upscaled]; - } - if (srcCell) { - const first = finalCells[0]; - if (!first || first.x !== srcCell.x || first.y !== srcCell.y) { - finalCells.unshift(srcCell); - } - } - const last = finalCells[finalCells.length - 1]; - if (!last || last.x !== cellDst.x || last.y !== cellDst.y) { - finalCells.push(cellDst); - } - if (finalCells.length < 2) { - // Create a single orthogonal step toward dst - const start = finalCells[0]; - if (!start) { - finalCells = [cellDst]; - } else if (start.x !== cellDst.x || start.y !== cellDst.y) { - const stepX = Math.sign(cellDst.x - start.x); - const stepY = Math.sign(cellDst.y - start.y); - const candidates: Cell[] = []; - if (stepX !== 0) candidates.push(new Cell(start.x + stepX, start.y)); - if (stepY !== 0) candidates.push(new Cell(start.x, start.y + stepY)); - let best: Cell | null = null; - let bestScore = Number.POSITIVE_INFINITY; - for (const cand of candidates) { - const ref = this.gameMap.ref(cand.x, cand.y); - const isWater = this.gameMap.isWater(ref); - const dist = - Math.abs(cellDst.x - cand.x) + Math.abs(cellDst.y - cand.y); - const score = (isWater ? 0 : 1000) + dist; - if (score < bestScore) { - best = cand; - bestScore = score; - } - } - if (best) finalCells.push(best); - } - if (finalCells.length < 2) { - // As a final guard, ensure there are at least two cells - finalCells.push(cellDst); - } - } - - // Map to tile refs - return finalCells.map((c) => this.gameMap.ref(c.x, c.y)); - } -} - -function fixExtremes(upscaled: Cell[], cellDst: Cell, cellSrc?: Cell): Cell[] { - if (cellSrc !== undefined) { - const srcIndex = findCell(upscaled, cellSrc); - if (srcIndex === -1) { - // didnt find the start tile in the path - upscaled.unshift(cellSrc); - } else if (srcIndex !== 0) { - // found start tile but not at the start - // remove all tiles before the start tile - upscaled = upscaled.slice(srcIndex); - } - } - - const dstIndex = findCell(upscaled, cellDst); - if (dstIndex === -1) { - // didnt find the dst tile in the path - upscaled.push(cellDst); - } else if (dstIndex !== upscaled.length - 1) { - // found dst tile but not at the end - // remove all tiles after the dst tile - upscaled = upscaled.slice(0, dstIndex + 1); - } - return upscaled; -} - -function upscalePath(path: Cell[], scaleFactor: number = 2): Cell[] { - // Scale up each point - const scaledPath = path.map( - (point) => new Cell(point.x * scaleFactor, point.y * scaleFactor), - ); - - const smoothPath: Cell[] = []; - - for (let i = 0; i < scaledPath.length - 1; i++) { - const current = scaledPath[i]; - const next = scaledPath[i + 1]; - - // Add the current point - smoothPath.push(current); - - // Always interpolate between scaled points - const dx = next.x - current.x; - const dy = next.y - current.y; - - // Calculate number of steps needed - const distance = Math.max(Math.abs(dx), Math.abs(dy)); - const steps = distance; - - // Add intermediate points - for (let step = 1; step < steps; step++) { - smoothPath.push( - new Cell( - Math.round(current.x + (dx * step) / steps), - Math.round(current.y + (dy * step) / steps), - ), - ); - } - } - - // Add the last point - if (scaledPath.length > 0) { - smoothPath.push(scaledPath[scaledPath.length - 1]); - } - - return smoothPath; -} - -function findCell(upscaled: Cell[], cellDst: Cell): number { - for (let i = 0; i < upscaled.length; i++) { - if (upscaled[i].x === cellDst.x && upscaled[i].y === cellDst.y) { - return i; - } - } - return -1; -} diff --git a/src/core/pathfinding/PathFinder.Air.ts b/src/core/pathfinding/PathFinder.Air.ts new file mode 100644 index 000000000..504427643 --- /dev/null +++ b/src/core/pathfinding/PathFinder.Air.ts @@ -0,0 +1,66 @@ +import { Game } from "../game/Game"; +import { TileRef } from "../game/GameMap"; +import { PseudoRandom } from "../PseudoRandom"; +import { PathFinder } from "./types"; + +export class AirPathFinder implements PathFinder { + private seed: number; + + constructor(private game: Game) { + this.seed = game.ticks(); + } + + findPath(from: TileRef | TileRef[], to: TileRef): TileRef[] | null { + if (Array.isArray(from)) { + throw new Error("AirPathFinder does not support multiple start points"); + } + + const random = new PseudoRandom(this.seed); + const path: TileRef[] = [from]; + let current = from; + + while (current !== to) { + const next = this.computeNext(current, to, random); + if (next === current) break; // Prevent infinite loop if something breaks + current = next; + path.push(current); + } + + return path; + } + + private computeNext( + from: TileRef, + to: TileRef, + random: PseudoRandom, + ): TileRef { + const x = this.game.x(from); + const y = this.game.y(from); + const dstX = this.game.x(to); + const dstY = this.game.y(to); + + if (x === dstX && y === dstY) { + return to; + } + + let nextX = x; + let nextY = y; + const ratio = Math.floor(1 + Math.abs(dstY - y) / (Math.abs(dstX - x) + 1)); + + if (x === dstX) { + // Can only move in Y + nextY += y < dstY ? 1 : -1; + } else if (y === dstY) { + // Can only move in X + nextX += x < dstX ? 1 : -1; + } else { + if (random.chance(ratio)) { + nextX += x < dstX ? 1 : -1; + } else { + nextY += y < dstY ? 1 : -1; + } + } + + return this.game.ref(nextX, nextY); + } +} diff --git a/src/core/pathfinding/PathFinder.Parabola.ts b/src/core/pathfinding/PathFinder.Parabola.ts new file mode 100644 index 000000000..83a6de28a --- /dev/null +++ b/src/core/pathfinding/PathFinder.Parabola.ts @@ -0,0 +1,88 @@ +import { GameMap, TileRef } from "../game/GameMap"; +import { within } from "../Util"; +import { DistanceBasedBezierCurve } from "../utilities/Line"; +import { PathResult, PathStatus, SteppingPathFinder } from "./types"; + +export interface ParabolaOptions { + increment?: number; + distanceBasedHeight?: boolean; + directionUp?: boolean; +} + +const PARABOLA_MIN_HEIGHT = 50; + +export class ParabolaUniversalPathFinder implements SteppingPathFinder { + private curve: DistanceBasedBezierCurve | null = null; + private lastTo: TileRef | null = null; + + constructor( + private gameMap: GameMap, + private options?: ParabolaOptions, + ) {} + + private createCurve(from: TileRef, to: TileRef): DistanceBasedBezierCurve { + const increment = this.options?.increment ?? 3; + const distanceBasedHeight = this.options?.distanceBasedHeight ?? true; + const directionUp = this.options?.directionUp ?? true; + + const p0 = { x: this.gameMap.x(from), y: this.gameMap.y(from) }; + const p3 = { x: this.gameMap.x(to), y: this.gameMap.y(to) }; + const dx = p3.x - p0.x; + const dy = p3.y - p0.y; + const distance = Math.sqrt(dx * dx + dy * dy); + const maxHeight = distanceBasedHeight + ? Math.max(distance / 3, PARABOLA_MIN_HEIGHT) + : 0; + const heightMult = directionUp ? -1 : 1; + const mapHeight = this.gameMap.height(); + + const p1 = { + x: p0.x + dx / 4, + y: within(p0.y + dy / 4 + heightMult * maxHeight, 0, mapHeight - 1), + }; + const p2 = { + x: p0.x + (dx * 3) / 4, + y: within(p0.y + (dy * 3) / 4 + heightMult * maxHeight, 0, mapHeight - 1), + }; + + return new DistanceBasedBezierCurve(p0, p1, p2, p3, increment); + } + + findPath(from: TileRef | TileRef[], to: TileRef): TileRef[] | null { + if (Array.isArray(from)) { + throw new Error( + "ParabolaUniversalPathFinder does not support multiple start points", + ); + } + const curve = this.createCurve(from, to); + return curve + .getAllPoints() + .map((p) => this.gameMap.ref(Math.floor(p.x), Math.floor(p.y))); + } + + next(from: TileRef, to: TileRef, speed?: number): PathResult { + if (this.lastTo !== to) { + this.curve = this.createCurve(from, to); + this.lastTo = to; + } + + const nextPoint = this.curve!.increment(speed ?? 1); + if (!nextPoint) { + return { status: PathStatus.COMPLETE, node: to }; + } + const tile = this.gameMap.ref( + Math.floor(nextPoint.x), + Math.floor(nextPoint.y), + ); + return { status: PathStatus.NEXT, node: tile }; + } + + invalidate(): void { + this.curve = null; + this.lastTo = null; + } + + currentIndex(): number { + return this.curve?.getCurrentIndex() ?? 0; + } +} diff --git a/src/core/pathfinding/PathFinder.Straight.ts b/src/core/pathfinding/PathFinder.Straight.ts new file mode 100644 index 000000000..a230a6b99 --- /dev/null +++ b/src/core/pathfinding/PathFinder.Straight.ts @@ -0,0 +1,44 @@ +import { GameMap, TileRef } from "../game/GameMap"; + +export class StraightPathFinder { + constructor(private mg: GameMap) {} + + nextTile(curr: TileRef, dst: TileRef, speed: number): TileRef | true { + const currX = this.mg.x(curr); + const currY = this.mg.y(curr); + + const dstX = this.mg.x(dst); + const dstY = this.mg.y(dst); + + const dx = dstX - currX; + const dy = dstY - currY; + + const distSq = dx * dx + dy * dy; + + if (distSq <= speed * speed) { + return true; + } + + const dist = Math.sqrt(distSq); + + const dirX = dx / dist; + const dirY = dy / dist; + + let nextX = Math.round(currX + dirX * speed); + let nextY = Math.round(currY + dirY * speed); + + // Clamp to map bounds to prevent invalid coordinates + nextX = Math.max(0, Math.min(this.mg.width() - 1, nextX)); + nextY = Math.max(0, Math.min(this.mg.height() - 1, nextY)); + + const remainingDx = dstX - nextX; + const remainingDy = dstY - nextY; + const remainingDist = Math.hypot(remainingDx, remainingDy); + + if (remainingDist <= speed) { + return true; + } else { + return this.mg.ref(nextX, nextY); + } + } +} diff --git a/src/core/pathfinding/PathFinder.ts b/src/core/pathfinding/PathFinder.ts index 7422e836b..04a4b60a9 100644 --- a/src/core/pathfinding/PathFinder.ts +++ b/src/core/pathfinding/PathFinder.ts @@ -1,43 +1,83 @@ import { Game } from "../game/Game"; -import { TileRef } from "../game/GameMap"; -import { MiniAStarAdapter } from "./adapters/MiniAStarAdapter"; -import { NavMeshAdapter } from "./adapters/NavMeshAdapter"; - -export enum PathStatus { - NEXT, - PENDING, - COMPLETE, - NOT_FOUND, -} - -export type PathResult = - | { status: PathStatus.PENDING } - | { status: PathStatus.NEXT; node: TileRef } - | { status: PathStatus.COMPLETE; node: TileRef } - | { status: PathStatus.NOT_FOUND }; +import { GameMap, TileRef } from "../game/GameMap"; +import { AStarWater } from "./algorithms/AStar.Water"; +import { AirPathFinder } from "./PathFinder.Air"; +import { + ParabolaOptions, + ParabolaUniversalPathFinder, +} from "./PathFinder.Parabola"; +import { PathFinderBuilder } from "./PathFinderBuilder"; +import { StepperConfig } from "./PathFinderStepper"; +import { BresenhamSmoothingTransformer } from "./smoothing/BresenhamPathSmoother"; +import { ComponentCheckTransformer } from "./transformers/ComponentCheckTransformer"; +import { MiniMapTransformer } from "./transformers/MiniMapTransformer"; +import { ShoreCoercingTransformer } from "./transformers/ShoreCoercingTransformer"; +import { PathStatus, SteppingPathFinder } from "./types"; -export interface PathFinder { - next(from: TileRef, to: TileRef, dist?: number): PathResult; - findPath(from: TileRef, to: TileRef): TileRef[] | null; +/** + * Pathfinders that work with GameMap - usable in both simulation and UI layers + */ +export class UniversalPathFinding { + static Parabola( + gameMap: GameMap, + options?: ParabolaOptions, + ): ParabolaUniversalPathFinder { + return new ParabolaUniversalPathFinder(gameMap, options); + } } -export interface MiniAStarOptions { - waterPath?: boolean; - iterations?: number; - maxTries?: number; -} +/** + * Pathfinders that require Game - simulation layer only + */ +export class PathFinding { + static Water(game: Game): SteppingPathFinder { + const pf = game.miniWaterHPA(); + const graph = game.miniWaterGraph(); -export class PathFinders { - static Water(game: Game): PathFinder { - if (!game.navMesh()) { - // Fall back to old water pathfinder if navmesh is not available - return PathFinders.WaterLegacy(game); + if (!pf || !graph || graph.nodeCount < 100) { + return PathFinding.WaterSimple(game); } - return new NavMeshAdapter(game); + const miniMap = game.miniMap(); + const componentCheckFn = (t: TileRef) => graph.getComponentId(t); + + return PathFinderBuilder.create(pf) + .wrap((pf) => new ComponentCheckTransformer(pf, componentCheckFn)) + .wrap((pf) => new BresenhamSmoothingTransformer(pf, miniMap)) + .wrap((pf) => new ShoreCoercingTransformer(pf, miniMap)) + .wrap((pf) => new MiniMapTransformer(pf, game.map(), miniMap)) + .buildWithStepper(tileStepperConfig(game)); } - static WaterLegacy(game: Game, options?: MiniAStarOptions): PathFinder { - return new MiniAStarAdapter(game, options); + static WaterSimple(game: Game): SteppingPathFinder { + const miniMap = game.miniMap(); + const pf = new AStarWater(miniMap); + + return PathFinderBuilder.create(pf) + .wrap((pf) => new ShoreCoercingTransformer(pf, miniMap)) + .wrap((pf) => new MiniMapTransformer(pf, game.map(), miniMap)) + .buildWithStepper(tileStepperConfig(game)); } + + static Air(game: Game): SteppingPathFinder { + const pf = new AirPathFinder(game); + + return PathFinderBuilder.create(pf).buildWithStepper({ + equals: (a, b) => a === b, + }); + } +} + +function tileStepperConfig(game: Game): StepperConfig { + return { + equals: (a, b) => a === b, + distance: (a, b) => game.manhattanDist(a, b), + preCheck: (from, to) => + typeof from !== "number" || + typeof to !== "number" || + !game.isValidRef(from) || + !game.isValidRef(to) + ? { status: PathStatus.NOT_FOUND } + : null, + }; } diff --git a/src/core/pathfinding/PathFinderBuilder.ts b/src/core/pathfinding/PathFinderBuilder.ts new file mode 100644 index 000000000..51d7b6460 --- /dev/null +++ b/src/core/pathfinding/PathFinderBuilder.ts @@ -0,0 +1,42 @@ +import { PathFinderStepper, StepperConfig } from "./PathFinderStepper"; +import { PathFinder, SteppingPathFinder } from "./types"; + +type WrapFactory = (pf: PathFinder) => PathFinder; + +/** + * PathFinderBuilder - fluent builder for composing PathFinder transformers. + * + * Usage: + * const finder = PathFinderBuilder.create(corePathFinder) + * .wrap((pf) => new SomeTransformer(pf, deps)) + * .wrap((pf) => new AnotherTransformer(pf, deps)) + * .build(); + */ +export class PathFinderBuilder { + private wrappers: WrapFactory[] = []; + + private constructor(private core: PathFinder) {} + + static create(core: PathFinder): PathFinderBuilder { + return new PathFinderBuilder(core); + } + + wrap(factory: WrapFactory): this { + this.wrappers.push(factory); + return this; + } + + build(): PathFinder { + return this.wrappers.reduce( + (pf, wrapper) => wrapper(pf), + this.core as PathFinder, + ); + } + + /** + * Build and wrap with PathFinderStepper for step-by-step traversal. + */ + buildWithStepper(config: StepperConfig): SteppingPathFinder { + return new PathFinderStepper(this.build(), config); + } +} diff --git a/src/core/pathfinding/PathFinderStepper.ts b/src/core/pathfinding/PathFinderStepper.ts new file mode 100644 index 000000000..4b8081fdc --- /dev/null +++ b/src/core/pathfinding/PathFinderStepper.ts @@ -0,0 +1,119 @@ +import { + PathFinder, + PathResult, + PathStatus, + SteppingPathFinder, +} from "./types"; + +export interface StepperConfig { + equals: (a: T, b: T) => boolean; + distance?: (a: T, b: T) => number; + preCheck?: (from: T, to: T) => PathResult | null; +} + +/** + * PathFinderStepper - wraps a PathFinder and provides step-by-step traversal + * + * Handles path caching, invalidation, and incremental movement. + * Generic over any PathFinder implementation. + */ +export class PathFinderStepper implements SteppingPathFinder { + private path: T[] | null = null; + private pathIndex = 0; + private lastTo: T | null = null; + + constructor( + private finder: PathFinder, + private config: StepperConfig = { equals: (a, b) => a === b }, + ) {} + + /** + * Get the next step on the path from `from` to `to`. + * Returns PathResult with status and optional next node. + */ + next(from: T, to: T, dist?: number): PathResult { + // Domain-specific pre-check (validation, cluster, etc.) + if (this.config.preCheck) { + const result = this.config.preCheck(from, to); + if (result) return result; + } + + if (this.config.equals(from, to)) { + return { status: PathStatus.COMPLETE, node: to }; + } + + // Distance-based early exit + if (dist !== undefined && dist > 0 && this.config.distance) { + if (this.config.distance(from, to) <= dist) { + return { status: PathStatus.COMPLETE, node: from }; + } + } + + // Invalidate cache if destination changed + if (this.lastTo === null || !this.config.equals(this.lastTo, to)) { + this.path = null; + this.pathIndex = 0; + this.lastTo = to; + } + + // Compute path if not cached + if (this.path === null) { + try { + this.path = this.finder.findPath(from, to); + } catch (err) { + console.error("PathFinder threw an error during findPath", err); + return { status: PathStatus.NOT_FOUND }; + } + + if (this.path === null) { + return { status: PathStatus.NOT_FOUND }; + } + + this.pathIndex = 0; + if (this.path.length > 0 && this.config.equals(this.path[0], from)) { + this.pathIndex = 1; + } + } + + const expectedPos = this.path[this.pathIndex - 1]; + if (this.pathIndex > 0 && !this.config.equals(from, expectedPos)) { + this.invalidate(); + this.lastTo = to; + return this.next(from, to, dist); + } + + // Check if we've reached the end + if (this.pathIndex >= this.path.length) { + return { status: PathStatus.COMPLETE, node: to }; + } + + // Return next step + const nextNode = this.path[this.pathIndex]; + this.pathIndex++; + + return { status: PathStatus.NEXT, node: nextNode }; + } + + invalidate(): void { + this.path = null; + this.pathIndex = 0; + this.lastTo = null; + } + + findPath(from: T | T[], to: T): T[] | null { + if (this.config.preCheck) { + const fromArray = Array.isArray(from) ? from : [from]; + + const allFailed = fromArray.every((f) => { + const result = this.config.preCheck!(f, to); + return result?.status === PathStatus.NOT_FOUND; + }); + + if (allFailed) { + return null; + } + } + + return this.finder.findPath(from, to); + } +} diff --git a/src/core/pathfinding/PathFinding.ts b/src/core/pathfinding/PathFinding.ts deleted file mode 100644 index 97e1422f8..000000000 --- a/src/core/pathfinding/PathFinding.ts +++ /dev/null @@ -1,285 +0,0 @@ -import { Game } from "../game/Game"; -import { GameMap, TileRef } from "../game/GameMap"; -import { PseudoRandom } from "../PseudoRandom"; -import { DistanceBasedBezierCurve } from "../utilities/Line"; -import { AStar, AStarResult, PathFindResultType } from "./AStar"; -import { MiniAStar } from "./MiniAStar"; -export { AStar, AStarResult, PathFindResultType }; - -const parabolaMinHeight = 50; - -export class ParabolaPathFinder { - constructor(private mg: GameMap) {} - private curve: DistanceBasedBezierCurve | undefined; - - computeControlPoints( - orig: TileRef, - dst: TileRef, - increment: number = 3, - distanceBasedHeight = true, - ) { - const p0 = { x: this.mg.x(orig), y: this.mg.y(orig) }; - const p3 = { x: this.mg.x(dst), y: this.mg.y(dst) }; - const dx = p3.x - p0.x; - const dy = p3.y - p0.y; - const distance = Math.sqrt(dx * dx + dy * dy); - const maxHeight = distanceBasedHeight - ? Math.max(distance / 3, parabolaMinHeight) - : 0; - // Use a bezier curve always pointing up - const p1 = { - x: p0.x + (p3.x - p0.x) / 4, - y: Math.max(p0.y + (p3.y - p0.y) / 4 - maxHeight, 0), - }; - const p2 = { - x: p0.x + ((p3.x - p0.x) * 3) / 4, - y: Math.max(p0.y + ((p3.y - p0.y) * 3) / 4 - maxHeight, 0), - }; - - this.curve = new DistanceBasedBezierCurve(p0, p1, p2, p3, increment); - } - - /** Clamp coordinates to valid map bounds */ - private clampToMap(x: number, y: number): { x: number; y: number } { - return { - x: Math.max(0, Math.min(this.mg.width() - 1, x)), - y: Math.max(0, Math.min(this.mg.height() - 1, y)), - }; - } - - nextTile(speed: number): TileRef | true { - if (!this.curve) { - throw new Error("ParabolaPathFinder not initialized"); - } - const nextPoint = this.curve.increment(speed); - if (!nextPoint) { - return true; - } - const clamped = this.clampToMap( - Math.floor(nextPoint.x), - Math.floor(nextPoint.y), - ); - return this.mg.ref(clamped.x, clamped.y); - } - - currentIndex(): number { - if (!this.curve) { - return 0; - } - return this.curve.getCurrentIndex(); - } - - allTiles(): TileRef[] { - if (!this.curve) { - return []; - } - return this.curve.getAllPoints().map((point) => { - const clamped = this.clampToMap(Math.floor(point.x), Math.floor(point.y)); - return this.mg.ref(clamped.x, clamped.y); - }); - } -} - -export class AirPathFinder { - constructor( - private mg: GameMap, - private random: PseudoRandom, - ) {} - - nextTile(tile: TileRef, dst: TileRef): TileRef | true { - const x = this.mg.x(tile); - const y = this.mg.y(tile); - const dstX = this.mg.x(dst); - const dstY = this.mg.y(dst); - - if (x === dstX && y === dstY) { - return true; - } - - // Calculate next position - let nextX = x; - let nextY = y; - - const ratio = Math.floor(1 + Math.abs(dstY - y) / (Math.abs(dstX - x) + 1)); - - if (this.random.chance(ratio) && x !== dstX) { - if (x < dstX) nextX++; - else if (x > dstX) nextX--; - } else { - if (y < dstY) nextY++; - else if (y > dstY) nextY--; - } - if (nextX === x && nextY === y) { - return true; - } - return this.mg.ref(nextX, nextY); - } -} - -export class StraightPathFinder { - constructor(private mg: GameMap) {} - - nextTile(curr: TileRef, dst: TileRef, speed: number): TileRef | true { - const currX = this.mg.x(curr); - const currY = this.mg.y(curr); - - const dstX = this.mg.x(dst); - const dstY = this.mg.y(dst); - - const dx = dstX - currX; - const dy = dstY - currY; - - const distSq = dx * dx + dy * dy; - - if (distSq <= speed * speed) { - return true; - } - - const dist = Math.sqrt(distSq); - - const dirX = dx / dist; - const dirY = dy / dist; - - let nextX = Math.round(currX + dirX * speed); - let nextY = Math.round(currY + dirY * speed); - - // Clamp to map bounds to prevent invalid coordinates - nextX = Math.max(0, Math.min(this.mg.width() - 1, nextX)); - nextY = Math.max(0, Math.min(this.mg.height() - 1, nextY)); - - const remainingDx = dstX - nextX; - const remainingDy = dstY - nextY; - const remainingDist = Math.hypot(remainingDx, remainingDy); - - if (remainingDist <= speed) { - return true; - } else { - return this.mg.ref(nextX, nextY); - } - } -} -export class MiniPathFinder { - private curr: TileRef | null = null; - private dst: TileRef | null = null; - private path: TileRef[] | null = null; - private path_idx: number = 0; - private aStar: AStar; - private computeFinished = true; - - constructor( - private game: Game, - private iterations: number, - private waterPath: boolean, - private maxTries: number, - ) {} - - private createAStar(curr: TileRef, dst: TileRef): AStar { - return new MiniAStar( - this.game.map(), - this.game.miniMap(), - curr, - dst, - this.iterations, - this.maxTries, - this.waterPath, - ); - } - - nextTile( - curr: TileRef | null, - dst: TileRef | null, - dist: number = 1, - ): AStarResult { - if (curr === null) { - console.error("curr is null"); - return { type: PathFindResultType.PathNotFound }; - } - if (dst === null) { - console.error("dst is null"); - return { type: PathFindResultType.PathNotFound }; - } - if (this.game.manhattanDist(curr, dst) < dist) { - this.path = null; - return { type: PathFindResultType.Completed, node: curr }; - } - - if (this.computeFinished) { - if (this.shouldRecompute(curr, dst)) { - this.curr = curr; - this.dst = dst; - this.path = null; - this.path_idx = 0; - this.aStar = this.createAStar(curr, dst); - this.computeFinished = false; - return this.nextTile(curr, dst); - } else { - const tile = this.path?.[this.path_idx++]; - if (tile === undefined) { - // Path exhausted unexpectedly. If already within step distance, report completion. - if (this.game.manhattanDist(curr, dst) < dist) { - return { type: PathFindResultType.Completed, node: curr }; - } - // Otherwise, recompute a fresh path from current position. - this.curr = curr; - this.dst = dst; - this.path = null; - this.path_idx = 0; - this.aStar = this.createAStar(curr, dst); - this.computeFinished = false; - return this.nextTile(curr, dst); - } - return { type: PathFindResultType.NextTile, node: tile }; - } - } - - switch (this.aStar.compute()) { - case PathFindResultType.Completed: - this.computeFinished = true; - this.path = this.aStar.reconstructPath(); - - // exclude first tile - this.path_idx = 1; - // If the reconstructed path is empty, fall back to completion or path-not-found handling. - if (!this.path || this.path.length === 0) { - if (this.game.manhattanDist(curr, dst) < dist) { - return { type: PathFindResultType.Completed, node: curr }; - } else { - return { type: PathFindResultType.PathNotFound }; - } - } - return this.nextTile(curr, dst); - case PathFindResultType.Pending: - return { type: PathFindResultType.Pending }; - case PathFindResultType.PathNotFound: - return { type: PathFindResultType.PathNotFound }; - default: - throw new Error("unexpected compute result"); - } - } - - public reconstructPath(): TileRef[] { - if (this.path === null) { - return []; - } - return this.path; - } - - private shouldRecompute(curr: TileRef, dst: TileRef) { - if (this.path === null || this.curr === null || this.dst === null) { - return true; - } - const dist = this.game.manhattanDist(curr, dst); - let tolerance = 10; - if (dist > 50) { - tolerance = 10; - } else if (dist > 25) { - tolerance = 5; - } else { - tolerance = 0; - } - if (this.game.manhattanDist(this.dst, dst) > tolerance) { - return true; - } - return false; - } -} diff --git a/src/core/pathfinding/SerialAStar.ts b/src/core/pathfinding/SerialAStar.ts deleted file mode 100644 index 81972720c..000000000 --- a/src/core/pathfinding/SerialAStar.ts +++ /dev/null @@ -1,219 +0,0 @@ -import FastPriorityQueue from "fastpriorityqueue"; -import { AStar, PathFindResultType } from "./AStar"; - -/** - * Implement this interface with your graph to find paths with A* - */ -export interface GraphAdapter { - // Iterable to support arrays or typed array views - neighbors(node: NodeType): Iterable; - cost(node: NodeType): number; - position(node: NodeType): { x: number; y: number }; - isTraversable(from: NodeType, to: NodeType): boolean; -} - -export class SerialAStar implements AStar { - private fwdOpenSet: FastPriorityQueue<{ - tile: NodeType; - fScore: number; - }>; - private bwdOpenSet: FastPriorityQueue<{ - tile: NodeType; - fScore: number; - }>; - - private fwdCameFrom = new Map(); - private bwdCameFrom = new Map(); - private fwdGScore = new Map(); - private bwdGScore = new Map(); - // Direction used to reach a node (encoded as an int 0..8) - private fwdDirTo = new Map(); - private bwdDirTo = new Map(); - - private meetingPoint: NodeType | null = null; - public completed = false; - private sources: NodeType[]; - private closestSource: NodeType; - - constructor( - src: NodeType | NodeType[], - private dst: NodeType, - private iterations: number, - private maxTries: number, - private graph: GraphAdapter, - private directionChangePenalty: number = 0, - ) { - this.fwdOpenSet = new FastPriorityQueue((a, b) => a.fScore < b.fScore); - this.bwdOpenSet = new FastPriorityQueue((a, b) => a.fScore < b.fScore); - this.sources = Array.isArray(src) ? src : [src]; - this.closestSource = this.findClosestSource(dst); - - // Initialize forward search with source point(s) - this.sources.forEach((startPoint) => { - this.fwdGScore.set(startPoint, 0); - this.fwdOpenSet.add({ - tile: startPoint, - fScore: this.heuristic(startPoint, dst), - }); - }); - - // Initialize backward search from destination - this.bwdGScore.set(dst, 0); - this.bwdOpenSet.add({ - tile: dst, - fScore: this.heuristic(dst, this.findClosestSource(dst)), - }); - } - - private findClosestSource(tile: NodeType): NodeType { - return this.sources.reduce((closest, source) => - this.heuristic(tile, source) < this.heuristic(tile, closest) - ? source - : closest, - ); - } - - compute(): PathFindResultType { - if (this.completed) return PathFindResultType.Completed; - - this.maxTries -= 1; - let iterations = this.iterations; - - while (!this.fwdOpenSet.isEmpty() && !this.bwdOpenSet.isEmpty()) { - iterations--; - if (iterations <= 0) { - if (this.maxTries <= 0) { - return PathFindResultType.PathNotFound; - } - return PathFindResultType.Pending; - } - - // Process forward search - const fwdCurrent = this.fwdOpenSet.poll()!.tile; - - // Check if we've found a meeting point - if (this.bwdGScore.has(fwdCurrent)) { - this.meetingPoint = fwdCurrent; - this.completed = true; - return PathFindResultType.Completed; - } - this.expandNode(fwdCurrent, true); - if (this.completed) return PathFindResultType.Completed; - - // Process backward search - const bwdCurrent = this.bwdOpenSet.poll()!.tile; - - // Check if we've found a meeting point - if (this.fwdGScore.has(bwdCurrent)) { - this.meetingPoint = bwdCurrent; - this.completed = true; - return PathFindResultType.Completed; - } - this.expandNode(bwdCurrent, false); - if (this.completed) return PathFindResultType.Completed; - } - - return this.completed - ? PathFindResultType.Completed - : PathFindResultType.PathNotFound; - } - - private expandNode(current: NodeType, isForward: boolean) { - // Hoist side-specific structures and immutable targets out of the loop - const gScore = isForward ? this.fwdGScore : this.bwdGScore; - const openSet = isForward ? this.fwdOpenSet : this.bwdOpenSet; - const cameFrom = isForward ? this.fwdCameFrom : this.bwdCameFrom; - const dirTo = isForward ? this.fwdDirTo : this.bwdDirTo; - const otherG = isForward ? this.bwdGScore : this.fwdGScore; - const target = isForward ? this.dst : this.closestSource; - - // Cache current and target positions once - const currentPos = this.graph.position(current); - const targetPos = this.graph.position(target); - const prevDirCode = - this.directionChangePenalty > 0 ? dirTo.get(current) : undefined; - const currentG = gScore.get(current)!; - - for (const neighbor of this.graph.neighbors(current)) { - // Skip non-traversable neighbors except when the neighbor is the target - if (neighbor !== target && !this.graph.isTraversable(current, neighbor)) - continue; - - const tentativeGScore = currentG + this.graph.cost(neighbor); - // Cache neighbor position once (used by penalty and heuristic) - const nPos = this.graph.position(neighbor); - - // Optional direction change penalty without string allocations - let penalty = 0; - let newDirCode: number | undefined = undefined; - if (this.directionChangePenalty > 0) { - const dx = Math.sign(nPos.x - currentPos.x) + 1; // 0..2 - const dy = Math.sign(nPos.y - currentPos.y) + 1; // 0..2 - newDirCode = dx * 3 + dy; // 0..8 - if (prevDirCode !== undefined && prevDirCode !== newDirCode) { - penalty = this.directionChangePenalty; - } - } - - const totalG = tentativeGScore + penalty; - const neighborG = gScore.get(neighbor); - if (neighborG === undefined || totalG < neighborG) { - cameFrom.set(neighbor, current); - gScore.set(neighbor, totalG); - if (this.directionChangePenalty > 0 && newDirCode !== undefined) { - dirTo.set(neighbor, newDirCode); - } - - // Inline heuristic using cached target position (2 * Manhattan) - const fScore = - totalG + - 2 * (Math.abs(nPos.x - targetPos.x) + Math.abs(nPos.y - targetPos.y)); - openSet.add({ tile: neighbor, fScore }); - - // Early meeting detection to reduce expansions - if (otherG.has(neighbor)) { - this.meetingPoint = neighbor; - this.completed = true; - return; - } - } - } - } - - private heuristic(a: NodeType, b: NodeType): number { - const posA = this.graph.position(a); - const posB = this.graph.position(b); - return 2 * (Math.abs(posA.x - posB.x) + Math.abs(posA.y - posB.y)); - } - - private getDirection(from: NodeType, to: NodeType): string { - const fromPos = this.graph.position(from); - const toPos = this.graph.position(to); - const dx = toPos.x - fromPos.x; - const dy = toPos.y - fromPos.y; - return `${Math.sign(dx)},${Math.sign(dy)}`; - } - - public reconstructPath(): NodeType[] { - if (!this.meetingPoint) return []; - - // Reconstruct path from start to meeting point - const fwdPath: NodeType[] = [this.meetingPoint]; - let current = this.meetingPoint; - - while (this.fwdCameFrom.has(current)) { - current = this.fwdCameFrom.get(current)!; - fwdPath.unshift(current); - } - - // Reconstruct path from meeting point to goal - current = this.meetingPoint; - - while (this.bwdCameFrom.has(current)) { - current = this.bwdCameFrom.get(current)!; - fwdPath.push(current); - } - - return fwdPath; - } -} diff --git a/src/core/pathfinding/adapters/MiniAStarAdapter.ts b/src/core/pathfinding/adapters/MiniAStarAdapter.ts deleted file mode 100644 index b1c1841d6..000000000 --- a/src/core/pathfinding/adapters/MiniAStarAdapter.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Game } from "../../game/Game"; -import { TileRef } from "../../game/GameMap"; -import { PathFindResultType } from "../AStar"; -import { - MiniAStarOptions, - PathFinder, - PathResult, - PathStatus, -} from "../PathFinder"; -import { MiniPathFinder } from "../PathFinding"; - -const DEFAULT_ITERATIONS = 10_000; -const DEFAULT_MAX_TRIES = 100; - -export class MiniAStarAdapter implements PathFinder { - private miniPathFinder: MiniPathFinder; - - constructor(game: Game, options?: MiniAStarOptions) { - this.miniPathFinder = new MiniPathFinder( - game, - options?.iterations ?? DEFAULT_ITERATIONS, - options?.waterPath ?? true, - options?.maxTries ?? DEFAULT_MAX_TRIES, - ); - } - - next(from: TileRef, to: TileRef, dist?: number): PathResult { - const result = this.miniPathFinder.nextTile(from, to, dist); - - switch (result.type) { - case PathFindResultType.Pending: - return { status: PathStatus.PENDING }; - case PathFindResultType.NextTile: - return { status: PathStatus.NEXT, node: result.node }; - case PathFindResultType.Completed: - return { status: PathStatus.COMPLETE, node: result.node }; - case PathFindResultType.PathNotFound: - return { status: PathStatus.NOT_FOUND }; - } - } - - findPath(from: TileRef, to: TileRef): TileRef[] | null { - const path: TileRef[] = [from]; - let current = from; - const maxSteps = 100_000; - - for (let i = 0; i < maxSteps; i++) { - const result = this.next(current, to); - - if (result.status === PathStatus.COMPLETE) { - return path; - } - - if (result.status === PathStatus.NOT_FOUND) { - return null; - } - - if (result.status === PathStatus.NEXT) { - current = result.node; - path.push(current); - } - } - - return null; - } -} diff --git a/src/core/pathfinding/adapters/NavMeshAdapter.ts b/src/core/pathfinding/adapters/NavMeshAdapter.ts deleted file mode 100644 index 4e081eb4a..000000000 --- a/src/core/pathfinding/adapters/NavMeshAdapter.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Game } from "../../game/Game"; -import { TileRef } from "../../game/GameMap"; -import { NavMesh } from "../navmesh/NavMesh"; -import { PathFinder, PathResult, PathStatus } from "../PathFinder"; - -export class NavMeshAdapter implements PathFinder { - private navMesh: NavMesh; - private pathIndex = 0; - private path: TileRef[] | null = null; - private lastTo: TileRef | null = null; - - constructor(private game: Game) { - const navMesh = game.navMesh(); - if (!navMesh) { - throw new Error("NavMeshAdapter requires game.navMesh() to be available"); - } - this.navMesh = navMesh; - } - - next(from: TileRef, to: TileRef, dist?: number): PathResult { - if (typeof from !== "number" || typeof to !== "number") { - return { status: PathStatus.NOT_FOUND }; - } - - if (!this.game.isValidRef(from) || !this.game.isValidRef(to)) { - return { status: PathStatus.NOT_FOUND }; - } - - if (from === to) { - return { status: PathStatus.COMPLETE, node: to }; - } - - if (dist !== undefined && dist > 0) { - const distance = this.game.manhattanDist(from, to); - - if (distance <= dist) { - return { status: PathStatus.COMPLETE, node: from }; - } - } - - if (this.lastTo !== to) { - this.path = null; - this.pathIndex = 0; - this.lastTo = to; - } - - if (this.path === null) { - this.cachePath(from, to); - - if (this.path === null) { - return { status: PathStatus.NOT_FOUND }; - } - } - - // Recompute if deviated from planned path - const expectedPos = this.path[this.pathIndex - 1]; - if (this.pathIndex > 0 && from !== expectedPos) { - this.cachePath(from, to); - - if (this.path === null) { - return { status: PathStatus.NOT_FOUND }; - } - } - - if (this.pathIndex >= this.path.length) { - return { status: PathStatus.COMPLETE, node: to }; - } - - const nextNode = this.path[this.pathIndex]; - this.pathIndex++; - - return { status: PathStatus.NEXT, node: nextNode }; - } - - findPath(from: TileRef, to: TileRef): TileRef[] | null { - return this.navMesh.findPath(from, to); - } - - private cachePath(from: TileRef, to: TileRef): boolean { - try { - this.path = this.navMesh.findPath(from, to); - } catch { - return false; - } - - if (this.path === null) { - return false; - } - - this.pathIndex = 0; - - // Path starts with 'from', skip to next tile - if (this.path.length > 0 && this.path[0] === from) { - this.pathIndex = 1; - } - - return true; - } -} diff --git a/src/core/pathfinding/algorithms/AStar.AbstractGraph.ts b/src/core/pathfinding/algorithms/AStar.AbstractGraph.ts new file mode 100644 index 000000000..82da9f604 --- /dev/null +++ b/src/core/pathfinding/algorithms/AStar.AbstractGraph.ts @@ -0,0 +1,249 @@ +import { PathFinder } from "../types"; +import { AbstractGraph } from "./AbstractGraph"; +import { BucketQueue, MinHeap, PriorityQueue } from "./PriorityQueue"; + +export interface AbstractGraphAStarConfig { + heuristicWeight?: number; + maxIterations?: number; + useMinHeap?: boolean; // Use MinHeap instead of BucketQueue (better for variable costs) +} + +export class AbstractGraphAStar implements PathFinder { + private stamp = 1; + + private readonly closedStamp: Uint32Array; + private readonly gScoreStamp: Uint32Array; + private readonly gScore: Float32Array; + private readonly cameFrom: Int32Array; + private readonly startNode: Int32Array; // tracks which start each node came from + private readonly queue: PriorityQueue; + private readonly graph: AbstractGraph; + private readonly heuristicWeight: number; + private readonly maxIterations: number; + + constructor(graph: AbstractGraph, config?: AbstractGraphAStarConfig) { + this.graph = graph; + this.heuristicWeight = config?.heuristicWeight ?? 1; + this.maxIterations = config?.maxIterations ?? 100_000; + + const numNodes = graph.nodeCount; + + this.closedStamp = new Uint32Array(numNodes); + this.gScoreStamp = new Uint32Array(numNodes); + this.gScore = new Float32Array(numNodes); + this.cameFrom = new Int32Array(numNodes); + this.startNode = new Int32Array(numNodes); + + // For abstract graphs with variable costs, MinHeap may be better + // BucketQueue is O(1) but requires integer priorities + if (config?.useMinHeap) { + this.queue = new MinHeap(numNodes); + } else { + // Estimate max priority: weight * (mapWidth + mapHeight) + // Use cluster size * clusters as approximation + const maxDist = graph.clusterSize * Math.max(graph.clustersX, 10) * 2; + const maxF = this.heuristicWeight * maxDist; + this.queue = new BucketQueue(maxF); + } + } + + findPath(start: number | number[], goal: number): number[] | null { + if (Array.isArray(start)) { + return this.findPathMultiSource(start, goal); + } + return this.findPathSingle(start, goal); + } + + private findPathSingle(startId: number, goalId: number): number[] | null { + this.stamp++; + if (this.stamp > 0xffffffff) { + this.closedStamp.fill(0); + this.gScoreStamp.fill(0); + this.stamp = 1; + } + + const stamp = this.stamp; + const graph = this.graph; + const closedStamp = this.closedStamp; + const gScoreStamp = this.gScoreStamp; + const gScore = this.gScore; + const cameFrom = this.cameFrom; + const queue = this.queue; + const weight = this.heuristicWeight; + + // Get goal node for heuristic + const goalNode = graph.getNode(goalId); + if (!goalNode) return null; + const goalX = goalNode.x; + const goalY = goalNode.y; + + // Get start node for initial heuristic + const startNode = graph.getNode(startId); + if (!startNode) return null; + + // Initialize + queue.clear(); + gScore[startId] = 0; + gScoreStamp[startId] = stamp; + cameFrom[startId] = -1; + + const startH = + weight * (Math.abs(startNode.x - goalX) + Math.abs(startNode.y - goalY)); + queue.push(startId, startH); + + let iterations = this.maxIterations; + + while (!queue.isEmpty()) { + if (--iterations <= 0) { + return null; + } + + const current = queue.pop(); + + if (closedStamp[current] === stamp) continue; + closedStamp[current] = stamp; + + if (current === goalId) { + return this.buildPathFromGoal(goalId); + } + + const currentG = gScore[current]; + const edges = graph.getNodeEdges(current); + + // Inline neighbor iteration + for (let i = 0; i < edges.length; i++) { + const edge = edges[i]; + const neighbor = graph.getOtherNode(edge, current); + + if (closedStamp[neighbor] === stamp) continue; + + const tentativeG = currentG + edge.cost; + + if (gScoreStamp[neighbor] !== stamp || tentativeG < gScore[neighbor]) { + cameFrom[neighbor] = current; + gScore[neighbor] = tentativeG; + gScoreStamp[neighbor] = stamp; + + // Inline heuristic calculation + const neighborNode = graph.getNode(neighbor); + if (neighborNode) { + const h = + weight * + (Math.abs(neighborNode.x - goalX) + + Math.abs(neighborNode.y - goalY)); + queue.push(neighbor, tentativeG + h); + } + } + } + } + + return null; + } + + private findPathMultiSource( + startIds: number[], + goalId: number, + ): number[] | null { + if (startIds.length === 0) return null; + if (startIds.length === 1) return this.findPathSingle(startIds[0], goalId); + + this.stamp++; + if (this.stamp > 0xffffffff) { + this.closedStamp.fill(0); + this.gScoreStamp.fill(0); + this.stamp = 1; + } + + const stamp = this.stamp; + const graph = this.graph; + const closedStamp = this.closedStamp; + const gScoreStamp = this.gScoreStamp; + const gScore = this.gScore; + const cameFrom = this.cameFrom; + const startNode = this.startNode; + const queue = this.queue; + const weight = this.heuristicWeight; + + // Get goal node for heuristic + const goalNode = graph.getNode(goalId); + if (!goalNode) return null; + const goalX = goalNode.x; + const goalY = goalNode.y; + + // Initialize all start nodes + queue.clear(); + for (const startId of startIds) { + const node = graph.getNode(startId); + if (!node) continue; + + gScore[startId] = 0; + gScoreStamp[startId] = stamp; + cameFrom[startId] = -1; + startNode[startId] = startId; // each start is its own origin + + const h = weight * (Math.abs(node.x - goalX) + Math.abs(node.y - goalY)); + queue.push(startId, h); + } + + let iterations = this.maxIterations; + + while (!queue.isEmpty()) { + if (--iterations <= 0) { + return null; + } + + const current = queue.pop(); + + if (closedStamp[current] === stamp) continue; + closedStamp[current] = stamp; + + if (current === goalId) { + return this.buildPathFromGoal(goalId); + } + + const currentG = gScore[current]; + const currentStart = startNode[current]; + const edges = graph.getNodeEdges(current); + + for (let i = 0; i < edges.length; i++) { + const edge = edges[i]; + const neighbor = graph.getOtherNode(edge, current); + + if (closedStamp[neighbor] === stamp) continue; + + const tentativeG = currentG + edge.cost; + + if (gScoreStamp[neighbor] !== stamp || tentativeG < gScore[neighbor]) { + cameFrom[neighbor] = current; + gScore[neighbor] = tentativeG; + gScoreStamp[neighbor] = stamp; + startNode[neighbor] = currentStart; // propagate origin + + const neighborNode = graph.getNode(neighbor); + if (neighborNode) { + const h = + weight * + (Math.abs(neighborNode.x - goalX) + + Math.abs(neighborNode.y - goalY)); + queue.push(neighbor, tentativeG + h); + } + } + } + } + + return null; + } + + private buildPathFromGoal(goalId: number): number[] { + const path: number[] = []; + let current = goalId; + + while (current !== -1) { + path.push(current); + current = this.cameFrom[current]; + } + + path.reverse(); + return path; + } +} diff --git a/src/core/pathfinding/algorithms/AStar.Bounded.ts b/src/core/pathfinding/algorithms/AStar.Bounded.ts new file mode 100644 index 000000000..923f06083 --- /dev/null +++ b/src/core/pathfinding/algorithms/AStar.Bounded.ts @@ -0,0 +1,289 @@ +import { GameMap, TileRef } from "../../game/GameMap"; +import { PathFinder } from "../types"; +import { BucketQueue } from "./PriorityQueue"; + +const LAND_BIT = 7; + +export interface BoundedAStarConfig { + heuristicWeight?: number; + maxIterations?: number; +} + +export interface SearchBounds { + minX: number; + maxX: number; + minY: number; + maxY: number; +} + +export class AStarBounded implements PathFinder { + private stamp = 1; + + private readonly closedStamp: Uint32Array; + private readonly gScoreStamp: Uint32Array; + private readonly gScore: Uint32Array; + private readonly cameFrom: Int32Array; + private readonly queue: BucketQueue; + private readonly terrain: Uint8Array; + private readonly mapWidth: number; + private readonly heuristicWeight: number; + private readonly maxIterations: number; + + constructor( + map: GameMap, + maxSearchArea: number, + config?: BoundedAStarConfig, + ) { + this.terrain = (map as any).terrain as Uint8Array; + this.mapWidth = map.width(); + this.heuristicWeight = config?.heuristicWeight ?? 1; + this.maxIterations = config?.maxIterations ?? 100_000; + + this.closedStamp = new Uint32Array(maxSearchArea); + this.gScoreStamp = new Uint32Array(maxSearchArea); + this.gScore = new Uint32Array(maxSearchArea); + this.cameFrom = new Int32Array(maxSearchArea); + + const maxDim = Math.ceil(Math.sqrt(maxSearchArea)); + const maxF = this.heuristicWeight * maxDim * 2; + this.queue = new BucketQueue(maxF); + } + + findPath(start: number | number[], goal: number): number[] | null { + const starts = Array.isArray(start) ? start : [start]; + const goalX = goal % this.mapWidth; + const goalY = (goal / this.mapWidth) | 0; + + let minX = goalX; + let maxX = goalX; + let minY = goalY; + let maxY = goalY; + + for (const s of starts) { + const sx = s % this.mapWidth; + const sy = (s / this.mapWidth) | 0; + minX = Math.min(minX, sx); + maxX = Math.max(maxX, sx); + minY = Math.min(minY, sy); + maxY = Math.max(maxY, sy); + } + + return this.searchBounded(starts as TileRef[], goal as TileRef, { + minX, + maxX, + minY, + maxY, + }); + } + + searchBounded( + start: TileRef | TileRef[], + goal: TileRef, + bounds: SearchBounds, + ): TileRef[] | null { + this.stamp++; + if (this.stamp > 0xffffffff) { + this.closedStamp.fill(0); + this.gScoreStamp.fill(0); + this.stamp = 1; + } + + const stamp = this.stamp; + const mapWidth = this.mapWidth; + const terrain = this.terrain; + const closedStamp = this.closedStamp; + const gScoreStamp = this.gScoreStamp; + const gScore = this.gScore; + const cameFrom = this.cameFrom; + const queue = this.queue; + const weight = this.heuristicWeight; + const landMask = 1 << LAND_BIT; + + const { minX, maxX, minY, maxY } = bounds; + const boundsWidth = maxX - minX + 1; + const goalX = goal % mapWidth; + const goalY = (goal / mapWidth) | 0; + const boundsHeight = maxY - minY + 1; + const numLocalNodes = boundsWidth * boundsHeight; + + if (numLocalNodes > this.closedStamp.length) { + return null; + } + + const toLocal = (tile: TileRef, clamp: boolean = false): number => { + let x = tile % mapWidth; + let y = (tile / mapWidth) | 0; + if (clamp) { + x = Math.max(minX, Math.min(maxX, x)); + y = Math.max(minY, Math.min(maxY, y)); + } + return (y - minY) * boundsWidth + (x - minX); + }; + + const toGlobal = (local: number): TileRef => { + const localX = local % boundsWidth; + const localY = (local / boundsWidth) | 0; + return ((localY + minY) * mapWidth + (localX + minX)) as TileRef; + }; + + const goalLocal = toLocal(goal, true); + if (goalLocal < 0 || goalLocal >= numLocalNodes) { + return null; + } + + queue.clear(); + const starts = Array.isArray(start) ? start : [start]; + for (const s of starts) { + const startLocal = toLocal(s, true); + if (startLocal < 0 || startLocal >= numLocalNodes) { + continue; + } + gScore[startLocal] = 0; + gScoreStamp[startLocal] = stamp; + cameFrom[startLocal] = -1; + const sx = s % mapWidth; + const sy = (s / mapWidth) | 0; + const h = weight * (Math.abs(sx - goalX) + Math.abs(sy - goalY)); + queue.push(startLocal, h); + } + + let iterations = this.maxIterations; + + while (!queue.isEmpty()) { + if (--iterations <= 0) { + return null; + } + + const currentLocal = queue.pop(); + + if (closedStamp[currentLocal] === stamp) continue; + closedStamp[currentLocal] = stamp; + + if (currentLocal === goalLocal) { + return this.buildPath(goalLocal, toGlobal, numLocalNodes); + } + + const currentG = gScore[currentLocal]; + const tentativeG = currentG + 1; + + // Convert to global coords for neighbor calculation + const current = toGlobal(currentLocal); + const currentX = current % mapWidth; + const currentY = (current / mapWidth) | 0; + + if (currentY > minY) { + const neighbor = current - mapWidth; + const neighborLocal = currentLocal - boundsWidth; + if ( + closedStamp[neighborLocal] !== stamp && + (neighbor === goal || (terrain[neighbor] & landMask) === 0) + ) { + if ( + gScoreStamp[neighborLocal] !== stamp || + tentativeG < gScore[neighborLocal] + ) { + cameFrom[neighborLocal] = currentLocal; + gScore[neighborLocal] = tentativeG; + gScoreStamp[neighborLocal] = stamp; + const f = + tentativeG + + weight * + (Math.abs(currentX - goalX) + Math.abs(currentY - 1 - goalY)); + queue.push(neighborLocal, f); + } + } + } + + if (currentY < maxY) { + const neighbor = current + mapWidth; + const neighborLocal = currentLocal + boundsWidth; + if ( + closedStamp[neighborLocal] !== stamp && + (neighbor === goal || (terrain[neighbor] & landMask) === 0) + ) { + if ( + gScoreStamp[neighborLocal] !== stamp || + tentativeG < gScore[neighborLocal] + ) { + cameFrom[neighborLocal] = currentLocal; + gScore[neighborLocal] = tentativeG; + gScoreStamp[neighborLocal] = stamp; + const f = + tentativeG + + weight * + (Math.abs(currentX - goalX) + Math.abs(currentY + 1 - goalY)); + queue.push(neighborLocal, f); + } + } + } + + if (currentX > minX) { + const neighbor = current - 1; + const neighborLocal = currentLocal - 1; + if ( + closedStamp[neighborLocal] !== stamp && + (neighbor === goal || (terrain[neighbor] & landMask) === 0) + ) { + if ( + gScoreStamp[neighborLocal] !== stamp || + tentativeG < gScore[neighborLocal] + ) { + cameFrom[neighborLocal] = currentLocal; + gScore[neighborLocal] = tentativeG; + gScoreStamp[neighborLocal] = stamp; + const f = + tentativeG + + weight * + (Math.abs(currentX - 1 - goalX) + Math.abs(currentY - goalY)); + queue.push(neighborLocal, f); + } + } + } + + if (currentX < maxX) { + const neighbor = current + 1; + const neighborLocal = currentLocal + 1; + if ( + closedStamp[neighborLocal] !== stamp && + (neighbor === goal || (terrain[neighbor] & landMask) === 0) + ) { + if ( + gScoreStamp[neighborLocal] !== stamp || + tentativeG < gScore[neighborLocal] + ) { + cameFrom[neighborLocal] = currentLocal; + gScore[neighborLocal] = tentativeG; + gScoreStamp[neighborLocal] = stamp; + const f = + tentativeG + + weight * + (Math.abs(currentX + 1 - goalX) + Math.abs(currentY - goalY)); + queue.push(neighborLocal, f); + } + } + } + } + + return null; + } + + private buildPath( + goalLocal: number, + toGlobal: (local: number) => TileRef, + maxPathLength: number, + ): TileRef[] { + const path: TileRef[] = []; + let current = goalLocal; + + // Safety check to prevent infinite loops + let iterations = 0; + while (current !== -1 && iterations < maxPathLength) { + path.push(toGlobal(current)); + current = this.cameFrom[current]; + iterations++; + } + + path.reverse(); + return path; + } +} diff --git a/src/core/pathfinding/algorithms/AStar.Water.ts b/src/core/pathfinding/algorithms/AStar.Water.ts new file mode 100644 index 000000000..920f1a475 --- /dev/null +++ b/src/core/pathfinding/algorithms/AStar.Water.ts @@ -0,0 +1,203 @@ +import { GameMap, TileRef } from "../../game/GameMap"; +import { PathFinder } from "../types"; +import { BucketQueue, PriorityQueue } from "./PriorityQueue"; + +const LAND_BIT = 7; // Bit 7 in terrain indicates land + +export interface AStarWaterConfig { + heuristicWeight?: number; + maxIterations?: number; +} + +export class AStarWater implements PathFinder { + private stamp = 1; + + private readonly closedStamp: Uint32Array; + private readonly gScoreStamp: Uint32Array; + private readonly gScore: Uint32Array; + private readonly cameFrom: Int32Array; + private readonly queue: PriorityQueue; + private readonly terrain: Uint8Array; + private readonly width: number; + private readonly numNodes: number; + private readonly heuristicWeight: number; + private readonly maxIterations: number; + + constructor(map: GameMap, config?: AStarWaterConfig) { + this.terrain = (map as any).terrain as Uint8Array; + this.width = map.width(); + this.numNodes = map.width() * map.height(); + this.heuristicWeight = config?.heuristicWeight ?? 15; + this.maxIterations = config?.maxIterations ?? 1_000_000; + + this.closedStamp = new Uint32Array(this.numNodes); + this.gScoreStamp = new Uint32Array(this.numNodes); + this.gScore = new Uint32Array(this.numNodes); + this.cameFrom = new Int32Array(this.numNodes); + + const maxF = this.heuristicWeight * (map.width() + map.height()); + this.queue = new BucketQueue(maxF); + } + + findPath(start: number | number[], goal: number): number[] | null { + this.stamp++; + if (this.stamp > 0xffffffff) { + this.closedStamp.fill(0); + this.gScoreStamp.fill(0); + this.stamp = 1; + } + + const stamp = this.stamp; + const width = this.width; + const numNodes = this.numNodes; + const terrain = this.terrain; + const closedStamp = this.closedStamp; + const gScoreStamp = this.gScoreStamp; + const gScore = this.gScore; + const cameFrom = this.cameFrom; + const queue = this.queue; + const weight = this.heuristicWeight; + const landMask = 1 << LAND_BIT; + + const goalX = goal % width; + const goalY = (goal / width) | 0; + + queue.clear(); + const starts = Array.isArray(start) ? start : [start]; + for (const s of starts) { + gScore[s] = 0; + gScoreStamp[s] = stamp; + cameFrom[s] = -1; + const sx = s % width; + const sy = (s / width) | 0; + const h = weight * (Math.abs(sx - goalX) + Math.abs(sy - goalY)); + queue.push(s, h); + } + + let iterations = this.maxIterations; + + while (!queue.isEmpty()) { + if (--iterations <= 0) { + return null; + } + + const current = queue.pop(); + + if (closedStamp[current] === stamp) continue; + closedStamp[current] = stamp; + + if (current === goal) { + return this.buildPath(goal); + } + + const currentG = gScore[current]; + const tentativeG = currentG + 1; + const currentX = current % width; + + if (current >= width) { + const neighbor = current - width; + if ( + closedStamp[neighbor] !== stamp && + (neighbor === goal || (terrain[neighbor] & landMask) === 0) + ) { + if ( + gScoreStamp[neighbor] !== stamp || + tentativeG < gScore[neighbor] + ) { + cameFrom[neighbor] = current; + gScore[neighbor] = tentativeG; + gScoreStamp[neighbor] = stamp; + const nx = neighbor % width; + const ny = (neighbor / width) | 0; + const f = + tentativeG + + weight * (Math.abs(nx - goalX) + Math.abs(ny - goalY)); + queue.push(neighbor, f); + } + } + } + + if (current < numNodes - width) { + const neighbor = current + width; + if ( + closedStamp[neighbor] !== stamp && + (neighbor === goal || (terrain[neighbor] & landMask) === 0) + ) { + if ( + gScoreStamp[neighbor] !== stamp || + tentativeG < gScore[neighbor] + ) { + cameFrom[neighbor] = current; + gScore[neighbor] = tentativeG; + gScoreStamp[neighbor] = stamp; + const nx = neighbor % width; + const ny = (neighbor / width) | 0; + const f = + tentativeG + + weight * (Math.abs(nx - goalX) + Math.abs(ny - goalY)); + queue.push(neighbor, f); + } + } + } + + if (currentX !== 0) { + const neighbor = current - 1; + if ( + closedStamp[neighbor] !== stamp && + (neighbor === goal || (terrain[neighbor] & landMask) === 0) + ) { + if ( + gScoreStamp[neighbor] !== stamp || + tentativeG < gScore[neighbor] + ) { + cameFrom[neighbor] = current; + gScore[neighbor] = tentativeG; + gScoreStamp[neighbor] = stamp; + const ny = (neighbor / width) | 0; + const f = + tentativeG + + weight * (Math.abs(currentX - 1 - goalX) + Math.abs(ny - goalY)); + queue.push(neighbor, f); + } + } + } + + if (currentX !== width - 1) { + const neighbor = current + 1; + if ( + closedStamp[neighbor] !== stamp && + (neighbor === goal || (terrain[neighbor] & landMask) === 0) + ) { + if ( + gScoreStamp[neighbor] !== stamp || + tentativeG < gScore[neighbor] + ) { + cameFrom[neighbor] = current; + gScore[neighbor] = tentativeG; + gScoreStamp[neighbor] = stamp; + const ny = (neighbor / width) | 0; + const f = + tentativeG + + weight * (Math.abs(currentX + 1 - goalX) + Math.abs(ny - goalY)); + queue.push(neighbor, f); + } + } + } + } + + return null; + } + + private buildPath(goal: number): TileRef[] { + const path: TileRef[] = []; + let current = goal; + + while (current !== -1) { + path.push(current as TileRef); + current = this.cameFrom[current]; + } + + path.reverse(); + return path; + } +} diff --git a/src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts b/src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts new file mode 100644 index 000000000..019893d6a --- /dev/null +++ b/src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts @@ -0,0 +1,562 @@ +import { GameMap, TileRef } from "../../game/GameMap"; +import { PathFinder } from "../types"; +import { AbstractGraphAStar } from "./AStar.AbstractGraph"; +import { AStarBounded } from "./AStar.Bounded"; +import { AbstractGraph, AbstractNode } from "./AbstractGraph"; +import { BFSGrid } from "./BFS.Grid"; +import { LAND_MARKER } from "./ConnectedComponents"; + +type PathDebugInfo = { + nodePath: TileRef[] | null; + initialPath: TileRef[] | null; + graph: { + clusterSize: number; + nodes: Array<{ id: number; tile: TileRef }>; + edges: Array<{ + id: number; + nodeA: number; + nodeB: number; + from: TileRef; + to: TileRef; + cost: number; + }>; + }; + timings: { [key: string]: number }; +}; + +export class AStarWaterHierarchical implements PathFinder { + private tileBFS: BFSGrid; + private abstractAStar: AbstractGraphAStar; + private localAStar: AStarBounded; + private localAStarMultiCluster: AStarBounded; + private sourceResolver: SourceResolver; + + public debugInfo: PathDebugInfo | null = null; + public debugMode: boolean = false; + + constructor( + private map: GameMap, + private graph: AbstractGraph, + private options: { + cachePaths?: boolean; + } = {}, + ) { + // BFS for nearest node search + this.tileBFS = new BFSGrid(map.width() * map.height()); + + const clusterSize = graph.clusterSize; + + // AbstractGraphAStar for abstract graph routing + this.abstractAStar = new AbstractGraphAStar(this.graph); + + // BoundedAStar for cluster-bounded local pathfinding + const maxLocalNodes = clusterSize * clusterSize; + this.localAStar = new AStarBounded(map, maxLocalNodes); + + // BoundedAStar for multi-cluster (3x3) local pathfinding + const multiClusterSize = clusterSize * 3; + const maxMultiClusterNodes = multiClusterSize * multiClusterSize; + this.localAStarMultiCluster = new AStarBounded(map, maxMultiClusterNodes); + + // SourceResolver for multi-source search + this.sourceResolver = new SourceResolver(this.map, this.graph); + } + + findPath(from: number | number[], to: number): number[] | null { + if (Array.isArray(from)) { + return this.findPathMultiSource(from as TileRef[], to as TileRef); + } + + return this.findPathSingle(from as TileRef, to as TileRef, this.debugMode); + } + + private findPathMultiSource( + sources: TileRef[], + target: TileRef, + ): TileRef[] | null { + // 1. Resolve target to abstract node + const targetNode = this.sourceResolver.resolveTarget(target); + if (!targetNode) return null; + + // 2. Map sources → abstract nodes (cheap O(1) cluster lookup per source) + const nodeToSource = this.sourceResolver.resolveSourcesToNodes(sources); + if (nodeToSource.size === 0) return null; + + // 3. Run multi-source A* on abstract graph + const nodeIds = [...nodeToSource.keys()]; + const nodePath = this.abstractAStar.findPath(nodeIds, targetNode.id); + if (!nodePath) return null; + + // 4. Get winning source tile (nodePath[0] is winning start node) + const winningSource = nodeToSource.get(nodePath[0])!; + + // 5. Run full single-source from winner + return this.findPathSingle(winningSource, target); + } + + findPathSingle( + from: TileRef, + to: TileRef, + debug: boolean = false, + ): TileRef[] | null { + if (debug) { + const allEdges: Array<{ + id: number; + nodeA: number; + nodeB: number; + from: TileRef; + to: TileRef; + cost: number; + }> = []; + + for (let edgeId = 0; edgeId < this.graph.edgeCount; edgeId++) { + const edge = this.graph.getEdge(edgeId); + if (!edge) continue; + + const nodeA = this.graph.getNode(edge.nodeA); + const nodeB = this.graph.getNode(edge.nodeB); + if (!nodeA || !nodeB) continue; + + allEdges.push({ + id: edge.id, + nodeA: edge.nodeA, + nodeB: edge.nodeB, + from: nodeA.tile, + to: nodeB.tile, + cost: edge.cost, + }); + } + + this.debugInfo = { + nodePath: null, + initialPath: null, + graph: { + clusterSize: this.graph.clusterSize, + nodes: this.graph + .getAllNodes() + .map((node) => ({ id: node.id, tile: node.tile })), + edges: allEdges, + }, + timings: { + total: 0, + }, + }; + } + + const dist = this.map.manhattanDist(from, to); + + // Early exit for very short distances + if (dist <= this.graph.clusterSize) { + performance.mark("hpa:findPath:earlyExitLocalPath:start"); + const startX = this.map.x(from); + const startY = this.map.y(from); + const clusterX = Math.floor(startX / this.graph.clusterSize); + const clusterY = Math.floor(startY / this.graph.clusterSize); + const localPath = this.findLocalPath(from, to, clusterX, clusterY, true); + performance.mark("hpa:findPath:earlyExitLocalPath:end"); + const measure = performance.measure( + "hpa:findPath:earlyExitLocalPath", + "hpa:findPath:earlyExitLocalPath:start", + "hpa:findPath:earlyExitLocalPath:end", + ); + + if (debug) { + this.debugInfo!.timings.earlyExitLocalPath = measure.duration; + this.debugInfo!.timings.total += measure.duration; + } + + if (localPath) { + if (debug) { + console.log( + `[DEBUG] Direct local path found for dist=${dist}, length=${localPath.length}`, + ); + } + return localPath; + } + + if (debug) { + console.log( + `[DEBUG] Direct path failed for dist=${dist}, falling back to abstract graph`, + ); + } + } + + performance.mark("hpa:findPath:findNodes:start"); + const startNode = this.findNearestNode(from); + const endNode = this.findNearestNode(to); + performance.mark("hpa:findPath:findNodes:end"); + const findNodesMeasure = performance.measure( + "hpa:findPath:findNodes", + "hpa:findPath:findNodes:start", + "hpa:findPath:findNodes:end", + ); + + if (debug) { + this.debugInfo!.timings.findNodes = findNodesMeasure.duration; + this.debugInfo!.timings.total += findNodesMeasure.duration; + } + + if (!startNode) { + if (debug) { + console.log( + `[DEBUG] Cannot find start node for (${this.map.x(from)}, ${this.map.y(from)})`, + ); + } + return null; + } + + if (!endNode) { + if (debug) { + console.log( + `[DEBUG] Cannot find end node for (${this.map.x(to)}, ${this.map.y(to)})`, + ); + } + return null; + } + + if (startNode.id === endNode.id) { + if (debug) { + console.log( + `[DEBUG] Start and end nodes are the same (ID=${startNode.id}), finding local path with multi-cluster search`, + ); + } + + performance.mark("hpa:findPath:sameNodeLocalPath:start"); + const clusterX = Math.floor(startNode.x / this.graph.clusterSize); + const clusterY = Math.floor(startNode.y / this.graph.clusterSize); + const path = this.findLocalPath(from, to, clusterX, clusterY, true); + performance.mark("hpa:findPath:sameNodeLocalPath:end"); + const sameNodeMeasure = performance.measure( + "hpa:findPath:sameNodeLocalPath", + "hpa:findPath:sameNodeLocalPath:start", + "hpa:findPath:sameNodeLocalPath:end", + ); + + if (debug) { + this.debugInfo!.timings.sameNodeLocalPath = sameNodeMeasure.duration; + this.debugInfo!.timings.total += sameNodeMeasure.duration; + } + + return path; + } + + performance.mark("hpa:findPath:findAbstractPath:start"); + const nodePath = this.findAbstractPath(startNode.id, endNode.id); + performance.mark("hpa:findPath:findAbstractPath:end"); + const findAbstractPathMeasure = performance.measure( + "hpa:findPath:findAbstractPath", + "hpa:findPath:findAbstractPath:start", + "hpa:findPath:findAbstractPath:end", + ); + + if (debug) { + this.debugInfo!.timings.findAbstractPath = + findAbstractPathMeasure.duration; + this.debugInfo!.timings.total += findAbstractPathMeasure.duration; + + this.debugInfo!.nodePath = nodePath + ? nodePath + .map((nodeId) => { + const node = this.graph.getNode(nodeId); + return node ? node.tile : -1; + }) + .filter((tile) => tile !== -1) + : null; + } + + if (!nodePath) { + if (debug) { + console.log( + `[DEBUG] No abstract path between nodes ${startNode.id} and ${endNode.id}`, + ); + } + return null; + } + + if (debug) { + console.log(`[DEBUG] Abstract path found: ${nodePath.length} waypoints`); + } + + const initialPath: TileRef[] = []; + + performance.mark("hpa:findPath:buildInitialPath:start"); + + // 1. Find path from start to first node + const firstNode = this.graph.getNode(nodePath[0])!; + const firstNodeTile = firstNode.tile; + + const startX = this.map.x(from); + const startY = this.map.y(from); + const startClusterX = Math.floor(startX / this.graph.clusterSize); + const startClusterY = Math.floor(startY / this.graph.clusterSize); + const startSegment = this.findLocalPath( + from, + firstNodeTile, + startClusterX, + startClusterY, + ); + + if (!startSegment) { + return null; + } + + initialPath.push(...startSegment); + + // 2. Build path through abstract nodes + for (let i = 0; i < nodePath.length - 1; i++) { + const fromNodeId = nodePath[i]; + const toNodeId = nodePath[i + 1]; + + const edge = this.graph.getEdgeBetween(fromNodeId, toNodeId); + if (!edge) { + return null; + } + + const fromNode = this.graph.getNode(fromNodeId)!; + const toNode = this.graph.getNode(toNodeId)!; + const fromTile = fromNode.tile; + const toTile = toNode.tile; + + // Check path cache (stored on graph, shared across all instances) + // Cache is direction-aware: A→B and B→A are cached separately + if (this.options.cachePaths) { + const cachedPath = this.graph.getCachedPath(edge.id, fromNodeId); + if (cachedPath && cachedPath.length > 0) { + // Path is cached for this exact direction, use as-is + initialPath.push(...cachedPath.slice(1)); + continue; + } + } + + const segmentPath = this.findLocalPath( + fromTile, + toTile, + edge.clusterX, + edge.clusterY, + ); + + if (!segmentPath) { + return null; + } + + initialPath.push(...segmentPath.slice(1)); + + // Cache the path for this direction + if (this.options.cachePaths) { + this.graph.setCachedPath(edge.id, fromNodeId, segmentPath); + } + } + + // 3. Find path from last node to end + const lastNode = this.graph.getNode(nodePath[nodePath.length - 1])!; + const lastNodeTile = lastNode.tile; + + const endX = this.map.x(to); + const endY = this.map.y(to); + const endClusterX = Math.floor(endX / this.graph.clusterSize); + const endClusterY = Math.floor(endY / this.graph.clusterSize); + const endSegment = this.findLocalPath( + lastNodeTile, + to, + endClusterX, + endClusterY, + ); + + if (!endSegment) { + return null; + } + + initialPath.push(...endSegment.slice(1)); + + performance.mark("hpa:findPath:buildInitialPath:end"); + const buildInitialPathMeasure = performance.measure( + "hpa:findPath:buildInitialPath", + "hpa:findPath:buildInitialPath:start", + "hpa:findPath:buildInitialPath:end", + ); + + if (debug) { + this.debugInfo!.timings.buildInitialPath = + buildInitialPathMeasure.duration; + this.debugInfo!.timings.total += buildInitialPathMeasure.duration; + this.debugInfo!.initialPath = initialPath; + console.log(`[DEBUG] Initial path: ${initialPath.length} tiles`); + } + + // Smoothing moved to SmoothingTransformer - return raw path + return initialPath; + } + + private findNearestNode(tile: TileRef): AbstractNode | null { + const x = this.map.x(tile); + const y = this.map.y(tile); + + const clusterX = Math.floor(x / this.graph.clusterSize); + const clusterY = Math.floor(y / this.graph.clusterSize); + + const clusterSize = this.graph.clusterSize; + const minX = clusterX * clusterSize; + const minY = clusterY * clusterSize; + const maxX = Math.min(this.map.width() - 1, minX + clusterSize - 1); + const maxY = Math.min(this.map.height() - 1, minY + clusterSize - 1); + + const cluster = this.graph.getCluster(clusterX, clusterY); + if (!cluster || cluster.nodeIds.length === 0) { + return null; + } + + const candidateNodes = cluster.nodeIds.map((id) => this.graph.getNode(id)!); + const maxDistance = clusterSize * clusterSize; + + return this.tileBFS.search( + this.map.width(), + this.map.height(), + tile, + maxDistance, + (t: TileRef) => this.graph.getComponentId(t) !== LAND_MARKER, + (t: TileRef, _dist: number) => { + const tileX = this.map.x(t); + const tileY = this.map.y(t); + + for (const node of candidateNodes) { + if (node.x === tileX && node.y === tileY) { + return node; + } + } + + if (tileX < minX || tileX > maxX || tileY < minY || tileY > maxY) { + return null; + } + }, + ); + } + + private findAbstractPath( + fromNodeId: number, + toNodeId: number, + ): number[] | null { + return this.abstractAStar.findPath(fromNodeId, toNodeId); + } + + private findLocalPath( + from: TileRef, + to: TileRef, + clusterX: number, + clusterY: number, + multiCluster: boolean = false, + ): TileRef[] | null { + // Calculate cluster bounds + const clusterSize = this.graph.clusterSize; + + let minX: number; + let minY: number; + let maxX: number; + let maxY: number; + + if (multiCluster) { + // 3×3 clusters centered on the starting cluster + minX = Math.max(0, (clusterX - 1) * clusterSize); + minY = Math.max(0, (clusterY - 1) * clusterSize); + maxX = Math.min(this.map.width() - 1, (clusterX + 2) * clusterSize - 1); + maxY = Math.min(this.map.height() - 1, (clusterY + 2) * clusterSize - 1); + } else { + minX = clusterX * clusterSize; + minY = clusterY * clusterSize; + maxX = Math.min(this.map.width() - 1, minX + clusterSize - 1); + maxY = Math.min(this.map.height() - 1, minY + clusterSize - 1); + } + + // Choose the appropriate BoundedAStar based on search area + const selectedAStar = multiCluster + ? this.localAStarMultiCluster + : this.localAStar; + + // Run BoundedAStar on bounded region - works directly on map coords + const path = selectedAStar.searchBounded(from, to, { + minX, + maxX, + minY, + maxY, + }); + + if (!path || path.length === 0) { + return null; + } + + // Fix endpoints: BoundedAStar clamps tiles to bounds, but node tiles may be + // just outside cluster bounds. Ensure path starts/ends at exact requested tiles. + if (path[0] !== from) { + path.unshift(from); + } + if (path[path.length - 1] !== to) { + path.push(to); + } + + return path; + } +} + +// Helper class for resolving tiles to abstract nodes +// Assumes tiles are already water and component-filtered (by transformer pipeline) +class SourceResolver { + constructor( + private map: GameMap, + private graph: AbstractGraph, + ) {} + + // Resolves target to its abstract node + resolveTarget(target: TileRef): AbstractNode | null { + return this.getClusterNode(target); + } + + // Maps sources → abstract nodes, returns Map + resolveSourcesToNodes(sources: TileRef[]): Map { + const nodeToSource = new Map(); + const nodeToDist = new Map(); + + for (const source of sources) { + const node = this.getClusterNode(source); + if (node === null) continue; + + const x = this.map.x(source); + const y = this.map.y(source); + const dist = Math.abs(node.x - x) + Math.abs(node.y - y); + + // Keep closest source per node + const prevDist = nodeToDist.get(node.id); + if (prevDist === undefined || dist < prevDist) { + nodeToSource.set(node.id, source); + nodeToDist.set(node.id, dist); + } + } + + return nodeToSource; + } + + private getClusterNode(tile: TileRef): AbstractNode | null { + const x = this.map.x(tile); + const y = this.map.y(tile); + const clusterX = Math.floor(x / this.graph.clusterSize); + const clusterY = Math.floor(y / this.graph.clusterSize); + + const cluster = this.graph.getCluster(clusterX, clusterY); + if (!cluster || cluster.nodeIds.length === 0) return null; + + // Return closest node to tile + let bestNode: AbstractNode | null = null; + let bestDist = Infinity; + + for (const nodeId of cluster.nodeIds) { + const node = this.graph.getNode(nodeId); + if (!node) continue; + + const dist = Math.abs(node.x - x) + Math.abs(node.y - y); + if (dist < bestDist) { + bestDist = dist; + bestNode = node; + } + } + + return bestNode; + } +} diff --git a/src/core/pathfinding/algorithms/AStar.ts b/src/core/pathfinding/algorithms/AStar.ts new file mode 100644 index 000000000..bb8fe405d --- /dev/null +++ b/src/core/pathfinding/algorithms/AStar.ts @@ -0,0 +1,127 @@ +// Generic A* implementation with adapter interface +// See AStar.Rail.ts for adapter version where performance is not critical +// See AStar.Water.ts for inlined version for performance-critical use + +import { PathFinder } from "../types"; +import { BucketQueue, PriorityQueue } from "./PriorityQueue"; + +export interface AStarAdapter { + // Important optimization: write to the buffer and return the count + // You can do this and it will be much faster :) + neighbors(node: number, buffer: Int32Array): number; + + cost(from: number, to: number, prev?: number): number; + heuristic(node: number, goal: number): number; + numNodes(): number; + maxPriority(): number; + maxNeighbors(): number; +} + +export interface AStarConfig { + adapter: AStarAdapter; + maxIterations?: number; +} + +export class AStar implements PathFinder { + private stamp = 1; + + private readonly closedStamp: Uint32Array; + private readonly gScoreStamp: Uint32Array; + private readonly gScore: Uint32Array; + private readonly cameFrom: Int32Array; + private readonly queue: PriorityQueue; + private readonly adapter: AStarAdapter; + private readonly neighborBuffer: Int32Array; + private readonly maxIterations: number; + + constructor(config: AStarConfig) { + this.adapter = config.adapter; + this.maxIterations = config.maxIterations ?? 500_000; + this.neighborBuffer = new Int32Array(this.adapter.maxNeighbors()); + this.closedStamp = new Uint32Array(this.adapter.numNodes()); + this.gScoreStamp = new Uint32Array(this.adapter.numNodes()); + this.gScore = new Uint32Array(this.adapter.numNodes()); + this.cameFrom = new Int32Array(this.adapter.numNodes()); + this.queue = new BucketQueue(this.adapter.maxPriority()); + } + + findPath(start: number | number[], goal: number): number[] | null { + this.stamp++; + if (this.stamp > 0xffffffff) { + this.closedStamp.fill(0); + this.gScoreStamp.fill(0); + this.stamp = 1; + } + + const stamp = this.stamp; + const adapter = this.adapter; + const closedStamp = this.closedStamp; + const gScoreStamp = this.gScoreStamp; + const gScore = this.gScore; + const cameFrom = this.cameFrom; + const queue = this.queue; + const buffer = this.neighborBuffer; + + queue.clear(); + const starts = Array.isArray(start) ? start : [start]; + for (const s of starts) { + gScore[s] = 0; + gScoreStamp[s] = stamp; + cameFrom[s] = -1; + queue.push(s, adapter.heuristic(s, goal)); + } + + let iterations = this.maxIterations; + + while (!queue.isEmpty()) { + if (--iterations <= 0) { + return null; + } + + const current = queue.pop(); + + if (closedStamp[current] === stamp) continue; + closedStamp[current] = stamp; + + if (current === goal) { + return this.buildPath(goal); + } + + const currentG = gScore[current]; + const prev = cameFrom[current]; + const count = adapter.neighbors(current, buffer); + + for (let i = 0; i < count; i++) { + const neighbor = buffer[i]; + + if (closedStamp[neighbor] === stamp) continue; + + const tentativeG = + currentG + + adapter.cost(current, neighbor, prev === -1 ? undefined : prev); + + if (gScoreStamp[neighbor] !== stamp || tentativeG < gScore[neighbor]) { + cameFrom[neighbor] = current; + gScore[neighbor] = tentativeG; + gScoreStamp[neighbor] = stamp; + queue.push(neighbor, tentativeG + adapter.heuristic(neighbor, goal)); + } + } + } + + return null; + } + + private buildPath(goal: number): number[] { + const path: number[] = []; + let current = goal; + + while (current !== -1) { + path.push(current); + current = this.cameFrom[current]; + } + + path.reverse(); + return path; + } +} diff --git a/src/core/pathfinding/algorithms/AbstractGraph.ts b/src/core/pathfinding/algorithms/AbstractGraph.ts new file mode 100644 index 000000000..d7be8faeb --- /dev/null +++ b/src/core/pathfinding/algorithms/AbstractGraph.ts @@ -0,0 +1,682 @@ +import { GameMap, TileRef } from "../../game/GameMap"; +import { BFSGrid } from "./BFS.Grid"; +import { ConnectedComponents } from "./ConnectedComponents"; + +export interface AbstractNode { + id: number; + x: number; + y: number; + tile: TileRef; + componentId: number; +} + +export interface AbstractEdge { + id: number; + nodeA: number; // Lower node ID (canonical order: nodeA < nodeB) + nodeB: number; // Higher node ID + cost: number; + clusterX: number; + clusterY: number; +} + +export interface Cluster { + x: number; + y: number; + nodeIds: number[]; +} + +export type BuildDebugInfo = { + clusters: number | null; + nodes: number | null; + edges: number | null; + actualBFSCalls: number | null; + potentialBFSCalls: number | null; + skippedByComponentFilter: number | null; + timings: { [key: string]: number }; +}; + +export class AbstractGraph { + // Nodes (array indexed by id) + private readonly _nodes: AbstractNode[] = []; + + // Edges (bidirectional, stored once) + private readonly _edges: AbstractEdge[] = []; + private readonly _nodeEdgeIds: number[][] = []; // nodeId → edge IDs + + // Clusters (array indexed by clusterKey) + private readonly _clusters: Cluster[] = []; + + // Path cache indexed by edge.id (shared across all users) + private _pathCache: (TileRef[] | null)[] = []; + + // Water components for componentId lookup + private _waterComponents: ConnectedComponents | null = null; + + constructor( + readonly clusterSize: number, + readonly clustersX: number, + readonly clustersY: number, + ) {} + + getNode(id: number): AbstractNode | undefined { + return this._nodes[id]; + } + + getAllNodes(): readonly AbstractNode[] { + return this._nodes; + } + + get nodeCount(): number { + return this._nodes.length; + } + + getEdge(id: number): AbstractEdge | undefined { + return this._edges[id]; + } + + getNodeEdges(nodeId: number): AbstractEdge[] { + const edgeIds = this._nodeEdgeIds[nodeId]; + if (!edgeIds) return []; + return edgeIds.map((id) => this._edges[id]); + } + + getEdgeBetween(nodeA: number, nodeB: number): AbstractEdge | undefined { + const edgeIds = this._nodeEdgeIds[nodeA]; + if (!edgeIds) return undefined; + + for (const edgeId of edgeIds) { + const edge = this._edges[edgeId]; + if (edge.nodeA === nodeB || edge.nodeB === nodeB) { + return edge; + } + } + return undefined; + } + + getOtherNode(edge: AbstractEdge, nodeId: number): number { + return edge.nodeA === nodeId ? edge.nodeB : edge.nodeA; + } + + get edgeCount(): number { + return this._edges.length; + } + + /** + * Get cached path for edge in specific direction + * @param edgeId Edge ID + * @param fromNodeId The starting node of the traversal (determines direction) + */ + getCachedPath(edgeId: number, fromNodeId: number): TileRef[] | null { + const edge = this._edges[edgeId]; + if (!edge) return null; + // Direction: 0 if traversing A→B, 1 if traversing B→A + const direction = fromNodeId === edge.nodeA ? 0 : 1; + const cacheIndex = edgeId * 2 + direction; + return this._pathCache[cacheIndex] ?? null; + } + + /** + * Cache path for edge in specific direction + * @param edgeId Edge ID + * @param fromNodeId The starting node of the traversal (determines direction) + * @param path The path tiles + */ + setCachedPath(edgeId: number, fromNodeId: number, path: TileRef[]): void { + const edge = this._edges[edgeId]; + if (!edge) return; + // Direction: 0 if traversing A→B, 1 if traversing B→A + const direction = fromNodeId === edge.nodeA ? 0 : 1; + const cacheIndex = edgeId * 2 + direction; + this._pathCache[cacheIndex] = path; + } + + _initPathCache(): void { + // Double the cache size to store both directions + this._pathCache = new Array(this._edges.length * 2).fill(null); + } + + setWaterComponents(wc: ConnectedComponents): void { + this._waterComponents = wc; + } + + getComponentId(tile: TileRef): number { + return this._waterComponents?.getComponentId(tile) ?? 0; + } + + getClusterKey(clusterX: number, clusterY: number): number { + return clusterY * this.clustersX + clusterX; + } + + getCluster(clusterX: number, clusterY: number): Cluster | undefined { + return this._clusters[this.getClusterKey(clusterX, clusterY)]; + } + + getClusterNodes(clusterX: number, clusterY: number): AbstractNode[] { + const cluster = this.getCluster(clusterX, clusterY); + if (!cluster) return []; + return cluster.nodeIds.map((id) => this._nodes[id]); + } + + getNearbyClusterNodes(clusterX: number, clusterY: number): AbstractNode[] { + const nodes: AbstractNode[] = []; + + for (let dy = -1; dy <= 1; dy++) { + for (let dx = -1; dx <= 1; dx++) { + const cluster = this.getCluster(clusterX + dx, clusterY + dy); + if (cluster) { + for (const nodeId of cluster.nodeIds) { + nodes.push(this._nodes[nodeId]); + } + } + } + } + + return nodes; + } + + _addNode(node: AbstractNode): void { + this._nodes[node.id] = node; + this._nodeEdgeIds[node.id] = []; + } + + _addEdge(edge: AbstractEdge): void { + this._edges[edge.id] = edge; + this._nodeEdgeIds[edge.nodeA].push(edge.id); + this._nodeEdgeIds[edge.nodeB].push(edge.id); + } + + _setCluster(key: number, cluster: Cluster): void { + this._clusters[key] = cluster; + } + + _addNodeToCluster(clusterKey: number, nodeId: number): void { + if (!this._clusters[clusterKey]) { + // This shouldn't happen if clusters are pre-created + return; + } + + this._clusters[clusterKey].nodeIds.push(nodeId); + } +} + +export class AbstractGraphBuilder { + static readonly CLUSTER_SIZE = 32; + + // Derived immutable state + private readonly width: number; + private readonly height: number; + private readonly clustersX: number; + private readonly clustersY: number; + private readonly tileBFS: BFSGrid; + private readonly waterComponents: ConnectedComponents; + + // Build state + private graph!: AbstractGraph; + private tileToNode = new Map(); + private nextNodeId = 0; + private nextEdgeId = 0; + private edgeBetween = new Map>(); + + public debugInfo: BuildDebugInfo | null = null; + + constructor( + private readonly map: GameMap, + private readonly clusterSize: number = AbstractGraphBuilder.CLUSTER_SIZE, + ) { + this.width = map.width(); + this.height = map.height(); + this.clustersX = Math.ceil(this.width / clusterSize); + this.clustersY = Math.ceil(this.height / clusterSize); + this.tileBFS = new BFSGrid(this.width * this.height); + this.waterComponents = new ConnectedComponents(map); + } + + build(debug: boolean = false): AbstractGraph { + performance.mark("abstractgraph:build:start"); + + this.graph = new AbstractGraph( + this.clusterSize, + this.clustersX, + this.clustersY, + ); + + if (debug) { + console.log( + `[DEBUG] Building abstract graph with cluster size ${this.clusterSize} (${this.clustersX}x${this.clustersY} clusters)`, + ); + + this.debugInfo = { + clusters: null, + nodes: null, + edges: null, + actualBFSCalls: null, + potentialBFSCalls: null, + skippedByComponentFilter: null, + timings: {}, + }; + } + + // Initialize water components + performance.mark("abstractgraph:build:water-component:start"); + this.waterComponents.initialize(); + performance.mark("abstractgraph:build:water-component:end"); + const wcMeasure = performance.measure( + "abstractgraph:build:water-component", + "abstractgraph:build:water-component:start", + "abstractgraph:build:water-component:end", + ); + + if (debug) { + console.log( + `[DEBUG] Water Component Identification: ${wcMeasure.duration.toFixed(2)}ms`, + ); + } + + // Pre-create all clusters + for (let cy = 0; cy < this.clustersY; cy++) { + for (let cx = 0; cx < this.clustersX; cx++) { + const key = this.graph.getClusterKey(cx, cy); + this.graph._setCluster(key, { x: cx, y: cy, nodeIds: [] }); + } + } + + // Find nodes (gateways) at cluster boundaries + performance.mark("abstractgraph:build:nodes:start"); + for (let cy = 0; cy < this.clustersY; cy++) { + for (let cx = 0; cx < this.clustersX; cx++) { + this.processCluster(cx, cy); + } + } + performance.mark("abstractgraph:build:nodes:end"); + const nodesMeasure = performance.measure( + "abstractgraph:build:nodes", + "abstractgraph:build:nodes:start", + "abstractgraph:build:nodes:end", + ); + + if (debug) { + console.log( + `[DEBUG] Node identification: ${nodesMeasure.duration.toFixed(2)}ms`, + ); + this.debugInfo!.potentialBFSCalls = 0; + this.debugInfo!.skippedByComponentFilter = 0; + } + + // Build edges between nodes in same cluster + performance.mark("abstractgraph:build:edges:start"); + for (let cy = 0; cy < this.clustersY; cy++) { + for (let cx = 0; cx < this.clustersX; cx++) { + const cluster = this.graph.getCluster(cx, cy); + if (!cluster || cluster.nodeIds.length === 0) continue; + + if (debug) { + const n = cluster.nodeIds.length; + this.debugInfo!.potentialBFSCalls! += (n * (n - 1)) / 2; + + // Count skipped by component filter + for (let i = 0; i < n; i++) { + for (let j = i + 1; j < n; j++) { + const nodeI = this.graph.getNode(cluster.nodeIds[i])!; + const nodeJ = this.graph.getNode(cluster.nodeIds[j])!; + if (nodeI.componentId !== nodeJ.componentId) { + this.debugInfo!.skippedByComponentFilter!++; + } + } + } + } + + this.buildClusterConnections(cx, cy); + } + } + performance.mark("abstractgraph:build:edges:end"); + const edgesMeasure = performance.measure( + "abstractgraph:build:edges", + "abstractgraph:build:edges:start", + "abstractgraph:build:edges:end", + ); + + if (debug) { + this.debugInfo!.actualBFSCalls = + this.debugInfo!.potentialBFSCalls! - + this.debugInfo!.skippedByComponentFilter!; + + console.log( + `[DEBUG] Edge identification: ${edgesMeasure.duration.toFixed(2)}ms`, + ); + console.log( + `[DEBUG] Potential BFS calls: ${this.debugInfo!.potentialBFSCalls}`, + ); + console.log( + `[DEBUG] Skipped by component filter: ${this.debugInfo!.skippedByComponentFilter} (${((this.debugInfo!.skippedByComponentFilter! / this.debugInfo!.potentialBFSCalls!) * 100).toFixed(1)}%)`, + ); + console.log( + `[DEBUG] Actual BFS calls: ${this.debugInfo!.actualBFSCalls}`, + ); + } + + performance.mark("abstractgraph:build:end"); + const totalMeasure = performance.measure( + "abstractgraph:build:total", + "abstractgraph:build:start", + "abstractgraph:build:end", + ); + + if (debug) { + console.log( + `[DEBUG] Abstract graph built in ${totalMeasure.duration.toFixed(2)}ms`, + ); + console.log(`[DEBUG] Nodes: ${this.graph.nodeCount}`); + console.log(`[DEBUG] Edges: ${this.graph.edgeCount}`); + console.log(`[DEBUG] Clusters: ${this.clustersX * this.clustersY}`); + + this.debugInfo!.clusters = this.clustersX * this.clustersY; + this.debugInfo!.nodes = this.graph.nodeCount; + this.debugInfo!.edges = this.graph.edgeCount; + } + + // Initialize path cache after all edges are built + this.graph._initPathCache(); + + // Store water components for componentId lookups + this.graph.setWaterComponents(this.waterComponents); + + return this.graph; + } + + private getOrCreateNode(x: number, y: number): AbstractNode { + const tile = this.map.ref(x, y); + + const existing = this.tileToNode.get(tile); + if (existing) { + return existing; + } + + const node: AbstractNode = { + id: this.nextNodeId++, + x, + y, + tile, + componentId: this.waterComponents.getComponentId(tile), + }; + + this.graph._addNode(node); + this.tileToNode.set(tile, node); + return node; + } + + private addNodeToCluster( + clusterX: number, + clusterY: number, + node: AbstractNode, + ): void { + const cluster = this.graph.getCluster(clusterX, clusterY); + if (!cluster) return; + + // Check for duplicates (node at cluster corner can be found by both edge scans) + if (!cluster.nodeIds.includes(node.id)) { + cluster.nodeIds.push(node.id); + } + } + + private processCluster(cx: number, cy: number): void { + const baseX = cx * this.clusterSize; + const baseY = cy * this.clusterSize; + + // Right edge (vertical boundary to next cluster) + if (cx < this.clustersX - 1) { + const edgeX = Math.min(baseX + this.clusterSize - 1, this.width - 1); + const nodes = this.findNodesOnVerticalEdge(edgeX, baseY); + + for (const node of nodes) { + this.addNodeToCluster(cx, cy, node); + this.addNodeToCluster(cx + 1, cy, node); + } + } + + // Bottom edge (horizontal boundary to next cluster) + if (cy < this.clustersY - 1) { + const edgeY = Math.min(baseY + this.clusterSize - 1, this.height - 1); + const nodes = this.findNodesOnHorizontalEdge(edgeY, baseX); + + for (const node of nodes) { + this.addNodeToCluster(cx, cy, node); + this.addNodeToCluster(cx, cy + 1, node); + } + } + } + + private findNodesOnVerticalEdge(x: number, baseY: number): AbstractNode[] { + const nodes: AbstractNode[] = []; + const maxY = Math.min(baseY + this.clusterSize, this.height); + + let spanStart = -1; + + const tryAddNode = (y: number) => { + if (spanStart === -1) return; + + const spanLength = y - spanStart; + const midY = spanStart + Math.floor(spanLength / 2); + spanStart = -1; + + const node = this.getOrCreateNode(x, midY); + nodes.push(node); + }; + + for (let y = baseY; y < maxY; y++) { + const tile = this.map.ref(x, y); + const nextTile = x + 1 < this.map.width() ? this.map.ref(x + 1, y) : -1; + const isEntrance = + this.map.isWater(tile) && nextTile !== -1 && this.map.isWater(nextTile); + + if (isEntrance) { + if (spanStart === -1) { + spanStart = y; + } + } else { + tryAddNode(y); + } + } + + tryAddNode(maxY); + return nodes; + } + + private findNodesOnHorizontalEdge(y: number, baseX: number): AbstractNode[] { + const nodes: AbstractNode[] = []; + const maxX = Math.min(baseX + this.clusterSize, this.width); + + let spanStart = -1; + + const tryAddNode = (x: number) => { + if (spanStart === -1) return; + + const spanLength = x - spanStart; + const midX = spanStart + Math.floor(spanLength / 2); + spanStart = -1; + + const node = this.getOrCreateNode(midX, y); + nodes.push(node); + }; + + for (let x = baseX; x < maxX; x++) { + const tile = this.map.ref(x, y); + const nextTile = y + 1 < this.map.height() ? this.map.ref(x, y + 1) : -1; + const isEntrance = + this.map.isWater(tile) && nextTile !== -1 && this.map.isWater(nextTile); + + if (isEntrance) { + if (spanStart === -1) { + spanStart = x; + } + } else { + tryAddNode(x); + } + } + + tryAddNode(maxX); + return nodes; + } + + private buildClusterConnections(cx: number, cy: number): void { + const cluster = this.graph.getCluster(cx, cy); + if (!cluster) return; + + const nodeIds = cluster.nodeIds; + const nodes = nodeIds.map((id) => this.graph.getNode(id)!); + + // Calculate cluster bounds + const clusterMinX = cx * this.clusterSize; + const clusterMinY = cy * this.clusterSize; + const clusterMaxX = Math.min( + this.width - 1, + clusterMinX + this.clusterSize - 1, + ); + const clusterMaxY = Math.min( + this.height - 1, + clusterMinY + this.clusterSize - 1, + ); + + for (let i = 0; i < nodes.length; i++) { + const fromNode = nodes[i]; + + // Build list of target nodes (only those we haven't processed with this node) + const targetNodes: AbstractNode[] = []; + for (let j = i + 1; j < nodes.length; j++) { + // Skip if nodes are in different water components + if (nodes[i].componentId !== nodes[j].componentId) { + continue; + } + targetNodes.push(nodes[j]); + } + + if (targetNodes.length === 0) continue; + + // Single BFS to find all reachable target nodes + const reachable = this.findAllReachableNodesInBounds( + fromNode.tile, + targetNodes, + clusterMinX, + clusterMaxX, + clusterMinY, + clusterMaxY, + ); + + // Create edges for all reachable nodes + for (const [targetId, cost] of reachable.entries()) { + this.addOrUpdateEdge(fromNode.id, targetId, cost, cx, cy); + } + } + } + + /** + * Add or update edge between two nodes. + * Edges are bidirectional and stored once with canonical order (nodeA < nodeB). + * If edge exists with higher cost, update it. + */ + private addOrUpdateEdge( + nodeIdA: number, + nodeIdB: number, + cost: number, + clusterX: number, + clusterY: number, + ): void { + // Canonical order: lower ID first + const [lo, hi] = + nodeIdA < nodeIdB ? [nodeIdA, nodeIdB] : [nodeIdB, nodeIdA]; + + // Check for existing edge + let nodeMap = this.edgeBetween.get(lo); + if (!nodeMap) { + nodeMap = new Map(); + this.edgeBetween.set(lo, nodeMap); + } + + const existingEdge = nodeMap.get(hi); + + if (existingEdge) { + // Update if new cost is cheaper + if (cost < existingEdge.cost) { + existingEdge.cost = cost; + existingEdge.clusterX = clusterX; + existingEdge.clusterY = clusterY; + } + return; + } + + // Create new edge + const edge: AbstractEdge = { + id: this.nextEdgeId++, + nodeA: lo, + nodeB: hi, + cost, + clusterX, + clusterY, + }; + + nodeMap.set(hi, edge); + this.graph._addEdge(edge); + } + + private findAllReachableNodesInBounds( + from: TileRef, + targetNodes: AbstractNode[], + minX: number, + maxX: number, + minY: number, + maxY: number, + ): Map { + const fromX = this.map.x(from); + const fromY = this.map.y(from); + + // Create a map of tile positions to node IDs for fast lookup + const tileToNodeId = new Map(); + let maxManhattanDist = 0; + + for (const node of targetNodes) { + tileToNodeId.set(node.tile, node.id); + const dx = Math.abs(node.x - fromX); + const dy = Math.abs(node.y - fromY); + maxManhattanDist = Math.max(maxManhattanDist, dx + dy); + } + + const maxDistance = maxManhattanDist * 4; // Allow path deviation + const reachable = new Map(); + let foundCount = 0; + + this.tileBFS.search( + this.map.width(), + this.map.height(), + from, + maxDistance, + (tile: number) => this.map.isWater(tile), + (tile: number, dist: number) => { + const x = this.map.x(tile); + const y = this.map.y(tile); + + // Reject if outside of bounding box (except start/target) + const isStartOrTarget = tile === from || tileToNodeId.has(tile); + if ( + !isStartOrTarget && + (x < minX || x > maxX || y < minY || y > maxY) + ) { + return null; + } + + // Check if this tile is one of our target nodes + const nodeId = tileToNodeId.get(tile); + + if (nodeId !== undefined) { + reachable.set(nodeId, dist); + foundCount++; + + // Early exit if we've found all target nodes + if (foundCount === targetNodes.length) { + return dist; // Return to stop BFS + } + } + }, + ); + + return reachable; + } +} diff --git a/src/core/pathfinding/navmesh/FastBFS.ts b/src/core/pathfinding/algorithms/BFS.Grid.ts similarity index 66% rename from src/core/pathfinding/navmesh/FastBFS.ts rename to src/core/pathfinding/algorithms/BFS.Grid.ts index 11ff34725..d70803c71 100644 --- a/src/core/pathfinding/navmesh/FastBFS.ts +++ b/src/core/pathfinding/algorithms/BFS.Grid.ts @@ -1,11 +1,7 @@ -export interface FastBFSAdapter { - visitor(node: number, dist: number): T | null | undefined; - isValidNode(node: number): boolean; -} - -// Optimized BFS using stamp-based visited tracking and typed array queue -export class FastBFS { +// 4-direction grid BFS with stamp-based visited tracking +export class BFSGrid { private stamp = 1; + private readonly visitedStamp: Uint32Array; private readonly queue: Int32Array; private readonly dist: Uint16Array; @@ -16,48 +12,57 @@ export class FastBFS { this.dist = new Uint16Array(numNodes); } - search( + /** + * Grid BFS search with visitor pattern. + * @param start - Starting node(s) + * @param maxDistance - Maximum distance to search + * @param isValidNode - Filter for traversable nodes + * @param visitor - Called for each node: + * - Returns R: Found target, return immediately + * - Returns undefined: Valid node, explore neighbors + * - Returns null: Reject node, don't explore neighbors + */ + search( width: number, height: number, - start: number, + start: number | number[], maxDistance: number, - isValidNode: FastBFSAdapter["isValidNode"], - visitor: FastBFSAdapter["visitor"], - ): T | null { + isValidNode: (node: number) => boolean, + visitor: (node: number, dist: number) => R | null | undefined, + ): R | null { const stamp = this.nextStamp(); const lastRowStart = (height - 1) * width; + const starts = typeof start === "number" ? [start] : start; let head = 0; let tail = 0; - this.visitedStamp[start] = stamp; - this.dist[start] = 0; - this.queue[tail++] = start; + for (const s of starts) { + this.visitedStamp[s] = stamp; + this.dist[s] = 0; + this.queue[tail++] = s; + } while (head < tail) { const node = this.queue[head++]; - const currentDist = this.dist[node]; + const dist = this.dist[node]; - if (currentDist > maxDistance) { - continue; - } - - // Call visitor: - // - Returns T: Found target, return immediately - // - Returns null: Reject tile, don't explore neighbors - // - Returns undefined: Valid tile, explore neighbors - const result = visitor(node, currentDist); + const result = visitor(node, dist); if (result !== null && result !== undefined) { return result; } - // If visitor returned null, reject this tile and don't explore neighbors if (result === null) { continue; } - const nextDist = currentDist + 1; + const nextDist = dist + 1; + + if (nextDist > maxDistance) { + continue; + } + const x = node % width; // North @@ -107,8 +112,7 @@ export class FastBFS { private nextStamp(): number { const stamp = this.stamp++; - if (this.stamp === 0) { - // Overflow - reset (extremely rare) + if (this.stamp > 0xffffffff) { this.visitedStamp.fill(0); this.stamp = 1; } diff --git a/src/core/pathfinding/algorithms/BFS.ts b/src/core/pathfinding/algorithms/BFS.ts new file mode 100644 index 000000000..06a7acc80 --- /dev/null +++ b/src/core/pathfinding/algorithms/BFS.ts @@ -0,0 +1,64 @@ +// Generic BFS implementation with adapter interface + +export interface BFSAdapter { + neighbors(node: T): T[]; +} + +export class BFS { + constructor(private adapter: BFSAdapter) {} + + /** + * BFS search with visitor pattern. + * @param start - Starting node(s) + * @param maxDistance - Maximum distance to search (Infinity for unlimited) + * @param visitor - Called for each node: + * - Returns R: Found target, return immediately + * - Returns undefined: Valid node, explore neighbors + * - Returns null: Reject node, don't explore neighbors + */ + search( + start: T | T[], + maxDistance: number, + visitor: (node: T, dist: number) => R | null | undefined, + ): R | null { + const visited = new Set(); + const queue: { node: T; dist: number }[] = []; + const starts = Array.isArray(start) ? start : [start]; + + for (const s of starts) { + visited.add(s); + queue.push({ node: s, dist: 0 }); + } + + while (queue.length > 0) { + const { node, dist } = queue.shift()!; + + const result = visitor(node, dist); + + if (result !== null && result !== undefined) { + return result; + } + + if (result === null) { + continue; + } + + const nextDist = dist + 1; + + if (nextDist > maxDistance) { + continue; + } + + for (const neighbor of this.adapter.neighbors(node)) { + if (visited.has(neighbor)) { + continue; + } + + visited.add(neighbor); + queue.push({ node: neighbor, dist: nextDist }); + } + } + + return null; + } +} diff --git a/src/core/pathfinding/navmesh/WaterComponents.ts b/src/core/pathfinding/algorithms/ConnectedComponents.ts similarity index 95% rename from src/core/pathfinding/navmesh/WaterComponents.ts rename to src/core/pathfinding/algorithms/ConnectedComponents.ts index e58cdf96f..93813b341 100644 --- a/src/core/pathfinding/navmesh/WaterComponents.ts +++ b/src/core/pathfinding/algorithms/ConnectedComponents.ts @@ -1,12 +1,14 @@ +// Connected Component Labeling using flood-fill + import { GameMap, TileRef } from "../../game/GameMap"; -const LAND_MARKER = 0xff; // Must fit in Uint8Array +export const LAND_MARKER = 0xff; // Must fit in Uint8Array /** - * Manages water component identification using flood-fill. - * Pre-allocates buffers and provides explicit initialization. + * Connected component labeling for grid-based maps. + * Identifies isolated regions using scan-line flood-fill. */ -export class WaterComponents { +export class ConnectedComponents { private readonly width: number; private readonly height: number; private readonly numTiles: number; diff --git a/src/core/pathfinding/algorithms/PriorityQueue.ts b/src/core/pathfinding/algorithms/PriorityQueue.ts new file mode 100644 index 000000000..c8f525f0b --- /dev/null +++ b/src/core/pathfinding/algorithms/PriorityQueue.ts @@ -0,0 +1,154 @@ +export interface PriorityQueue { + push(node: number, priority: number): void; + pop(): number; + isEmpty(): boolean; + clear(): void; +} + +// Binary min-heap: O(log n) push/pop, works with any priority values +export class MinHeap implements PriorityQueue { + private heap: Int32Array; + private priorities: Float32Array; + private size = 0; + + constructor(private capacity: number) { + this.heap = new Int32Array(capacity); + this.priorities = new Float32Array(capacity); + } + + push(node: number, priority: number): void { + if (this.size >= this.capacity) { + throw new Error(`MinHeap capacity exceeded: ${this.capacity}`); + } + + let i = this.size++; + this.heap[i] = node; + this.priorities[i] = priority; + + // Bubble up + while (i > 0) { + const parent = (i - 1) >> 1; + if (this.priorities[parent] <= this.priorities[i]) break; + // Swap + const tmpNode = this.heap[parent]; + const tmpPri = this.priorities[parent]; + this.heap[parent] = this.heap[i]; + this.priorities[parent] = this.priorities[i]; + this.heap[i] = tmpNode; + this.priorities[i] = tmpPri; + i = parent; + } + } + + pop(): number { + const result = this.heap[0]; + this.size--; + if (this.size > 0) { + this.heap[0] = this.heap[this.size]; + this.priorities[0] = this.priorities[this.size]; + + // Bubble down + let i = 0; + while (true) { + const left = (i << 1) + 1; + const right = left + 1; + let smallest = i; + + if ( + left < this.size && + this.priorities[left] < this.priorities[smallest] + ) { + smallest = left; + } + if ( + right < this.size && + this.priorities[right] < this.priorities[smallest] + ) { + smallest = right; + } + if (smallest === i) break; + + // Swap + const tmpNode = this.heap[smallest]; + const tmpPri = this.priorities[smallest]; + this.heap[smallest] = this.heap[i]; + this.priorities[smallest] = this.priorities[i]; + this.heap[i] = tmpNode; + this.priorities[i] = tmpPri; + i = smallest; + } + } + return result; + } + + isEmpty(): boolean { + return this.size === 0; + } + + clear(): void { + this.size = 0; + } +} + +// Bucket queue: O(1) push/pop when priorities are integers +export class BucketQueue implements PriorityQueue { + private buckets: Int32Array[]; + private bucketSizes: Int32Array; + private minBucket: number; + private maxBucket: number; + private size: number; + + constructor(maxPriority: number) { + this.maxBucket = maxPriority + 1; + this.buckets = new Array(this.maxBucket); + this.bucketSizes = new Int32Array(this.maxBucket); + this.minBucket = this.maxBucket; + this.size = 0; + } + + push(node: number, priority: number): void { + const bucket = Math.min(priority | 0, this.maxBucket - 1); + + if (!this.buckets[bucket]) { + this.buckets[bucket] = new Int32Array(64); + } + + const size = this.bucketSizes[bucket]; + if (size >= this.buckets[bucket].length) { + const newBucket = new Int32Array(this.buckets[bucket].length * 2); + newBucket.set(this.buckets[bucket]); + this.buckets[bucket] = newBucket; + } + + this.buckets[bucket][size] = node; + this.bucketSizes[bucket]++; + this.size++; + + if (bucket < this.minBucket) { + this.minBucket = bucket; + } + } + + pop(): number { + while (this.minBucket < this.maxBucket) { + const size = this.bucketSizes[this.minBucket]; + if (size > 0) { + this.bucketSizes[this.minBucket]--; + this.size--; + return this.buckets[this.minBucket][size - 1]; + } + this.minBucket++; + } + return -1; + } + + isEmpty(): boolean { + return this.size === 0; + } + + clear(): void { + this.bucketSizes.fill(0); + this.minBucket = this.maxBucket; + this.size = 0; + } +} diff --git a/src/core/pathfinding/navmesh/FastAStar.ts b/src/core/pathfinding/navmesh/FastAStar.ts deleted file mode 100644 index 770248e79..000000000 --- a/src/core/pathfinding/navmesh/FastAStar.ts +++ /dev/null @@ -1,202 +0,0 @@ -// A* optimized for performance for small to medium graphs. -// Works with node IDs represented as integers (0 to numNodes-1) - -export interface FastAStarAdapter { - getNeighbors(node: number): number[]; - getCost(from: number, to: number): number; - heuristic(node: number, goal: number): number; -} - -// Simple binary min-heap for open set using typed arrays -class MinHeap { - private heap: Int32Array; - private scores: Float32Array; - private size = 0; - - constructor(capacity: number, scores: Float32Array) { - this.heap = new Int32Array(capacity); - this.scores = scores; - } - - push(node: number): void { - let i = this.size++; - this.heap[i] = node; - - // Bubble up - while (i > 0) { - const parent = (i - 1) >> 1; - if (this.scores[this.heap[parent]] <= this.scores[this.heap[i]]) { - break; - } - - // Swap - const tmp = this.heap[parent]; - this.heap[parent] = this.heap[i]; - this.heap[i] = tmp; - i = parent; - } - } - - pop(): number { - const result = this.heap[0]; - this.heap[0] = this.heap[--this.size]; - - // Bubble down - let i = 0; - while (true) { - const left = (i << 1) + 1; - const right = left + 1; - let smallest = i; - - if ( - left < this.size && - this.scores[this.heap[left]] < this.scores[this.heap[smallest]] - ) { - smallest = left; - } - - if ( - right < this.size && - this.scores[this.heap[right]] < this.scores[this.heap[smallest]] - ) { - smallest = right; - } - - if (smallest === i) { - break; - } - - // Swap - const tmp = this.heap[smallest]; - this.heap[smallest] = this.heap[i]; - this.heap[i] = tmp; - i = smallest; - } - - return result; - } - - isEmpty(): boolean { - return this.size === 0; - } - - clear(): void { - this.size = 0; - } -} - -export class FastAStar { - private stamp = 1; - private readonly closedStamp: Uint32Array; // Tracks fully processed nodes - private readonly gScoreStamp: Uint32Array; // Tracks valid gScores - private readonly gScore: Float32Array; - private readonly fScore: Float32Array; - private readonly cameFrom: Int32Array; - private readonly openHeap: MinHeap; - - constructor(numNodes: number) { - this.closedStamp = new Uint32Array(numNodes); - this.gScoreStamp = new Uint32Array(numNodes); - this.gScore = new Float32Array(numNodes); - this.fScore = new Float32Array(numNodes); - this.cameFrom = new Int32Array(numNodes); - this.openHeap = new MinHeap(numNodes, this.fScore); - } - - private nextStamp(): number { - const stamp = this.stamp++; - - if (this.stamp === 0) { - // Overflow - reset (extremely rare) - this.closedStamp.fill(0); - this.gScoreStamp.fill(0); - this.stamp = 1; - } - - return stamp; - } - - search( - start: number, - goal: number, - adapter: FastAStarAdapter, - maxIterations: number = 100000, - ): number[] | null { - const stamp = this.nextStamp(); - - this.openHeap.clear(); - this.gScore[start] = 0; - this.gScoreStamp[start] = stamp; - this.fScore[start] = adapter.heuristic(start, goal); - this.cameFrom[start] = -1; - this.openHeap.push(start); - - let iterations = 0; - - while (!this.openHeap.isEmpty() && iterations < maxIterations) { - iterations++; - - const current = this.openHeap.pop(); - - // Skip if already processed (duplicate from heap) - if (this.closedStamp[current] === stamp) { - continue; - } - - // Mark as processed - this.closedStamp[current] = stamp; - - // Found goal - if (current === goal) { - return this.reconstructPath(start, goal); - } - - const neighbors = adapter.getNeighbors(current); - const currentGScore = this.gScore[current]; - - for (const neighbor of neighbors) { - // Skip already processed neighbors - if (this.closedStamp[neighbor] === stamp) { - continue; - } - - const tentativeGScore = - currentGScore + adapter.getCost(current, neighbor); - - // If we haven't visited this neighbor yet, or found a better path - const hasValidGScore = this.gScoreStamp[neighbor] === stamp; - if (!hasValidGScore || tentativeGScore < this.gScore[neighbor]) { - this.cameFrom[neighbor] = current; - this.gScore[neighbor] = tentativeGScore; - this.gScoreStamp[neighbor] = stamp; - this.fScore[neighbor] = - tentativeGScore + adapter.heuristic(neighbor, goal); - - // Add to heap (allow duplicates for better paths) - this.openHeap.push(neighbor); - } - } - } - - return null; - } - - private reconstructPath(start: number, goal: number): number[] { - const path: number[] = []; - let current = goal; - - while (current !== start) { - path.push(current); - current = this.cameFrom[current]; - - // Safety check - if (current === -1) { - return []; - } - } - - path.push(start); - path.reverse(); - return path; - } -} diff --git a/src/core/pathfinding/navmesh/FastAStarAdapter.ts b/src/core/pathfinding/navmesh/FastAStarAdapter.ts deleted file mode 100644 index 95b962233..000000000 --- a/src/core/pathfinding/navmesh/FastAStarAdapter.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { GameMap, TileRef } from "../../game/GameMap"; -import { FastAStarAdapter } from "./FastAStar"; -import { GatewayGraph } from "./GatewayGraph"; - -export class GatewayGraphAdapter implements FastAStarAdapter { - constructor(private graph: GatewayGraph) {} - - getNeighbors(node: number): number[] { - const edges = this.graph.getEdges(node); - return edges.map((edge) => edge.to); - } - - getCost(from: number, to: number): number { - const edges = this.graph.getEdges(from); - const edge = edges.find((edge) => edge.to === to); - return edge?.cost ?? 1; - } - - heuristic(node: number, goal: number): number { - const nodeGw = this.graph.getGateway(node); - const goalGw = this.graph.getGateway(goal); - - if (!nodeGw || !goalGw) { - throw new Error( - `Invalid gateway ID in heuristic: node=${node} (${nodeGw ? "exists" : "missing"}), goal=${goal} (${goalGw ? "exists" : "missing"})`, - ); - } - - // Manhattan distance heuristic - const dx = Math.abs(nodeGw.x - goalGw.x); - const dy = Math.abs(nodeGw.y - goalGw.y); - return dx + dy; - } -} - -export class BoundedGameMapAdapter implements FastAStarAdapter { - private readonly minX: number; - private readonly minY: number; - private readonly width: number; - private readonly height: number; - private readonly startTile: TileRef; - private readonly goalTile: TileRef; - - readonly numNodes: number; - - constructor( - private map: GameMap, - startTile: TileRef, - goalTile: TileRef, - bounds: { minX: number; maxX: number; minY: number; maxY: number }, - ) { - this.startTile = startTile; - this.goalTile = goalTile; - - this.minX = bounds.minX; - this.minY = bounds.minY; - this.width = bounds.maxX - bounds.minX + 1; - this.height = bounds.maxY - bounds.minY + 1; - - this.numNodes = this.width * this.height; - } - - // Convert global TileRef to local node ID - tileToNode(tile: TileRef): number { - const x = this.map.x(tile) - this.minX; - const y = this.map.y(tile) - this.minY; - - // Allow start and goal tiles to be outside bounds (matching graph building behavior) - const isOutsideBounds = - x < 0 || x >= this.width || y < 0 || y >= this.height; - const isStartOrGoal = tile === this.startTile || tile === this.goalTile; - if (isOutsideBounds && !isStartOrGoal) { - return -1; // Outside bounds - } - - // Clamp coordinates for start/goal tiles that are outside bounds - const clampedX = Math.max(0, Math.min(this.width - 1, x)); - const clampedY = Math.max(0, Math.min(this.height - 1, y)); - - return clampedY * this.width + clampedX; - } - - // Convert local node ID to global TileRef - nodeToTile(node: number): TileRef { - const localX = node % this.width; - const localY = Math.floor(node / this.width); - return this.map.ref(localX + this.minX, localY + this.minY); - } - - getNeighbors(node: number): number[] { - const tile = this.nodeToTile(node); - const neighbors = this.map.neighbors(tile); - const result: number[] = []; - - for (const neighborTile of neighbors) { - if (!this.map.isWater(neighborTile)) continue; - - const neighborNode = this.tileToNode(neighborTile); - if (neighborNode !== -1) { - result.push(neighborNode); - } - } - - return result; - } - - getCost(_from: number, _to: number): number { - return 1; // Uniform cost for water tiles - } - - heuristic(node: number, goal: number): number { - const nodeTile = this.nodeToTile(node); - const goalTile = this.nodeToTile(goal); - - const dx = Math.abs(this.map.x(nodeTile) - this.map.x(goalTile)); - const dy = Math.abs(this.map.y(nodeTile) - this.map.y(goalTile)); - - return dx + dy; // Manhattan distance - } -} diff --git a/src/core/pathfinding/navmesh/GatewayGraph.ts b/src/core/pathfinding/navmesh/GatewayGraph.ts deleted file mode 100644 index c08b60a99..000000000 --- a/src/core/pathfinding/navmesh/GatewayGraph.ts +++ /dev/null @@ -1,587 +0,0 @@ -import { Game } from "../../game/Game"; -import { GameMap, TileRef } from "../../game/GameMap"; -import { FastBFS } from "./FastBFS"; -import { WaterComponents } from "./WaterComponents"; - -export interface Gateway { - id: number; - x: number; - y: number; - tile: TileRef; - componentId: number; -} - -export interface Edge { - from: number; - to: number; - cost: number; - path?: TileRef[]; - sectorX: number; - sectorY: number; -} - -export interface Sector { - x: number; - y: number; - gateways: Gateway[]; - edges: Edge[]; -} - -export type BuildDebugInfo = { - sectors: number | null; - gateways: number | null; - edges: number | null; - actualBFSCalls: number | null; - potentialBFSCalls: number | null; - skippedByComponentFilter: number | null; - timings: { [key: string]: number }; -}; - -export class GatewayGraph { - constructor( - readonly sectors: ReadonlyMap, - readonly gateways: ReadonlyMap, - readonly edges: ReadonlyMap, - readonly sectorSize: number, - readonly sectorsX: number, - ) {} - - getSectorKey(sectorX: number, sectorY: number): number { - return sectorY * this.sectorsX + sectorX; - } - - getSector(sectorX: number, sectorY: number): Sector | undefined { - return this.sectors.get(this.getSectorKey(sectorX, sectorY)); - } - - getGateway(id: number): Gateway | undefined { - return this.gateways.get(id); - } - - getEdges(gatewayId: number): Edge[] { - return this.edges.get(gatewayId) ?? []; - } - - getNearbySectorGateways(sectorX: number, sectorY: number): Gateway[] { - const nearby: Gateway[] = []; - for (let dy = -1; dy <= 1; dy++) { - for (let dx = -1; dx <= 1; dx++) { - const sector = this.getSector(sectorX + dx, sectorY + dy); - if (sector) { - nearby.push(...sector.gateways); - } - } - } - return nearby; - } - - getAllGateways(): Gateway[] { - return Array.from(this.gateways.values()); - } -} - -export class GatewayGraphBuilder { - static readonly SECTOR_SIZE = 32; - - // Derived immutable state - private readonly miniMap: GameMap; - private readonly width: number; - private readonly height: number; - private readonly sectorsX: number; - private readonly sectorsY: number; - private readonly fastBFS: FastBFS; - private readonly waterComponents: WaterComponents; - - // Mutable build state - private sectors = new Map(); - private gateways = new Map(); - private tileToGateway = new Map(); - private edges = new Map(); - private nextGatewayId = 0; - - // Programatically accessible debug info - public debugInfo: BuildDebugInfo | null = null; - - constructor( - private readonly game: Game, - private readonly sectorSize: number, - ) { - this.miniMap = game.miniMap(); - this.width = this.miniMap.width(); - this.height = this.miniMap.height(); - this.sectorsX = Math.ceil(this.width / sectorSize); - this.sectorsY = Math.ceil(this.height / sectorSize); - this.fastBFS = new FastBFS(this.width * this.height); - this.waterComponents = new WaterComponents(this.miniMap); - } - - build(debug: boolean): GatewayGraph { - performance.mark("navsat:build:start"); - - if (debug) { - console.log( - `[DEBUG] Building gateway graph with sector size ${this.sectorSize} (${this.sectorsX}x${this.sectorsY} sectors)`, - ); - - this.debugInfo = { - sectors: null, - gateways: null, - edges: null, - actualBFSCalls: null, - potentialBFSCalls: null, - skippedByComponentFilter: null, - timings: {}, - }; - } - - // Initialize water components before building gateway graph - performance.mark("navsat:build:water-component:start"); - this.waterComponents.initialize(); - performance.mark("navsat:build:water-component:end"); - const measure = performance.measure( - "navsat:build:water-component", - "navsat:build:water-component:start", - "navsat:build:water-component:end", - ); - - if (debug) { - console.log( - `[DEBUG] Water Component Identification: ${measure.duration.toFixed(2)}ms`, - ); - } - - performance.mark("navsat:build:gateways:start"); - for (let sy = 0; sy < this.sectorsY; sy++) { - for (let sx = 0; sx < this.sectorsX; sx++) { - this.processSector(sx, sy); - } - } - performance.mark("navsat:build:gateways:end"); - const gatewaysMeasure = performance.measure( - "navsat:build:gateways", - "navsat:build:gateways:start", - "navsat:build:gateways:end", - ); - - if (debug) { - console.log( - `[DEBUG] Gateway identification: ${gatewaysMeasure.duration.toFixed(2)}ms`, - ); - - this.debugInfo!.edges = 0; - this.debugInfo!.potentialBFSCalls = 0; - this.debugInfo!.skippedByComponentFilter = 0; - } - - performance.mark("navsat:build:edges:start"); - for (const sector of this.sectors.values()) { - const gws = sector.gateways; - const numGateways = gws.length; - - if (debug) { - this.debugInfo!.potentialBFSCalls! += - (numGateways * (numGateways - 1)) / 2; - - for (let i = 0; i < gws.length; i++) { - for (let j = i + 1; j < gws.length; j++) { - if (gws[i].componentId !== gws[j].componentId) { - this.debugInfo!.skippedByComponentFilter!++; - } - } - } - } - - this.buildSectorConnections(sector); - - if (debug) { - // Divide by 2 because bidirectional - this.debugInfo!.edges! += sector.edges.length / 2; - } - } - - if (debug) { - this.debugInfo!.actualBFSCalls = - this.debugInfo!.potentialBFSCalls! - - this.debugInfo!.skippedByComponentFilter!; - } - - performance.mark("navsat:build:edges:end"); - const edgesMeasure = performance.measure( - "navsat:build:edges", - "navsat:build:edges:start", - "navsat:build:edges:end", - ); - - if (debug) { - console.log( - `[DEBUG] Edges Identification: ${edgesMeasure.duration.toFixed(2)}ms`, - ); - console.log( - `[DEBUG] Potential BFS calls: ${this.debugInfo!.potentialBFSCalls}`, - ); - console.log( - `[DEBUG] Skipped by component filter: ${this.debugInfo!.skippedByComponentFilter} (${((this.debugInfo!.skippedByComponentFilter! / this.debugInfo!.potentialBFSCalls!) * 100).toFixed(1)}%)`, - ); - console.log( - `[DEBUG] Actual BFS calls: ${this.debugInfo!.actualBFSCalls}`, - ); - console.log( - `[DEBUG] Edges Found: ${this.debugInfo!.edges} (${((this.debugInfo!.edges! / this.debugInfo!.actualBFSCalls!) * 100).toFixed(1)}% success rate)`, - ); - } - - performance.mark("navsat:build:end"); - const totalMeasure = performance.measure( - "navsat:build:total", - "navsat:build:start", - "navsat:build:end", - ); - - if (debug) { - console.log( - `[DEBUG] Gateway graph built in ${totalMeasure.duration.toFixed(2)}ms`, - ); - console.log(`[DEBUG] Gateways: ${this.gateways.size}`); - console.log(`[DEBUG] Sectors: ${this.sectors.size}`); - } - - return new GatewayGraph( - this.sectors, - this.gateways, - this.edges, - this.sectorSize, - this.sectorsX, - ); - } - - private getSectorKey(sectorX: number, sectorY: number): number { - return sectorY * this.sectorsX + sectorX; - } - - private getOrCreateGateway(x: number, y: number): Gateway { - const tile = this.miniMap.ref(x, y); - - // O(1) lookup using tile reference - const existing = this.tileToGateway.get(tile); - if (existing) { - return existing; - } - - const gateway: Gateway = { - id: this.nextGatewayId++, - x: x, - y: y, - tile: tile, - componentId: this.waterComponents.getComponentId(tile), - }; - - this.gateways.set(gateway.id, gateway); - this.tileToGateway.set(tile, gateway); - return gateway; - } - - private addGatewayToSector(sector: Sector, gateway: Gateway): void { - // Check for duplicates: a gateway at a sector corner can be - // detected by both horizontal and vertical edge scans - for (const existingGw of sector.gateways) { - if (existingGw.x === gateway.x && existingGw.y === gateway.y) { - return; - } - } - - // Gateway doesn't exist in sector yet, add it - sector.gateways.push(gateway); - } - - private processSector(sx: number, sy: number): void { - const sectorKey = this.getSectorKey(sx, sy); - let sector = this.sectors.get(sectorKey); - - if (!sector) { - sector = { x: sx, y: sy, gateways: [], edges: [] }; - this.sectors.set(sectorKey, sector); - } - - const baseX = sx * this.sectorSize; - const baseY = sy * this.sectorSize; - - if (sx < this.sectorsX - 1) { - const edgeX = Math.min(baseX + this.sectorSize - 1, this.width - 1); - const newGateways = this.findGatewaysOnVerticalEdge(edgeX, baseY); - - for (const gateway of newGateways) { - this.addGatewayToSector(sector, gateway); - - const rightSectorKey = this.getSectorKey(sx + 1, sy); - let rightSector = this.sectors.get(rightSectorKey); - - if (!rightSector) { - rightSector = { x: sx + 1, y: sy, gateways: [], edges: [] }; - this.sectors.set(rightSectorKey, rightSector); - } - - this.addGatewayToSector(rightSector, gateway); - } - } - - if (sy < this.sectorsY - 1) { - const edgeY = Math.min(baseY + this.sectorSize - 1, this.height - 1); - const newGateways = this.findGatewaysOnHorizontalEdge(edgeY, baseX); - - for (const gateway of newGateways) { - this.addGatewayToSector(sector, gateway); - - const bottomSectorKey = this.getSectorKey(sx, sy + 1); - let bottomSector = this.sectors.get(bottomSectorKey); - - if (!bottomSector) { - bottomSector = { x: sx, y: sy + 1, gateways: [], edges: [] }; - this.sectors.set(bottomSectorKey, bottomSector); - } - - this.addGatewayToSector(bottomSector, gateway); - } - } - } - - private findGatewaysOnVerticalEdge(x: number, baseY: number): Gateway[] { - const gateways: Gateway[] = []; - const maxY = Math.min(baseY + this.sectorSize, this.height); - - let gatewayStart = -1; - - const tryAddGateway = (y: number) => { - if (gatewayStart === -1) return; - - const gatewayLength = y - gatewayStart; - const midY = gatewayStart + Math.floor(gatewayLength / 2); - - gatewayStart = -1; - - const gateway = this.getOrCreateGateway(x, midY); - gateways.push(gateway); - }; - - for (let y = baseY; y < maxY; y++) { - const tile = this.miniMap.ref(x, y); - const nextTile = - x + 1 < this.miniMap.width() ? this.miniMap.ref(x + 1, y) : -1; - const isGateway = - this.miniMap.isWater(tile) && - nextTile !== -1 && - this.miniMap.isWater(nextTile); - - if (isGateway) { - if (gatewayStart === -1) { - gatewayStart = y; - } - } else { - tryAddGateway(y); - } - } - - tryAddGateway(maxY); - - return gateways; - } - - private findGatewaysOnHorizontalEdge(y: number, baseX: number): Gateway[] { - const gateways: Gateway[] = []; - const maxX = Math.min(baseX + this.sectorSize, this.width); - - let gatewayStart = -1; - - const tryAddGateway = (x: number) => { - if (gatewayStart === -1) return; - - const gatewayLength = x - gatewayStart; - const midX = gatewayStart + Math.floor(gatewayLength / 2); - - gatewayStart = -1; - - const gateway = this.getOrCreateGateway(midX, y); - gateways.push(gateway); - }; - - for (let x = baseX; x < maxX; x++) { - const tile = this.miniMap.ref(x, y); - const nextTile = - y + 1 < this.miniMap.height() ? this.miniMap.ref(x, y + 1) : -1; - const isGateway = - this.miniMap.isWater(tile) && - nextTile !== -1 && - this.miniMap.isWater(nextTile); - - if (isGateway) { - if (gatewayStart === -1) { - gatewayStart = x; - } - } else { - tryAddGateway(x); - } - } - - tryAddGateway(maxX); - - return gateways; - } - - private buildSectorConnections(sector: Sector): void { - const gateways = sector.gateways; - - // Calculate bounding box once for this sector - const sectorMinX = sector.x * this.sectorSize; - const sectorMinY = sector.y * this.sectorSize; - const sectorMaxX = Math.min( - this.width - 1, - sectorMinX + this.sectorSize - 1, - ); - const sectorMaxY = Math.min( - this.height - 1, - sectorMinY + this.sectorSize - 1, - ); - - for (let i = 0; i < gateways.length; i++) { - const fromGateway = gateways[i]; - - // Build list of target gateways (only those we haven't processed yet) - const targetGateways: Gateway[] = []; - for (let j = i + 1; j < gateways.length; j++) { - // Skip if gateways are in different water components - if (gateways[i].componentId !== gateways[j].componentId) { - continue; - } - - targetGateways.push(gateways[j]); - } - - if (targetGateways.length === 0) { - continue; - } - - // Single BFS to find all reachable target gateways - const reachableGateways = this.findAllReachableGatewaysInBounds( - fromGateway.tile, - targetGateways, - sectorMinX, - sectorMaxX, - sectorMinY, - sectorMaxY, - ); - - // Create edges for all reachable gateways - for (const [targetId, cost] of reachableGateways.entries()) { - if (!this.edges.has(fromGateway.id)) { - this.edges.set(fromGateway.id, []); - } - - if (!this.edges.has(targetId)) { - this.edges.set(targetId, []); - } - - // Check for existing edges - gateways may live in 2 sectors, keep only cheaper connection - const existingEdgeFromI = this.edges - .get(fromGateway.id)! - .find((e) => e.to === targetId); - const existingEdgeFromJ = this.edges - .get(targetId)! - .find((e) => e.to === fromGateway.id); - - // If edge doesn't exist or new cost is cheaper, update it - if (!existingEdgeFromI || cost < existingEdgeFromI.cost) { - const edge1: Edge = { - from: fromGateway.id, - to: targetId, - cost: cost, - sectorX: sector.x, - sectorY: sector.y, - }; - - const edge2: Edge = { - from: targetId, - to: fromGateway.id, - cost: cost, - sectorX: sector.x, - sectorY: sector.y, - }; - - // Add to sector edges for tracking - sector.edges.push(edge1, edge2); - - if (existingEdgeFromI) { - const idx1 = this.edges - .get(fromGateway.id)! - .indexOf(existingEdgeFromI); - this.edges.get(fromGateway.id)![idx1] = edge1; - - const idx2 = this.edges.get(targetId)!.indexOf(existingEdgeFromJ!); - this.edges.get(targetId)![idx2] = edge2; - } else { - this.edges.get(fromGateway.id)!.push(edge1); - this.edges.get(targetId)!.push(edge2); - } - } - } - } - } - - private findAllReachableGatewaysInBounds( - from: TileRef, - targetGateways: Gateway[], - minX: number, - maxX: number, - minY: number, - maxY: number, - ): Map { - const fromX = this.miniMap.x(from); - const fromY = this.miniMap.y(from); - - // Create a map of tile positions to gateway IDs for fast lookup - const tileToGateway = new Map(); - let maxManhattanDist = 0; - - for (const gateway of targetGateways) { - tileToGateway.set(gateway.tile, gateway.id); - const dx = Math.abs(gateway.x - fromX); - const dy = Math.abs(gateway.y - fromY); - maxManhattanDist = Math.max(maxManhattanDist, dx + dy); - } - - const maxDistance = maxManhattanDist * 4; // Allow path deviation - const reachable = new Map(); - let foundCount = 0; - - this.fastBFS.search( - this.miniMap.width(), - this.miniMap.height(), - from, - maxDistance, - (tile: number) => this.miniMap.isWater(tile), - (tile: number, dist: number) => { - const x = this.miniMap.x(tile); - const y = this.miniMap.y(tile); - - // Reject if outside of bounding box - const isStartOrEnd = tile === from || tileToGateway.has(tile); - if (!isStartOrEnd && (x < minX || x > maxX || y < minY || y > maxY)) { - return null; - } - - // Check if this tile is one of our target gateways - const gatewayId = tileToGateway.get(tile); - - if (gatewayId !== undefined) { - reachable.set(gatewayId, dist); - foundCount++; - - // Early exit if we've found all target gateways - if (foundCount === targetGateways.length) { - return dist; // Return to stop BFS - } - } - }, - ); - - return reachable; - } -} diff --git a/src/core/pathfinding/navmesh/NavMesh.ts b/src/core/pathfinding/navmesh/NavMesh.ts deleted file mode 100644 index 574dbfccc..000000000 --- a/src/core/pathfinding/navmesh/NavMesh.ts +++ /dev/null @@ -1,819 +0,0 @@ -import { Game } from "../../game/Game"; -import { TileRef } from "../../game/GameMap"; -import { FastAStar } from "./FastAStar"; -import { BoundedGameMapAdapter, GatewayGraphAdapter } from "./FastAStarAdapter"; -import { FastBFS } from "./FastBFS"; -import { Gateway, GatewayGraph, GatewayGraphBuilder } from "./GatewayGraph"; - -type PathDebugInfo = { - gatewayPath: TileRef[] | null; - initialPath: TileRef[] | null; - smoothPath: TileRef[] | null; - graph: { - sectorSize: number; - gateways: Array<{ id: number; tile: TileRef }>; - edges: Array<{ - fromId: number; - toId: number; - from: TileRef; - to: TileRef; - cost: number; - path: TileRef[] | null; - }>; - }; - timings: { [key: string]: number }; -}; - -export class NavMesh { - private graph!: GatewayGraph; - private initialized = false; - private fastBFS!: FastBFS; - private gatewayAStar!: FastAStar; - private localAStar!: FastAStar; - private localAStarMultiSector!: FastAStar; - - public debugInfo: PathDebugInfo | null = null; - - constructor( - private game: Game, - private options: { - cachePaths?: boolean; - } = {}, - ) {} - - initialize(debug: boolean = false) { - const gatewayGraphBuilder = new GatewayGraphBuilder( - this.game, - GatewayGraphBuilder.SECTOR_SIZE, - ); - this.graph = gatewayGraphBuilder.build(debug); - - const miniMap = this.game.miniMap(); - this.fastBFS = new FastBFS(miniMap.width() * miniMap.height()); - - const gatewayCount = this.graph.getAllGateways().length; - this.gatewayAStar = new FastAStar(gatewayCount); - - // Fixed-size FastAStar for sector-bounded local pathfinding - // Single sector: 32×32 = 1,024 nodes - const sectorSize = GatewayGraphBuilder.SECTOR_SIZE; - const maxLocalNodes = sectorSize * sectorSize; // 1,024 nodes - this.localAStar = new FastAStar(maxLocalNodes); - - // Multi-sector FastAStar for cross-sector pathfinding (same gateway, different sectors) - // 3×3 sectors: 96×96 = 9,216 nodes - const multiSectorSize = sectorSize * 3; - const maxMultiSectorNodes = multiSectorSize * multiSectorSize; - this.localAStarMultiSector = new FastAStar(maxMultiSectorNodes); - - this.initialized = true; - } - - findPath( - from: TileRef, - to: TileRef, - debug: boolean = false, - ): TileRef[] | null { - if (!this.initialized) { - throw new Error( - "NavMesh not initialized. Call initialize() before using findPath().", - ); - } - - if (debug) { - // Collect all edges with their paths for visualization - const allEdges: Array<{ - fromId: number; - toId: number; - from: TileRef; - to: TileRef; - cost: number; - path: TileRef[] | null; - }> = []; - - for (const [fromId, edges] of this.graph.edges.entries()) { - const fromGw = this.graph.getGateway(fromId); - if (!fromGw) continue; - - for (const edge of edges) { - const toGw = this.graph.getGateway(edge.to); - if (!toGw) continue; - - // Only add each edge once (not both directions) - // Include self-loops (fromId === edge.to) for debugging - if (fromId <= edge.to) { - allEdges.push({ - fromId: fromId, - toId: edge.to, - from: fromGw.tile, - to: toGw.tile, - cost: edge.cost, - path: edge.path ?? null, - }); - } - } - } - - this.debugInfo = { - gatewayPath: null, - initialPath: null, - smoothPath: null, - graph: { - sectorSize: this.graph.sectorSize, - gateways: this.graph - .getAllGateways() - .map((gw) => ({ id: gw.id, tile: gw.tile })), - edges: allEdges, - }, - timings: { - total: 0, - }, - }; - } - - const dist = this.game.manhattanDist(from, to); - - // Early exit for very short distances that fit within multi-sector range - if (dist <= this.graph.sectorSize) { - performance.mark("navsat:findPath:earlyExitLocalPath:start"); - const map = this.game.map(); - const startMiniX = Math.floor(map.x(from) / 2); - const startMiniY = Math.floor(map.y(from) / 2); - const sectorX = Math.floor(startMiniX / this.graph.sectorSize); - const sectorY = Math.floor(startMiniY / this.graph.sectorSize); - const localPath = this.findLocalPath( - from, - to, - sectorX, - sectorY, - 2000, - true, - ); - performance.mark("navsat:findPath:earlyExitLocalPath:end"); - const measure = performance.measure( - "navsat:findPath:earlyExitLocalPath", - "navsat:findPath:earlyExitLocalPath:start", - "navsat:findPath:earlyExitLocalPath:end", - ); - - if (debug) { - this.debugInfo!.timings.earlyExitLocalPath = measure.duration; - this.debugInfo!.timings.total += measure.duration; - } - - if (localPath) { - if (debug) { - console.log( - `[DEBUG] Direct local path found for dist=${dist}, length=${localPath.length}`, - ); - } - - return localPath; - } - - if (debug) { - console.log( - `[DEBUG] Direct path failed for dist=${dist}, falling back to gateway graph`, - ); - } - } - - performance.mark("navsat:findPath:findGateways:start"); - const startGateway = this.findNearestGateway(from); - const endGateway = this.findNearestGateway(to); - performance.mark("navsat:findPath:findGateways:end"); - const findGatewaysMeasure = performance.measure( - "navsat:findPath:findGateways", - "navsat:findPath:findGateways:start", - "navsat:findPath:findGateways:end", - ); - - if (debug) { - this.debugInfo!.timings.findGateways = findGatewaysMeasure.duration; - this.debugInfo!.timings.total += findGatewaysMeasure.duration; - } - - if (!startGateway) { - if (debug) { - console.log( - `[DEBUG] Cannot find start gateway for (${this.game.x(from)}, ${this.game.y(from)})`, - ); - } - - return null; - } - - if (!endGateway) { - if (debug) { - console.log( - `[DEBUG] Cannot find end gateway for (${this.game.x(to)}, ${this.game.y(to)})`, - ); - } - - return null; - } - - if (startGateway.id === endGateway.id) { - if (debug) { - console.log( - `[DEBUG] Start and end gateways are the same (ID=${startGateway.id}), finding local path with multi-sector search`, - ); - } - - performance.mark("navsat:findPath:sameGatewayLocalPath:start"); - const sectorX = Math.floor(startGateway.x / this.graph.sectorSize); - const sectorY = Math.floor(startGateway.y / this.graph.sectorSize); - const path = this.findLocalPath(from, to, sectorX, sectorY, 10000, true); - performance.mark("navsat:findPath:sameGatewayLocalPath:end"); - const sameGatewayMeasure = performance.measure( - "navsat:findPath:sameGatewayLocalPath", - "navsat:findPath:sameGatewayLocalPath:start", - "navsat:findPath:sameGatewayLocalPath:end", - ); - - if (debug) { - this.debugInfo!.timings.sameGatewayLocalPath = - sameGatewayMeasure.duration; - this.debugInfo!.timings.total += sameGatewayMeasure.duration; - } - - return path; - } - - performance.mark("navsat:findPath:findGatewayPath:start"); - const gatewayPath = this.findGatewayPath(startGateway.id, endGateway.id); - performance.mark("navsat:findPath:findGatewayPath:end"); - const findGatewayPathMeasure = performance.measure( - "navsat:findPath:findGatewayPath", - "navsat:findPath:findGatewayPath:start", - "navsat:findPath:findGatewayPath:end", - ); - - if (debug) { - this.debugInfo!.timings.findGatewayPath = findGatewayPathMeasure.duration; - this.debugInfo!.timings.total += findGatewayPathMeasure.duration; - - this.debugInfo!.gatewayPath = gatewayPath - ? gatewayPath - .map((gwId) => { - const gw = this.graph.getGateway(gwId); - return gw ? gw.tile : -1; - }) - .filter((tile) => tile !== -1) - : null; - } - - if (!gatewayPath) { - if (debug) { - console.log( - `[DEBUG] No gateway path between gateways ${startGateway.id} and ${endGateway.id}`, - ); - } - - return null; - } - - if (debug) { - console.log( - `[DEBUG] Gateway path found: ${gatewayPath.length} waypoints`, - ); - } - - const initialPath: TileRef[] = []; - const map = this.game.map(); - const miniMap = this.game.miniMap(); - - performance.mark("navsat:findPath:buildInitialPath:start"); - - // 1. Find path from start to first gateway - const firstGateway = this.graph.getGateway(gatewayPath[0])!; - const firstGatewayTile = map.ref( - miniMap.x(firstGateway.tile) * 2, - miniMap.y(firstGateway.tile) * 2, - ); - - // Use start position's sector with multi-sector search (gateway may be on border) - const startMiniX = Math.floor(map.x(from) / 2); - const startMiniY = Math.floor(map.y(from) / 2); - const startSectorX = Math.floor(startMiniX / this.graph.sectorSize); - const startSectorY = Math.floor(startMiniY / this.graph.sectorSize); - const startSegment = this.findLocalPath( - from, - firstGatewayTile, - startSectorX, - startSectorY, - ); - - if (!startSegment) { - return null; - } - - initialPath.push(...startSegment); - - // 2. Build path through gateways - for (let i = 0; i < gatewayPath.length - 1; i++) { - const fromGwId = gatewayPath[i]; - const toGwId = gatewayPath[i + 1]; - - const edges = this.graph.getEdges(fromGwId); - const edge = edges.find((edge) => edge.to === toGwId); - - if (!edge) { - return null; - } - - if (edge.path) { - // Use cached path if available - initialPath.push(...edge.path.slice(1)); - continue; - } - - const fromGw = this.graph.getGateway(fromGwId)!; - const toGw = this.graph.getGateway(toGwId)!; - const fromTile = map.ref( - miniMap.x(fromGw.tile) * 2, - miniMap.y(fromGw.tile) * 2, - ); - const toTile = map.ref( - miniMap.x(toGw.tile) * 2, - miniMap.y(toGw.tile) * 2, - ); - - const segmentPath = this.findLocalPath( - fromTile, - toTile, - edge.sectorX, - edge.sectorY, - ); - - if (!segmentPath) { - return null; - } - - // Skip first tile to avoid duplication - initialPath.push(...segmentPath.slice(1)); - - if (this.options.cachePaths) { - // Cache the path for future reuse on both directional edges - edge.path = segmentPath; - - // Also cache the reversed path on the opposite direction edge - const reverseEdges = this.graph.getEdges(toGwId); - const reverseEdge = reverseEdges.find((e) => e.to === fromGwId); - if (reverseEdge) { - reverseEdge.path = segmentPath.slice().reverse(); - } - } - } - - // 3. Find path from last gateway to end - const lastGateway = this.graph.getGateway( - gatewayPath[gatewayPath.length - 1], - )!; - const lastGatewayTile = map.ref( - miniMap.x(lastGateway.tile) * 2, - miniMap.y(lastGateway.tile) * 2, - ); - - // Use end position's sector with multi-sector search (gateway may be on border) - const endMiniX = Math.floor(map.x(to) / 2); - const endMiniY = Math.floor(map.y(to) / 2); - const endSectorX = Math.floor(endMiniX / this.graph.sectorSize); - const endSectorY = Math.floor(endMiniY / this.graph.sectorSize); - const endSegment = this.findLocalPath( - lastGatewayTile, - to, - endSectorX, - endSectorY, - ); - - if (!endSegment) { - return null; - } - - // Skip first tile to avoid duplication - initialPath.push(...endSegment.slice(1)); - - performance.mark("navsat:findPath:buildInitialPath:end"); - const buildInitialPathMeasure = performance.measure( - "navsat:findPath:buildInitialPath", - "navsat:findPath:buildInitialPath:start", - "navsat:findPath:buildInitialPath:end", - ); - - if (debug) { - this.debugInfo!.timings.buildInitialPath = - buildInitialPathMeasure.duration; - this.debugInfo!.timings.total += buildInitialPathMeasure.duration; - this.debugInfo!.initialPath = initialPath; - console.log(`[DEBUG] Initial path: ${initialPath.length} tiles`); - } - - performance.mark("navsat:findPath:smoothPath:start"); - const smoothedPath = this.smoothPath(initialPath); - performance.mark("navsat:findPath:smoothPath:end"); - const smoothPathMeasure = performance.measure( - "navsat:findPath:smoothPath", - "navsat:findPath:smoothPath:start", - "navsat:findPath:smoothPath:end", - ); - - if (debug) { - this.debugInfo!.timings.buildSmoothPath = smoothPathMeasure.duration; - this.debugInfo!.timings.total += smoothPathMeasure.duration; - this.debugInfo!.smoothPath = smoothedPath; - console.log( - `[DEBUG] Smoothed path: ${initialPath.length} → ${smoothedPath.length} tiles`, - ); - } - - return smoothedPath; - } - - private findNearestGateway(tile: TileRef): Gateway | null { - const map = this.game.map(); - const x = map.x(tile); - const y = map.y(tile); - - // Convert to miniMap coordinates - const miniMap = this.game.miniMap(); - const miniX = Math.floor(x / 2); - const miniY = Math.floor(y / 2); - const miniFrom = miniMap.ref(miniX, miniY); - - // Check gateways in the tile's own sector (using miniMap coordinates) - const sectorX = Math.floor(miniX / this.graph.sectorSize); - const sectorY = Math.floor(miniY / this.graph.sectorSize); - - // Calculate single sector bounds - const sectorSize = this.graph.sectorSize; - const minX = sectorX * sectorSize; - const minY = sectorY * sectorSize; - const maxX = Math.min(miniMap.width() - 1, minX + sectorSize - 1); - const maxY = Math.min(miniMap.height() - 1, minY + sectorSize - 1); - - // Get gateways from the tile's own sector only (includes border gateways) - const sector = this.graph.getSector(sectorX, sectorY); - - if (!sector) { - return null; - } - - const candidateGateways = sector.gateways; - if (candidateGateways.length === 0) { - return null; - } - - // Use BFS to find the nearest reachable gateway (by water path distance) - // Search space is bounded by sector bounds, so maxDistance can be large - const maxDistance = sectorSize * sectorSize; - - return this.fastBFS.search( - miniMap.width(), - miniMap.height(), - miniFrom, - maxDistance, - (tile: TileRef) => miniMap.isWater(tile), - (tile: TileRef, _dist: number) => { - const tileX = miniMap.x(tile); - const tileY = miniMap.y(tile); - - // Check if any candidate gateway is at this position first - for (const gateway of candidateGateways) { - if (gateway.x === tileX && gateway.y === tileY) { - return gateway; - } - } - - // Reject non-gateway tiles outside the sector bounds - if (tileX < minX || tileX > maxX || tileY < minY || tileY > maxY) { - return null; - } - }, - ); - } - - private findGatewayPath( - fromGatewayId: number, - toGatewayId: number, - ): number[] | null { - const adapter = new GatewayGraphAdapter(this.graph); - return this.gatewayAStar.search( - fromGatewayId, - toGatewayId, - adapter, - 100000, - ); - } - - private findLocalPath( - from: TileRef, - to: TileRef, - sectorX: number, - sectorY: number, - maxIterations: number = 10000, - multiSector: boolean = false, - ): TileRef[] | null { - const map = this.game.map(); - const miniMap = this.game.miniMap(); - - // Convert full map coordinates to miniMap coordinates - const miniFrom = miniMap.ref( - Math.floor(map.x(from) / 2), - Math.floor(map.y(from) / 2), - ); - - const miniTo = miniMap.ref( - Math.floor(map.x(to) / 2), - Math.floor(map.y(to) / 2), - ); - - // Calculate sector bounds - const sectorSize = this.graph.sectorSize; - - let minX: number; - let minY: number; - let maxX: number; - let maxY: number; - - if (multiSector) { - // 3×3 sectors centered on the starting sector - minX = Math.max(0, (sectorX - 1) * sectorSize); - minY = Math.max(0, (sectorY - 1) * sectorSize); - maxX = Math.min(miniMap.width() - 1, (sectorX + 2) * sectorSize - 1); - maxY = Math.min(miniMap.height() - 1, (sectorY + 2) * sectorSize - 1); - } else { - // Single sector - minX = sectorX * sectorSize; - minY = sectorY * sectorSize; - maxX = Math.min(miniMap.width() - 1, minX + sectorSize - 1); - maxY = Math.min(miniMap.height() - 1, minY + sectorSize - 1); - } - - const adapter = new BoundedGameMapAdapter(miniMap, miniFrom, miniTo, { - minX, - maxX, - minY, - maxY, - }); - - // Convert to local node IDs - const startNode = adapter.tileToNode(miniFrom); - const goalNode = adapter.tileToNode(miniTo); - - if (startNode === -1 || goalNode === -1) { - return null; // Start or goal outside bounds - } - - // Choose the appropriate FastAStar buffer based on search area - const selectedAStar = multiSector - ? this.localAStarMultiSector - : this.localAStar; - - // Run FastAStar on bounded region - const path = selectedAStar.search( - startNode, - goalNode, - adapter, - maxIterations, - ); - - if (!path) { - return null; - } - - // Convert path from local node IDs back to miniMap TileRefs - const miniPath = path.map((node: number) => adapter.nodeToTile(node)); - - // Upscale from miniMap to full map (same logic as MiniAStar) - const result = this.upscalePathToFullMap(miniPath, from, to); - - return result; - } - - private upscalePathToFullMap( - miniPath: TileRef[], - from: TileRef, - to: TileRef, - ): TileRef[] { - const map = this.game.map(); - const miniMap = this.game.miniMap(); - - // Convert miniMap path to cells - const miniCells = miniPath.map((tile) => ({ - x: miniMap.x(tile), - y: miniMap.y(tile), - })); - - // FIRST: Scale all points (2x) - const scaledPath = miniCells.map((point) => ({ - x: point.x * 2, - y: point.y * 2, - })); - - // SECOND: Interpolate between scaled points - const smoothPath: Array<{ x: number; y: number }> = []; - for (let i = 0; i < scaledPath.length - 1; i++) { - const current = scaledPath[i]; - const next = scaledPath[i + 1]; - - // Add the current point - smoothPath.push(current); - - // Calculate dx/dy from SCALED coordinates - const dx = next.x - current.x; - const dy = next.y - current.y; - const distance = Math.max(Math.abs(dx), Math.abs(dy)); - const steps = distance; - - // Add intermediate points - for (let step = 1; step < steps; step++) { - smoothPath.push({ - x: Math.round(current.x + (dx * step) / steps), - y: Math.round(current.y + (dy * step) / steps), - }); - } - } - - // Add last point - if (scaledPath.length > 0) { - smoothPath.push(scaledPath[scaledPath.length - 1]); - } - - const scaledCells = smoothPath; - - // Fix extremes to ensure exact start/end - const fromCell = { x: map.x(from), y: map.y(from) }; - const toCell = { x: map.x(to), y: map.y(to) }; - - // Ensure start is correct - const startIdx = scaledCells.findIndex( - (c) => c.x === fromCell.x && c.y === fromCell.y, - ); - if (startIdx === -1) { - scaledCells.unshift(fromCell); - } else if (startIdx !== 0) { - scaledCells.splice(0, startIdx); - } - - // Ensure end is correct - const endIdx = scaledCells.findIndex( - (c) => c.x === toCell.x && c.y === toCell.y, - ); - if (endIdx === -1) { - scaledCells.push(toCell); - } else if (endIdx !== scaledCells.length - 1) { - scaledCells.splice(endIdx + 1); - } - - // Convert back to TileRefs - return scaledCells.map((cell) => map.ref(cell.x, cell.y)); - } - - private tracePath(from: TileRef, to: TileRef): TileRef[] | null { - const x0 = this.game.x(from); - const y0 = this.game.y(from); - const x1 = this.game.x(to); - const y1 = this.game.y(to); - - const tiles: TileRef[] = []; - - // Bresenham's line algorithm - trace and collect all tiles - const dx = Math.abs(x1 - x0); - const dy = Math.abs(y1 - y0); - const sx = x0 < x1 ? 1 : -1; - const sy = y0 < y1 ? 1 : -1; - let err = dx - dy; - - let x = x0; - let y = y0; - - // Safety limit to prevent excessive memory allocation - const maxTiles = 100000; - let iterations = 0; - - while (true) { - if (iterations++ > maxTiles) { - return null; // Path too long - } - const tile = this.game.ref(x, y); - if (!this.game.isWater(tile)) { - return null; // Path blocked - } - - tiles.push(tile); - - if (x === x1 && y === y1) { - break; - } - - const e2 = 2 * err; - const shouldMoveX = e2 > -dy; - const shouldMoveY = e2 < dx; - - if (shouldMoveX && shouldMoveY) { - // Diagonal move - need to expand into two 4-directional moves - // Try moving X first, then Y - x += sx; - err -= dy; - - const intermediateTile = this.game.ref(x, y); - if (!this.game.isWater(intermediateTile)) { - // X first doesn't work, try Y first instead - x -= sx; // undo - err += dy; // undo - - y += sy; - err += dx; - - const altTile = this.game.ref(x, y); - if (!this.game.isWater(altTile)) { - return null; // Neither direction works - } - tiles.push(altTile); - - // Now move X - x += sx; - err -= dy; - } else { - tiles.push(intermediateTile); - - // Now move Y - y += sy; - err += dx; - } - } else { - // Single-axis move - if (shouldMoveX) { - x += sx; - err -= dy; - } - - if (shouldMoveY) { - y += sy; - err += dx; - } - } - } - - return tiles; - } - - private smoothPath(path: TileRef[]): TileRef[] { - if (path.length <= 2) { - return path; - } - - const smoothed: TileRef[] = []; - let current = 0; - - while (current < path.length - 1) { - // Look as far ahead as possible while maintaining line of sight - let farthest = current + 1; - let bestTrace: TileRef[] | null = null; - - for ( - let i = current + 2; - i < path.length; - i += Math.max(1, Math.floor(path.length / 20)) - ) { - const trace = this.tracePath(path[current], path[i]); - - if (trace !== null) { - farthest = i; - bestTrace = trace; - } else { - break; - } - } - - // Also try the final tile if we haven't already - if ( - farthest < path.length - 1 && - (path.length - 1 - current) % 10 !== 0 - ) { - const trace = this.tracePath(path[current], path[path.length - 1]); - if (trace !== null) { - farthest = path.length - 1; - bestTrace = trace; - } - } - - // Add the traced path (or just current tile if no improvement) - if (bestTrace !== null && farthest > current + 1) { - // Add all tiles from the trace except the last one (to avoid duplication) - smoothed.push(...bestTrace.slice(0, -1)); - } else { - // No LOS improvement, just add current tile - smoothed.push(path[current]); - } - - current = farthest; - } - - // Add the final tile - smoothed.push(path[path.length - 1]); - - return smoothed; - } -} diff --git a/src/core/pathfinding/smoothing/BresenhamPathSmoother.ts b/src/core/pathfinding/smoothing/BresenhamPathSmoother.ts new file mode 100644 index 000000000..d4cafdba9 --- /dev/null +++ b/src/core/pathfinding/smoothing/BresenhamPathSmoother.ts @@ -0,0 +1,168 @@ +import { GameMap, TileRef } from "../../game/GameMap"; +import { PathFinder } from "../types"; +import { PathSmoother } from "./PathSmoother"; + +/** + * Path smoother using Bresenham line-of-sight algorithm. + * Greedily skips waypoints when direct traversal is possible. + */ +export class BresenhamPathSmoother implements PathSmoother { + constructor( + private map: GameMap, + private isTraversable: (tile: TileRef) => boolean, + ) {} + + smooth(path: TileRef[]): TileRef[] { + if (path.length <= 2) { + return path; + } + + const smoothed: TileRef[] = []; + let current = 0; + + while (current < path.length - 1) { + let farthest = current + 1; + let bestTrace: TileRef[] | null = null; + + for ( + let i = current + 2; + i < path.length; + i += Math.max(1, Math.floor(path.length / 20)) + ) { + const trace = this.tracePath(path[current], path[i]); + + if (trace !== null) { + farthest = i; + bestTrace = trace; + } else { + break; + } + } + + if ( + farthest < path.length - 1 && + (path.length - 1 - current) % 10 !== 0 + ) { + const trace = this.tracePath(path[current], path[path.length - 1]); + if (trace !== null) { + farthest = path.length - 1; + bestTrace = trace; + } + } + + if (bestTrace !== null && farthest > current + 1) { + smoothed.push(...bestTrace.slice(0, -1)); + } else { + smoothed.push(path[current]); + } + + current = farthest; + } + + smoothed.push(path[path.length - 1]); + + return smoothed; + } + + private tracePath(from: TileRef, to: TileRef): TileRef[] | null { + const x0 = this.map.x(from); + const y0 = this.map.y(from); + const x1 = this.map.x(to); + const y1 = this.map.y(to); + + const tiles: TileRef[] = []; + + const dx = Math.abs(x1 - x0); + const dy = Math.abs(y1 - y0); + const sx = x0 < x1 ? 1 : -1; + const sy = y0 < y1 ? 1 : -1; + let err = dx - dy; + + let x = x0; + let y = y0; + + const maxTiles = 100000; + let iterations = 0; + + while (true) { + if (iterations++ > maxTiles) { + return null; + } + const tile = this.map.ref(x, y); + if (!this.isTraversable(tile)) { + return null; + } + + tiles.push(tile); + + if (x === x1 && y === y1) { + break; + } + + const e2 = 2 * err; + const shouldMoveX = e2 > -dy; + const shouldMoveY = e2 < dx; + + if (shouldMoveX && shouldMoveY) { + x += sx; + err -= dy; + + const intermediateTile = this.map.ref(x, y); + if (!this.isTraversable(intermediateTile)) { + x -= sx; + err += dy; + + y += sy; + err += dx; + + const altTile = this.map.ref(x, y); + if (!this.isTraversable(altTile)) { + return null; + } + tiles.push(altTile); + + x += sx; + err -= dy; + } else { + tiles.push(intermediateTile); + + y += sy; + err += dx; + } + } else { + if (shouldMoveX) { + x += sx; + err -= dy; + } + + if (shouldMoveY) { + y += sy; + err += dx; + } + } + } + + return tiles; + } +} + +/** + * Ready-to-use transformer that applies Bresenham smoothing. + * Defaults to water traversability. + */ +export class BresenhamSmoothingTransformer implements PathFinder { + private smoother: BresenhamPathSmoother; + + constructor( + private inner: PathFinder, + map: GameMap, + isTraversable: (tile: TileRef) => boolean = (t) => map.isWater(t), + ) { + this.smoother = new BresenhamPathSmoother(map, isTraversable); + } + + findPath(from: TileRef | TileRef[], to: TileRef): TileRef[] | null { + const path = this.inner.findPath(from, to); + return path ? this.smoother.smooth(path) : null; + } +} diff --git a/src/core/pathfinding/smoothing/PathSmoother.ts b/src/core/pathfinding/smoothing/PathSmoother.ts new file mode 100644 index 000000000..fc4188afc --- /dev/null +++ b/src/core/pathfinding/smoothing/PathSmoother.ts @@ -0,0 +1,7 @@ +/** + * PathSmoother - interface for path smoothing algorithms. + * Takes a path and returns a smoothed version. + */ +export interface PathSmoother { + smooth(path: T[]): T[]; +} diff --git a/src/core/pathfinding/smoothing/SmoothingTransformer.ts b/src/core/pathfinding/smoothing/SmoothingTransformer.ts new file mode 100644 index 000000000..ed1c60bff --- /dev/null +++ b/src/core/pathfinding/smoothing/SmoothingTransformer.ts @@ -0,0 +1,18 @@ +import { PathFinder } from "../types"; +import { PathSmoother } from "./PathSmoother"; + +/** + * Transformer that applies path smoothing to any PathFinder. + * Wraps an inner PathFinder and smooths its output. + */ +export class SmoothingTransformer implements PathFinder { + constructor( + private inner: PathFinder, + private smoother: PathSmoother, + ) {} + + findPath(from: T | T[], to: T): T[] | null { + const path = this.inner.findPath(from, to); + return path ? this.smoother.smooth(path) : null; + } +} diff --git a/src/core/pathfinding/spatial/SpatialQuery.ts b/src/core/pathfinding/spatial/SpatialQuery.ts new file mode 100644 index 000000000..1336a636f --- /dev/null +++ b/src/core/pathfinding/spatial/SpatialQuery.ts @@ -0,0 +1,90 @@ +import { Game, Player, TerraNullius } from "../../game/Game"; +import { TileRef } from "../../game/GameMap"; +import { PathFinding } from "../PathFinder"; + +type Owner = Player | TerraNullius; + +export class SpatialQuery { + constructor(private game: Game) {} + + /** + * Find nearest tile matching predicate using BFS traversal. + * Uses Manhattan distance filter, ignores terrain barriers. + */ + private bfsNearest( + from: TileRef, + maxDist: number, + predicate: (t: TileRef) => boolean, + ): TileRef | null { + const map = this.game.map(); + const candidates: TileRef[] = []; + + for (const tile of map.bfs( + from, + (_, t) => map.manhattanDist(from, t) <= maxDist, + )) { + if (predicate(tile)) { + candidates.push(tile); + } + } + + if (candidates.length === 0) return null; + + // Sort by Manhattan distance to find actual nearest + candidates.sort( + (a, b) => map.manhattanDist(from, a) - map.manhattanDist(from, b), + ); + + return candidates[0]; + } + + /** + * Find closest shore tile by land BFS. + * Works for both players and terra nullius. + */ + closestShore( + owner: Owner, + tile: TileRef, + maxDist: number = 50, + ): TileRef | null { + const gm = this.game; + const ownerId = owner.smallID(); + + const isValidTile = (t: TileRef) => { + if (!gm.isShore(t) || !gm.isLand(t)) return false; + const tOwner = gm.ownerID(t); + return tOwner === ownerId; + }; + + return this.bfsNearest(tile, maxDist, isValidTile); + } + + /** + * Find closest shore tile by water pathfinding. + * Returns null for terra nullius (no borderTiles). + */ + closestShoreByWater(owner: Owner, target: TileRef): TileRef | null { + if (!owner.isPlayer()) return null; + + const gm = this.game; + const player = owner as Player; + + // Target must be water or shore (land adjacent to water) + if (!gm.isWater(target) && !gm.isShore(target)) return null; + + const targetComponent = gm.getWaterComponent(target); + if (targetComponent === null) return null; + + const isValidTile = (t: TileRef) => { + if (!gm.isShore(t) || !gm.isLand(t)) return false; + const tComponent = gm.getWaterComponent(t); + return tComponent === targetComponent; + }; + + const shores = Array.from(player.borderTiles()).filter(isValidTile); + if (shores.length === 0) return null; + + const path = PathFinding.Water(gm).findPath(shores, target); + return path?.[0] ?? null; + } +} diff --git a/src/core/pathfinding/transformers/ComponentCheckTransformer.ts b/src/core/pathfinding/transformers/ComponentCheckTransformer.ts new file mode 100644 index 000000000..2d1d4d685 --- /dev/null +++ b/src/core/pathfinding/transformers/ComponentCheckTransformer.ts @@ -0,0 +1,35 @@ +// Component check transformer - fail fast if src/dst in different components + +import { PathFinder } from "../types"; + +/** + * Wraps a PathFinder to fail fast when source and destination + * are in different components (e.g., disconnected water bodies). + * + * Avoids running expensive pathfinding when no path exists. + */ +export class ComponentCheckTransformer implements PathFinder { + constructor( + private inner: PathFinder, + private getComponent: (t: T) => number, + ) {} + + findPath(from: T | T[], to: T): T[] | null { + const toComponent = this.getComponent(to); + + // Check all sources - at least one must match destination component + const fromArray = Array.isArray(from) ? from : [from]; + const validSources = fromArray.filter( + (f) => this.getComponent(f) === toComponent, + ); + + if (validSources.length === 0) { + return null; // No source in same component as destination + } + + // Delegate with only valid sources + const delegateFrom = + validSources.length === 1 ? validSources[0] : validSources; + return this.inner.findPath(delegateFrom, to); + } +} diff --git a/src/core/pathfinding/transformers/MiniMapTransformer.ts b/src/core/pathfinding/transformers/MiniMapTransformer.ts new file mode 100644 index 000000000..885368716 --- /dev/null +++ b/src/core/pathfinding/transformers/MiniMapTransformer.ts @@ -0,0 +1,128 @@ +import { Cell } from "../../game/Game"; +import { GameMap, TileRef } from "../../game/GameMap"; +import { PathFinder } from "../types"; + +export class MiniMapTransformer implements PathFinder { + constructor( + private inner: PathFinder, + private map: GameMap, + private miniMap: GameMap, + ) {} + + findPath(from: TileRef | TileRef[], to: TileRef): TileRef[] | null { + // Convert game coords → minimap coords (supports multi-source) + const fromArray = Array.isArray(from) ? from : [from]; + const miniFromArray = fromArray.map((f) => + this.miniMap.ref( + Math.floor(this.map.x(f) / 2), + Math.floor(this.map.y(f) / 2), + ), + ); + const miniFrom = + miniFromArray.length === 1 ? miniFromArray[0] : miniFromArray; + + const miniTo = this.miniMap.ref( + Math.floor(this.map.x(to) / 2), + Math.floor(this.map.y(to) / 2), + ); + + // Search on minimap + const path = this.inner.findPath(miniFrom, miniTo); + if (!path || path.length === 0) { + return null; + } + + // Convert minimap TileRefs → Cells + const cellPath = path.map( + (ref) => new Cell(this.miniMap.x(ref), this.miniMap.y(ref)), + ); + + // For multi-source, find closest source to path start + const upscaledPath = this.upscalePath(cellPath); + let cellFrom: Cell | undefined; + if (Array.isArray(from)) { + if (upscaledPath.length > 0) { + const pathStart = upscaledPath[0]; + let minDist = Infinity; + for (const f of from) { + const fx = this.map.x(f); + const fy = this.map.y(f); + const dist = Math.abs(fx - pathStart.x) + Math.abs(fy - pathStart.y); + if (dist < minDist) { + minDist = dist; + cellFrom = new Cell(fx, fy); + } + } + } + } else { + cellFrom = new Cell(this.map.x(from), this.map.y(from)); + } + const cellTo = new Cell(this.map.x(to), this.map.y(to)); + const upscaled = this.fixExtremes(upscaledPath, cellTo, cellFrom); + + return upscaled.map((c) => this.map.ref(c.x, c.y)); + } + + private upscalePath(path: Cell[], scaleFactor: number = 2): Cell[] { + const scaledPath = path.map( + (point) => new Cell(point.x * scaleFactor, point.y * scaleFactor), + ); + + const smoothPath: Cell[] = []; + + for (let i = 0; i < scaledPath.length - 1; i++) { + const current = scaledPath[i]; + const next = scaledPath[i + 1]; + + smoothPath.push(current); + + const dx = next.x - current.x; + const dy = next.y - current.y; + const distance = Math.max(Math.abs(dx), Math.abs(dy)); + const steps = distance; + + for (let step = 1; step < steps; step++) { + smoothPath.push( + new Cell( + Math.round(current.x + (dx * step) / steps), + Math.round(current.y + (dy * step) / steps), + ), + ); + } + } + + if (scaledPath.length > 0) { + smoothPath.push(scaledPath[scaledPath.length - 1]); + } + + return smoothPath; + } + + private fixExtremes(upscaled: Cell[], cellDst: Cell, cellSrc?: Cell): Cell[] { + if (cellSrc !== undefined) { + const srcIndex = this.findCell(upscaled, cellSrc); + if (srcIndex === -1) { + upscaled.unshift(cellSrc); + } else if (srcIndex !== 0) { + upscaled = upscaled.slice(srcIndex); + } + } + + const dstIndex = this.findCell(upscaled, cellDst); + if (dstIndex === -1) { + upscaled.push(cellDst); + } else if (dstIndex !== upscaled.length - 1) { + upscaled = upscaled.slice(0, dstIndex + 1); + } + return upscaled; + } + + private findCell(cells: Cell[], target: Cell): number { + for (let i = 0; i < cells.length; i++) { + if (cells[i].x === target.x && cells[i].y === target.y) { + return i; + } + } + return -1; + } +} diff --git a/src/core/pathfinding/transformers/ShoreCoercingTransformer.ts b/src/core/pathfinding/transformers/ShoreCoercingTransformer.ts new file mode 100644 index 000000000..523387127 --- /dev/null +++ b/src/core/pathfinding/transformers/ShoreCoercingTransformer.ts @@ -0,0 +1,91 @@ +// Shore-coercing transformer that converts shore tiles to water tiles for pathfinding + +import { GameMap, TileRef } from "../../game/GameMap"; +import { PathFinder } from "../types"; + +/** + * Wraps a PathFinder to handle shore tiles. + * Coerces shore tiles to nearby water tiles before pathfinding, + * then fixes the path extremes to include the original shore tiles. + * + * Works at whatever resolution the map provides - can be used with + * full map or minimap-based pathfinders. + */ +export class ShoreCoercingTransformer implements PathFinder { + constructor( + private inner: PathFinder, + private map: GameMap, + ) {} + + findPath(from: TileRef | TileRef[], to: TileRef): TileRef[] | null { + const fromArray = Array.isArray(from) ? from : [from]; + const waterToOriginal = new Map(); + const waterFrom: TileRef[] = []; + + for (const f of fromArray) { + const coerced = this.coerceToWater(f); + if (coerced.water !== null) { + waterFrom.push(coerced.water); + waterToOriginal.set(coerced.water, coerced.original); + } + } + + if (waterFrom.length === 0) { + return null; + } + + // Coerce to tile + const coercedTo = this.coerceToWater(to); + if (coercedTo.water === null) { + return null; + } + + // Search on water tiles + const fromTiles = waterFrom.length === 1 ? waterFrom[0] : waterFrom; + const path = this.inner.findPath(fromTiles, coercedTo.water); + if (!path || path.length === 0) { + return null; + } + + // Look up the actual path start in the map + const originalShore = waterToOriginal.get(path[0]); + if (originalShore !== undefined && originalShore !== null) { + path.unshift(originalShore); + } + + // Append original to if different + if ( + coercedTo.original !== null && + path[path.length - 1] !== coercedTo.original + ) { + path.push(coercedTo.original); + } + + return path; + } + + /** + * Coerce a tile to water for pathfinding. + * If tile is already water, returns it unchanged. + * If tile is shore (land with water neighbor), finds the nearest water neighbor. + */ + private coerceToWater(tile: TileRef): { + water: TileRef | null; + original: TileRef | null; + } { + // If already water, no coercion needed + if (this.map.isWater(tile)) { + return { water: tile, original: null }; + } + + // Find adjacent water neighbor + for (const n of this.map.neighbors(tile)) { + if (this.map.isWater(n)) { + return { water: n, original: tile }; + } + } + + // No water neighbor found - let HPA* handle at minimap level + return { water: null, original: tile }; + } +} diff --git a/src/core/pathfinding/types.ts b/src/core/pathfinding/types.ts new file mode 100644 index 000000000..89e746957 --- /dev/null +++ b/src/core/pathfinding/types.ts @@ -0,0 +1,34 @@ +/** + * Core pathfinding types and interfaces. + * No dependencies - safe to import from anywhere. + */ + +export enum PathStatus { + NEXT, + PENDING, + COMPLETE, + NOT_FOUND, +} + +export type PathResult = + | { status: PathStatus.PENDING } + | { status: PathStatus.NEXT; node: T } + | { status: PathStatus.COMPLETE; node: T } + | { status: PathStatus.NOT_FOUND }; + +/** + * PathFinder - core pathfinding interface. + * Implementations find paths between nodes. + */ +export interface PathFinder { + findPath(from: T | T[], to: T): T[] | null; +} + +/** + * SteppingPathFinder - PathFinder with stepping support. + * Used by execution classes that need incremental path traversal. + */ +export interface SteppingPathFinder extends PathFinder { + next(from: T, to: T, dist?: number): PathResult; + invalidate(): void; +} diff --git a/tests/core/executions/TradeShipExecution.test.ts b/tests/core/executions/TradeShipExecution.test.ts index 2ea187a51..6e74d66ce 100644 --- a/tests/core/executions/TradeShipExecution.test.ts +++ b/tests/core/executions/TradeShipExecution.test.ts @@ -1,6 +1,6 @@ import { TradeShipExecution } from "../../../src/core/execution/TradeShipExecution"; import { Game, Player, Unit } from "../../../src/core/game/Game"; -import { PathStatus } from "../../../src/core/pathfinding/PathFinder"; +import { PathStatus } from "../../../src/core/pathfinding/types"; import { setup } from "../../util/Setup"; describe("TradeShipExecution", () => { diff --git a/tests/core/pathfinding/PathFinder.test.ts b/tests/core/pathfinding/PathFinder.test.ts deleted file mode 100644 index 2c13486f8..000000000 --- a/tests/core/pathfinding/PathFinder.test.ts +++ /dev/null @@ -1,332 +0,0 @@ -import { Game } from "../../../src/core/game/Game"; -import { TileRef } from "../../../src/core/game/GameMap"; -import { MiniAStarAdapter } from "../../../src/core/pathfinding/adapters/MiniAStarAdapter"; -import { NavMeshAdapter } from "../../../src/core/pathfinding/adapters/NavMeshAdapter"; -import { - PathFinder, - PathStatus, -} from "../../../src/core/pathfinding/PathFinder"; -import { setup } from "../../util/Setup"; -import { gameFromString } from "./utils"; - -type AdapterFactory = { - name: string; - create: (game: Game) => PathFinder; -}; - -const adapters: AdapterFactory[] = [ - { - name: "MiniAStarAdapter", - create: (game) => new MiniAStarAdapter(game, { waterPath: true }), - }, - { - name: "NavMeshAdapter", - create: (game) => new NavMeshAdapter(game), - }, -]; - -// Shared world game instance -let worldGame: Game; - -beforeAll(async () => { - worldGame = await setup("world", { disableNavMesh: false }); -}); - -describe.each(adapters)("$name", ({ create }) => { - describe("findPath()", () => { - test("finds path between adjacent tiles", async () => { - const game = await gameFromString(["WWWW"]); - const adapter = create(game); - const src = game.ref(0, 0); - const dst = game.ref(1, 0); - - const path = adapter.findPath(src, dst); - - expect(path).not.toBeNull(); - expect(path![0]).toBe(src); - expect(path![path!.length - 1]).toBe(dst); - }); - - test("finds path across multiple tiles", async () => { - const game = await gameFromString(["WWWWWW", "WWWWWW", "WWWWWW"]); - const adapter = create(game); - const src = game.ref(0, 0); - const dst = game.ref(5, 2); - - const path = adapter.findPath(src, dst); - - expect(path).not.toBeNull(); - expect(path![0]).toBe(src); - expect(path![path!.length - 1]).toBe(dst); - }); - - test("returns single-element path for same tile", async () => { - // Old quirk of MiniAStar, we return dst tile twice - // Should probably be fixed to return [] instead - - const game = await gameFromString(["WW"]); - const adapter = create(game); - const tile = game.ref(0, 0); - - const path = adapter.findPath(tile, tile); - - expect(path).not.toBeNull(); - expect(path!.length).toBe(1); - expect(path![0]).toBe(tile); - }); - - test("returns null for blocked path", async () => { - const game = await gameFromString(["WWLLWW"]); - const adapter = create(game); - const src = game.ref(0, 0); - const dst = game.ref(5, 0); - - const path = adapter.findPath(src, dst); - - expect(path).toBeNull(); - }); - - test("returns null for water to land", () => { - const adapter = create(worldGame); - const src = worldGame.ref(926, 283); // water - const dst = worldGame.ref(950, 230); // land - - const path = adapter.findPath(src, dst); - - expect(path).toBeNull(); - }); - - test("traverses 3-tile path in 3 tiles", async () => { - // Expected: [1, 2, 3] - const game = await gameFromString(["WWWW"]); - const adapter = create(game); - const src = game.ref(0, 0); - const dst = game.ref(3, 0); - - const path = adapter.findPath(src, dst); - - expect(path).not.toBeNull(); - expect(path).toEqual([ - game.ref(0, 0), - game.ref(1, 0), - game.ref(2, 0), - game.ref(3, 0), - ]); - }); - }); - - describe("next() state machine", () => { - test("returns NEXT on first call", async () => { - const game = await gameFromString(["WWWW"]); - const adapter = create(game); - const src = game.ref(0, 0); - const dst = game.ref(3, 0); - - const result = adapter.next(src, dst); - - expect(result.status).toBe(PathStatus.NEXT); - }); - - test("returns COMPLETE when at destination", async () => { - const game = await gameFromString(["WW"]); - const adapter = create(game); - const tile = game.ref(0, 0); - - const result = adapter.next(tile, tile); - - expect(result.status).toBe(PathStatus.COMPLETE); - }); - - test("returns NOT_FOUND for blocked path", async () => { - const game = await gameFromString(["WWLLWW"]); - const adapter = create(game); - const src = game.ref(0, 0); - const dst = game.ref(5, 0); - - const result = adapter.next(src, dst); - - expect(result.status).toBe(PathStatus.NOT_FOUND); - }); - - test("traverses 3-tile path in 4 calls", async () => { - // Expected: NEXT(1) -> NEXT(2) -> NEXT(3) -> COMPLETE(4) - const game = await gameFromString(["WWWW"]); - const adapter = create(game); - const src = game.ref(0, 0); - const dst = game.ref(3, 0); - - let current = src; - const steps: string[] = []; - - // 3 NEXT calls to reach destination - for (let i = 1; i <= 4; i++) { - const result = adapter.next(current, dst); - expect([PathStatus.NEXT, PathStatus.COMPLETE]).toContain(result.status); - - current = (result as { node: TileRef }).node; - steps.push(`${PathStatus[result.status]}(${current})`); - } - - expect(steps).toEqual(["NEXT(1)", "NEXT(2)", "NEXT(3)", "COMPLETE(3)"]); - }); - }); - - describe("Destination changes", () => { - test("reaches new destination when dest changes", async () => { - const game = await gameFromString(["WWWWWWWW"]); // 8 wide - const adapter = create(game); - const src = game.ref(0, 0); - const dst1 = game.ref(4, 0); - const dst2 = game.ref(7, 0); - - // First path exists - expect(adapter.findPath(src, dst1)).not.toBeNull(); - - // Can still find path to new destination - expect(adapter.findPath(dst1, dst2)).not.toBeNull(); - }); - - test("recomputes when destination changes mid-path", async () => { - const game = await gameFromString(["WWWWWWWWWWWWWWWWWWWW"]); // 20 wide - const adapter = create(game); - const src = game.ref(0, 0); - const dst1 = game.ref(10, 0); - const dst2 = game.ref(19, 0); - - // Start pathing to dst1, take one step - const result1 = adapter.next(src, dst1); - expect(result1.status).toBe(PathStatus.NEXT); - - // Change destination mid-path, continue from current position - let current = (result1 as { node: TileRef }).node; - let result = adapter.next(current, dst2); - for (let i = 0; i < 100 && result.status === PathStatus.NEXT; i++) { - current = (result as { node: TileRef }).node; - result = adapter.next(current, dst2); - } - - expect(result.status).toBe(PathStatus.COMPLETE); - expect(current).toBe(dst2); - }); - }); - - describe("Error handling", () => { - // MiniAStar logs console error when nulls passed, muted in test - - test("returns NOT_FOUND for null source", async () => { - const game = await gameFromString(["WWWW"]); - const adapter = create(game); - const dst = game.ref(0, 0); - - const consoleSpy = jest - .spyOn(console, "error") - .mockImplementation(() => {}); - const result = adapter.next(null as unknown as TileRef, dst); - expect(result.status).toBe(PathStatus.NOT_FOUND); - consoleSpy.mockRestore(); - }); - - test("returns NOT_FOUND for null destination", async () => { - const game = await gameFromString(["WWWW"]); - const adapter = create(game); - const src = game.ref(0, 0); - - const consoleSpy = jest - .spyOn(console, "error") - .mockImplementation(() => {}); - const result = adapter.next(src, null as unknown as TileRef); - expect(result.status).toBe(PathStatus.NOT_FOUND); - consoleSpy.mockRestore(); - }); - }); - - describe("dist parameter", () => { - test("returns COMPLETE when within dist", () => { - const adapter = create(worldGame); - const src = worldGame.ref(926, 283); - const dst = worldGame.ref(928, 283); // 2 tiles away - - const result = adapter.next(src, dst, 5); - - expect(result.status).toBe(PathStatus.COMPLETE); - }); - - test("returns NEXT when beyond dist", () => { - const adapter = create(worldGame); - const src = worldGame.ref(926, 283); - const dst = worldGame.ref(950, 257); - - // Adapter may need a few ticks to compute path - let result = adapter.next(src, dst, 5); - for (let i = 0; i < 100 && result.status === PathStatus.PENDING; i++) { - result = adapter.next(src, dst, 5); - } - - expect(result.status).toBe(PathStatus.NEXT); - }); - }); - - describe("World map routes", () => { - test("Spain to France (Mediterranean)", () => { - const adapter = create(worldGame); - const path = adapter.findPath( - worldGame.ref(926, 283), - worldGame.ref(950, 257), - ); - expect(path).not.toBeNull(); - }); - - test("Miami to Rio (Atlantic)", () => { - const adapter = create(worldGame); - const path = adapter.findPath( - worldGame.ref(488, 355), - worldGame.ref(680, 658), - ); - expect(path).not.toBeNull(); - expect(path!.length).toBeGreaterThan(100); - }); - - test("France to Poland (around Europe)", () => { - const adapter = create(worldGame); - const path = adapter.findPath( - worldGame.ref(950, 257), - worldGame.ref(1033, 175), - ); - expect(path).not.toBeNull(); - }); - - test("Miami to Spain (transatlantic)", () => { - const adapter = create(worldGame); - const path = adapter.findPath( - worldGame.ref(488, 355), - worldGame.ref(926, 283), - ); - expect(path).not.toBeNull(); - }); - - test("Rio to Poland (South Atlantic to Baltic)", () => { - const adapter = create(worldGame); - const path = adapter.findPath( - worldGame.ref(680, 658), - worldGame.ref(1033, 175), - ); - expect(path).not.toBeNull(); - }); - }); - - describe("Known bugs", () => { - test("path can cross 1-tile land barrier", async () => { - const game = await gameFromString(["WLLWLWWLLW"]); - const adapter = create(game); - const path = adapter.findPath(game.ref(0, 0), game.ref(9, 0)); - expect(path).not.toBeNull(); - }); - - test("path can cross diagonal land barrier", async () => { - const game = await gameFromString(["WL", "LW"]); - const adapter = create(game); - const path = adapter.findPath(game.ref(0, 0), game.ref(1, 1)); - expect(path).not.toBeNull(); - }); - }); -}); diff --git a/tests/core/pathfinding/PathFinderStepper.test.ts b/tests/core/pathfinding/PathFinderStepper.test.ts new file mode 100644 index 000000000..5d6ff0635 --- /dev/null +++ b/tests/core/pathfinding/PathFinderStepper.test.ts @@ -0,0 +1,178 @@ +import { PathFinderStepper } from "../../../src/core/pathfinding/PathFinderStepper"; +import { PathFinder, PathStatus } from "../../../src/core/pathfinding/types"; + +describe("PathFinderStepper", () => { + function createMockFinder( + pathMap: Map, + ): PathFinder { + return { + findPath(from: number | number[], to: number): number[] | null { + const fromTile = Array.isArray(from) ? from[0] : from; + const key = `${fromTile}->${to}`; + return pathMap.get(key) ?? null; + }, + }; + } + + describe("next", () => { + it("returns COMPLETE when at destination", () => { + const pathMap = new Map(); + const stepper = new PathFinderStepper(createMockFinder(pathMap)); + + const result = stepper.next(5, 5); + + expect(result.status).toBe(PathStatus.COMPLETE); + expect((result as { node: number }).node).toBe(5); + }); + + it("returns NEXT with path nodes sequentially", () => { + const pathMap = new Map([["1->4", [1, 2, 3, 4]]]); + const stepper = new PathFinderStepper(createMockFinder(pathMap)); + + // First step: 1 -> 4, returns 2 + const result1 = stepper.next(1, 4); + expect(result1.status).toBe(PathStatus.NEXT); + expect((result1 as { node: number }).node).toBe(2); + + // Second step: from 2, returns 3 + const result2 = stepper.next(2, 4); + expect(result2.status).toBe(PathStatus.NEXT); + expect((result2 as { node: number }).node).toBe(3); + + // Third step: from 3, returns 4 + const result3 = stepper.next(3, 4); + expect(result3.status).toBe(PathStatus.NEXT); + expect((result3 as { node: number }).node).toBe(4); + + // Fourth step: at destination + const result4 = stepper.next(4, 4); + expect(result4.status).toBe(PathStatus.COMPLETE); + }); + + it("returns NOT_FOUND when no path exists", () => { + const pathMap = new Map(); + const stepper = new PathFinderStepper(createMockFinder(pathMap)); + + const result = stepper.next(1, 99); + + expect(result.status).toBe(PathStatus.NOT_FOUND); + }); + + it("recomputes path when moved off-path", () => { + // Path from 1->5 goes through 2,3,4 + // Path from 10->5 goes through 9,8,7,6 + const pathMap = new Map([ + ["1->5", [1, 2, 3, 4, 5]], + ["10->5", [10, 9, 8, 7, 6, 5]], + ]); + const stepper = new PathFinderStepper(createMockFinder(pathMap)); + + // Start on path 1->5 + const result1 = stepper.next(1, 5); + expect(result1.status).toBe(PathStatus.NEXT); + expect((result1 as { node: number }).node).toBe(2); + + // Move off-path to tile 10 (not on original path) + // Should recompute using path from 10->5 + const result2 = stepper.next(10, 5); + expect(result2.status).toBe(PathStatus.NEXT); + expect((result2 as { node: number }).node).toBe(9); + }); + + it("recomputes path when destination changes", () => { + const pathMap = new Map([ + ["1->5", [1, 2, 3, 4, 5]], + ["2->9", [2, 6, 7, 8, 9]], + ]); + const stepper = new PathFinderStepper(createMockFinder(pathMap)); + + // Start on path 1->5 + const result1 = stepper.next(1, 5); + expect(result1.status).toBe(PathStatus.NEXT); + expect((result1 as { node: number }).node).toBe(2); + + // Change destination to 9 (from current position 2) + const result2 = stepper.next(2, 9); + expect(result2.status).toBe(PathStatus.NEXT); + expect((result2 as { node: number }).node).toBe(6); + }); + }); + + describe("invalidate", () => { + it("clears cached path so next recomputes", () => { + let callCount = 0; + const finder: PathFinder = { + findPath(from, to): number[] | null { + callCount++; + const fromTile = Array.isArray(from) ? from[0] : from; + return [fromTile, to]; + }, + }; + const stepper = new PathFinderStepper(finder); + + stepper.next(1, 5); + stepper.next(5, 5); + + // Second call follows path without recomputing + expect(callCount).toBe(1); + + stepper.invalidate(); + stepper.next(1, 5); + + // Recomputed path after invalidation + expect(callCount).toBe(2); + }); + }); + + describe("findPath", () => { + it("delegates to inner finder", () => { + const pathMap = new Map([["1->5", [1, 2, 3, 4, 5]]]); + const stepper = new PathFinderStepper(createMockFinder(pathMap)); + + const path = stepper.findPath(1, 5); + + expect(path).toEqual([1, 2, 3, 4, 5]); + }); + + it("supports multi-source", () => { + const finder: PathFinder = { + findPath(from, to): number[] | null { + const firstFrom = Array.isArray(from) ? from[0] : from; + return [firstFrom, to]; + }, + }; + const stepper = new PathFinderStepper(finder); + + const path = stepper.findPath([1, 2, 3], 5); + + expect(path).toEqual([1, 5]); + }); + }); + + describe("custom equals", () => { + it("uses custom equals function for position comparison", () => { + type Pos = { x: number; y: number }; + const posEquals = (a: Pos, b: Pos) => a.x === b.x && a.y === b.y; + + const finder: PathFinder = { + findPath(from, to): Pos[] | null { + const f = Array.isArray(from) ? from[0] : from; + return [f, { x: 2, y: 0 }, to]; + }, + }; + + const stepper = new PathFinderStepper(finder, { equals: posEquals }); + + const from1 = { x: 1, y: 0 }; + const to = { x: 3, y: 0 }; + + const result1 = stepper.next(from1, to); + expect(result1.status).toBe(PathStatus.NEXT); + + // Use equivalent but different object (a !== b), still on track + const result2 = stepper.next({ x: 2, y: 0 }, to); + expect(result2.status).toBe(PathStatus.NEXT); + expect((result2 as { node: Pos }).node).toEqual({ x: 3, y: 0 }); + }); + }); +}); diff --git a/tests/core/pathfinding/PathFinding.Air.test.ts b/tests/core/pathfinding/PathFinding.Air.test.ts new file mode 100644 index 000000000..0927ed530 --- /dev/null +++ b/tests/core/pathfinding/PathFinding.Air.test.ts @@ -0,0 +1,183 @@ +import { Game } from "../../../src/core/game/Game"; +import { TileRef } from "../../../src/core/game/GameMap"; +import { PathFinding } from "../../../src/core/pathfinding/PathFinder"; +import { SteppingPathFinder } from "../../../src/core/pathfinding/types"; +import { setup } from "../../util/Setup"; + +describe("PathFinding.Air", () => { + let game: Game; + + function createPathFinder(): SteppingPathFinder { + return PathFinding.Air(game); + } + + beforeAll(async () => { + game = await setup("ocean_and_land"); + }); + + describe("findPath", () => { + it("returns path between any two points (ignores terrain)", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + // Air pathfinder ignores terrain, so can go anywhere + // (2,2) → (14,14): manhattan = 24, path length = 25 + const from = map.ref(2, 2); + const to = map.ref(14, 14); + + const path = pathFinder.findPath(from, to); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(25); + expect(path![0]).toBe(from); + expect(path![path!.length - 1]).toBe(to); + }); + + it("throws error for multiple start points", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + const from = [map.ref(2, 2), map.ref(4, 4)]; + const to = map.ref(14, 14); + + expect(() => pathFinder.findPath(from, to)).toThrow( + "does not support multiple start points", + ); + }); + + it("returns single-tile path when from equals to", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + const tile = map.ref(8, 8); + + const path = pathFinder.findPath(tile, tile); + + expect(path).not.toBeNull(); + expect(path![0]).toBe(tile); + }); + }); + + describe("path validity", () => { + it("all consecutive tiles in path are adjacent (Manhattan distance 1)", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + // (2,2) → (14,14): manhattan = 24, path length = 25 + const from = map.ref(2, 2); + const to = map.ref(14, 14); + + const path = pathFinder.findPath(from, to); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(25); + + // Verify every consecutive pair is adjacent + for (let i = 1; i < path!.length; i++) { + const dist = map.manhattanDist(path![i - 1], path![i]); + expect(dist).toBe(1); + } + }); + + it("path ends at exact destination", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + const from = map.ref(5, 5); + const to = map.ref(10, 12); + + const path = pathFinder.findPath(from, to); + + expect(path).not.toBeNull(); + expect(path![path!.length - 1]).toBe(to); + }); + }); + + describe("path shapes", () => { + it("diagonal path has equal X and Y movement", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + // Equal X and Y offset: (0,0) → (10,10) + const from = map.ref(0, 0); + const to = map.ref(10, 10); + + const path = pathFinder.findPath(from, to); + expect(path).not.toBeNull(); + + let xMoves = 0; + let yMoves = 0; + for (let i = 1; i < path!.length; i++) { + const dx = map.x(path![i]) - map.x(path![i - 1]); + const dy = map.y(path![i]) - map.y(path![i - 1]); + if (dx !== 0) xMoves++; + if (dy !== 0) yMoves++; + } + + expect(xMoves).toBe(10); + expect(yMoves).toBe(10); + }); + + it("horizontal path has only X movement", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + // Pure horizontal: (0,5) → (15,5) + const from = map.ref(0, 5); + const to = map.ref(15, 5); + + const path = pathFinder.findPath(from, to); + expect(path).not.toBeNull(); + + let xMoves = 0; + let yMoves = 0; + for (let i = 1; i < path!.length; i++) { + const dx = map.x(path![i]) - map.x(path![i - 1]); + const dy = map.y(path![i]) - map.y(path![i - 1]); + if (dx !== 0) xMoves++; + if (dy !== 0) yMoves++; + } + + expect(xMoves).toBe(15); + expect(yMoves).toBe(0); + }); + + it("vertical path has only Y movement", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + // Pure vertical: (5,0) → (5,15) + const from = map.ref(5, 0); + const to = map.ref(5, 15); + + const path = pathFinder.findPath(from, to); + expect(path).not.toBeNull(); + + let xMoves = 0; + let yMoves = 0; + for (let i = 1; i < path!.length; i++) { + const dx = map.x(path![i]) - map.x(path![i - 1]); + const dy = map.y(path![i]) - map.y(path![i - 1]); + if (dx !== 0) xMoves++; + if (dy !== 0) yMoves++; + } + + expect(xMoves).toBe(0); + expect(yMoves).toBe(15); + }); + + it("adjacent tiles produce minimal path", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + const from = map.ref(5, 5); + const to = map.ref(6, 5); + + const path = pathFinder.findPath(from, to); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(2); + expect(path![0]).toBe(from); + expect(path![1]).toBe(to); + }); + }); +}); diff --git a/tests/core/pathfinding/PathFinding.Water.test.ts b/tests/core/pathfinding/PathFinding.Water.test.ts new file mode 100644 index 000000000..0023ff789 --- /dev/null +++ b/tests/core/pathfinding/PathFinding.Water.test.ts @@ -0,0 +1,276 @@ +import { Game } from "../../../src/core/game/Game"; +import { TileRef } from "../../../src/core/game/GameMap"; +import { PathFinding } from "../../../src/core/pathfinding/PathFinder"; +import { + PathStatus, + SteppingPathFinder, +} from "../../../src/core/pathfinding/types"; +import { setup } from "../../util/Setup"; +import { createGame, L, W } from "./_fixtures"; + +describe("PathFinding.Water", () => { + let game: Game; + let worldGame: Game; + + function createPathFinder(g: Game = game): SteppingPathFinder { + return PathFinding.Water(g); + } + + beforeAll(async () => { + game = await setup("ocean_and_land"); + worldGame = await setup("world", { disableNavMesh: false }); + }); + + describe("findPath", () => { + it("finds path between adjacent water tiles", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + const from = map.ref(8, 0); + const to = map.ref(9, 0); + + expect(map.isWater(from)).toBe(true); + expect(map.isWater(to)).toBe(true); + + const path = pathFinder.findPath(from, to); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(2); + expect(path![0]).toBe(from); + expect(path![1]).toBe(to); + }); + + it("returns null for land tiles", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + const landTile = map.ref(0, 0); + const waterTile = map.ref(8, 0); + + expect(map.isLand(landTile)).toBe(true); + expect(map.isShore(landTile)).toBe(false); + expect(map.isWater(waterTile)).toBe(true); + + const path = pathFinder.findPath(landTile, waterTile); + + expect(path).toBeNull(); + }); + + it("returns single-tile path when from equals to", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + const waterTile = map.ref(8, 0); + expect(map.isWater(waterTile)).toBe(true); + + const path = pathFinder.findPath(waterTile, waterTile); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(1); + expect(path![0]).toBe(waterTile); + }); + + it("supports multiple start tiles", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + const dest = map.ref(8, 0); + const source1 = map.ref(9, 0); + const source2 = map.ref(8, 1); + + expect(map.isWater(dest)).toBe(true); + expect(map.isWater(source1)).toBe(true); + expect(map.isWater(source2)).toBe(true); + + const from = [source1, source2]; + const path = pathFinder.findPath(from, dest); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(2); + expect(from).toContain(path![0]); + expect(path![1]).toBe(dest); + }); + }); + + describe("path validity", () => { + it("all consecutive tiles in path are connected", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + // Distant water tiles: (8,0) → (15,4), distance = 11 + const from = map.ref(8, 0); + const to = map.ref(15, 4); + + expect(map.isWater(from)).toBe(true); + expect(map.isWater(to)).toBe(true); + expect(map.manhattanDist(from, to)).toBe(11); + + const path = pathFinder.findPath(from, to); + + expect(path).not.toBeNull(); + + for (let i = 1; i < path!.length; i++) { + const dist = map.manhattanDist(path![i - 1], path![i]); + expect(dist).toEqual(1); + } + }); + }); + + describe("shore handling", () => { + it("path from shore to shore starts and ends on shore", () => { + const pathFinder = createPathFinder(); + const map = game.map(); + + // Shore tiles at (7,0) and (7,6), distance = 6 + // Both have water neighbors at (8,0) and (8,6) + const from = map.ref(7, 0); + const to = map.ref(7, 6); + + expect(map.isShore(from)).toBe(true); + expect(map.isShore(to)).toBe(true); + expect(map.manhattanDist(from, to)).toBe(6); + + const path = pathFinder.findPath(from, to); + + expect(path).not.toBeNull(); + expect(path![0]).toBe(from); + expect(path![path!.length - 1]).toBe(to); + }); + }); + + describe("determinism", () => { + it("same inputs produce identical paths", () => { + const pathFinder1 = createPathFinder(); + const pathFinder2 = createPathFinder(); + const map = game.map(); + + // Distant water tiles: (8,0) → (15,4) + const from = map.ref(8, 0); + const to = map.ref(15, 4); + + const path1 = pathFinder1.findPath(from, to); + const path2 = pathFinder2.findPath(from, to); + + expect(path1).not.toBeNull(); + expect(path2).not.toBeNull(); + expect(path1).toEqual(path2); + }); + }); + + describe("World map routes", () => { + it("Spain to France (Mediterranean)", () => { + const pathFinder = createPathFinder(worldGame); + const path = pathFinder.findPath( + worldGame.ref(926, 283), + worldGame.ref(950, 257), + ); + expect(path).not.toBeNull(); + }); + + it("Miami to Rio (Atlantic)", () => { + const pathFinder = createPathFinder(worldGame); + const path = pathFinder.findPath( + worldGame.ref(488, 355), + worldGame.ref(680, 658), + ); + expect(path).not.toBeNull(); + }); + + it("France to Poland (around Europe)", () => { + const pathFinder = createPathFinder(worldGame); + const path = pathFinder.findPath( + worldGame.ref(950, 257), + worldGame.ref(1033, 175), + ); + expect(path).not.toBeNull(); + }); + + it("Miami to Spain (transatlantic)", () => { + const pathFinder = createPathFinder(worldGame); + const path = pathFinder.findPath( + worldGame.ref(488, 355), + worldGame.ref(926, 283), + ); + expect(path).not.toBeNull(); + }); + + it("Rio to Poland (South Atlantic to Baltic)", () => { + const pathFinder = createPathFinder(worldGame); + const path = pathFinder.findPath( + worldGame.ref(680, 658), + worldGame.ref(1033, 175), + ); + expect(path).not.toBeNull(); + }); + }); + + describe("Error handling", () => { + it("returns NOT_FOUND for null source", () => { + const pathFinder = createPathFinder(); + + const consoleSpy = jest + .spyOn(console, "error") + .mockImplementation(() => {}); + + const result = pathFinder.next( + null as unknown as TileRef, + game.ref(8, 0), + ); + + expect(result.status).toBe(PathStatus.NOT_FOUND); + + consoleSpy.mockRestore(); + }); + + it("returns NOT_FOUND for null destination", () => { + const pathFinder = createPathFinder(); + + const consoleSpy = jest + .spyOn(console, "error") + .mockImplementation(() => {}); + + const result = pathFinder.next( + game.ref(8, 0), + null as unknown as TileRef, + ); + + expect(result.status).toBe(PathStatus.NOT_FOUND); + + consoleSpy.mockRestore(); + }); + }); + + describe("Known bugs", () => { + it("path can cross 1-tile land barrier", () => { + const syntheticGame = createGame({ + width: 10, + height: 1, + grid: [W, L, L, W, L, W, W, L, L, W], + }); + + const pathFinder = createPathFinder(syntheticGame); + const path = pathFinder.findPath( + syntheticGame.ref(0, 0), + syntheticGame.ref(9, 0), + ); + + expect(path).not.toBeNull(); + }); + + it("path can cross diagonal land barrier", () => { + const syntheticGame = createGame({ + width: 2, + height: 2, + grid: [W, L, L, W], + }); + + const pathFinder = createPathFinder(syntheticGame); + const path = pathFinder.findPath( + syntheticGame.ref(0, 0), + syntheticGame.ref(1, 1), + ); + + expect(path).not.toBeNull(); + }); + }); +}); diff --git a/tests/core/pathfinding/SpatialQuery.test.ts b/tests/core/pathfinding/SpatialQuery.test.ts new file mode 100644 index 000000000..7b28b823f --- /dev/null +++ b/tests/core/pathfinding/SpatialQuery.test.ts @@ -0,0 +1,235 @@ +import { SpawnExecution } from "../../../src/core/execution/SpawnExecution"; +import { + Game, + Player, + PlayerInfo, + PlayerType, +} from "../../../src/core/game/Game"; +import { TileRef } from "../../../src/core/game/GameMap"; +import { SpatialQuery } from "../../../src/core/pathfinding/spatial/SpatialQuery"; +import { createGame, L, W } from "./_fixtures"; + +// Spawns player and **expands territory** via getSpawnTiles (euclidean dist 4) +// Ref: src/core/execution/Util.ts +function addPlayer(game: Game, tile: TileRef): Player { + const info = new PlayerInfo( + undefined, + "test", + PlayerType.Human, + null, + "test_id", + ); + game.addPlayer(info); + game.addExecution(new SpawnExecution(info, tile)); + while (game.inSpawnPhase()) game.executeNextTick(); + return game.player(info.id); +} + +describe("SpatialQuery", () => { + describe("closestShore", () => { + it("finds shore tile owned by player", () => { + // prettier-ignore + const game = createGame({ + width: 5, height: 5, grid: [ + W, W, W, W, W, + W, L, L, L, W, + W, L, L, L, W, + W, L, L, L, W, + W, W, W, W, W, + ], + }); + + const spatial = new SpatialQuery(game); + const player = addPlayer(game, game.ref(2, 2)); + + // All land tiles owned by player because of spawn expansion + const result = spatial.closestShore(player, game.ref(2, 2)); + + expect(result).not.toBeNull(); + expect(game.isShore(result!)).toBe(true); + expect(game.ownerID(result!)).toBe(player.smallID()); + }); + + it("returns null when no shore within maxDist", () => { + // prettier-ignore + const game = createGame({ + width: 7, height: 7, grid: [ + W, W, W, W, W, W, W, + W, L, L, L, L, L, W, + W, L, L, L, L, L, W, + W, L, L, L, L, L, W, + W, L, L, L, L, L, W, + W, L, L, L, L, L, W, + W, W, W, W, W, W, W, + ], + }); + + const spatial = new SpatialQuery(game); + const player = addPlayer(game, game.ref(3, 3)); + + // maxDist=1 from center (3,3) - shore is 2 tiles away + const result = spatial.closestShore(player, game.ref(3, 3), 1); + + expect(result).toBeNull(); + }); + + it("finds shore on player's island (two separate islands)", () => { + // prettier-ignore + const game = createGame({ + width: 8, height: 4, grid: [ + L, L, W, W, W, W, L, L, + L, L, W, W, W, W, L, L, + L, L, W, W, W, W, L, L, + L, L, W, W, W, W, L, L, + ], + }); + + const spatial = new SpatialQuery(game); + const player = addPlayer(game, game.ref(0, 0)); + + const result = spatial.closestShore(player, game.ref(0, 2)); + + expect(result).not.toBeNull(); + expect(game.isShore(result!)).toBe(true); + expect(game.ownerID(result!)).toBe(player.smallID()); + expect(game.x(result!)).toBeLessThanOrEqual(2); + }); + + it("finds shore even if no land path exists (two separate islands)", () => { + // prettier-ignore + const game = createGame({ + width: 8, height: 4, grid: [ + L, L, W, W, W, W, L, L, + L, L, W, W, W, W, L, L, + L, L, W, W, W, W, L, L, + L, L, W, W, W, W, L, L, + ], + }); + + const spatial = new SpatialQuery(game); + const player = addPlayer(game, game.ref(0, 0)); + + const result = spatial.closestShore(player, game.ref(7, 2)); + + expect(result).not.toBeNull(); + expect(game.isShore(result!)).toBe(true); + expect(game.ownerID(result!)).toBe(player.smallID()); + expect(game.x(result!)).toBeLessThanOrEqual(2); + }); + + it("finds shore for terra nullius when land is unclaimed", () => { + // prettier-ignore + const game = createGame({ + width: 5, height: 5, grid: [ + W, W, W, W, W, + W, L, L, L, W, + W, L, L, L, W, + W, L, L, L, W, + W, W, W, W, W, + ], + }); + + const spatial = new SpatialQuery(game); + const terraNullius = game.terraNullius(); + + const result = spatial.closestShore(terraNullius, game.ref(2, 2)); + + expect(result).not.toBeNull(); + expect(game.isShore(result!)).toBe(true); + }); + }); + + describe("closestShoreByWater", () => { + it("returns null for terra nullius", () => { + // prettier-ignore + const game = createGame({ + width: 5, height: 5, grid: [ + W, W, W, W, W, + W, L, L, L, W, + W, L, L, L, W, + W, L, L, L, W, + W, W, W, W, W, + ], + }); + + const spatial = new SpatialQuery(game); + const terraNullius = game.terraNullius(); + + const result = spatial.closestShoreByWater(terraNullius, game.ref(0, 0)); + + expect(result).toBeNull(); + }); + + it("returns null when target is on land", () => { + // prettier-ignore + const game = createGame({ + width: 5, height: 5, grid: [ + W, W, W, W, W, + W, L, L, L, W, + W, L, L, L, W, + W, L, L, L, W, + W, W, W, W, W, + ], + }); + + const spatial = new SpatialQuery(game); + const player = addPlayer(game, game.ref(2, 2)); + + const result = spatial.closestShoreByWater(player, game.ref(2, 2)); + + expect(result).toBeNull(); + }); + + it("returns null when target is in disconnected water body", () => { + // prettier-ignore + const game = createGame({ + width: 14, height: 6, grid: [ + W, W, L, L, L, L, L, L, L, L, L, L, W, W, + W, W, L, L, L, L, L, L, L, L, L, L, W, W, + W, W, L, L, L, L, L, L, L, L, L, L, W, W, + W, W, L, L, L, L, L, L, L, L, L, L, W, W, + W, W, L, L, L, L, L, L, L, L, L, L, W, W, + W, W, L, L, L, L, L, L, L, L, L, L, W, W, + ], + }); + + const spatial = new SpatialQuery(game); + const player = addPlayer(game, game.ref(3, 2)); + const result = spatial.closestShoreByWater(player, game.ref(13, 2)); + + expect(result).toBeNull(); + }); + + it("finds shore via long water path around island", () => { + // prettier-ignore + const game = createGame({ + width: 18, height: 14, grid: [ + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, L, L, L, L, L, L, L, L, L, L, W, W, W, W, + W, W, W, W, L, L, L, L, L, L, L, L, L, L, W, W, W, W, + W, W, W, W, L, L, L, L, L, L, L, L, L, L, W, W, W, W, + W, W, W, W, L, L, L, L, L, L, L, L, L, L, W, W, W, W, + W, W, W, W, L, L, L, L, L, L, L, L, L, L, W, W, W, W, + W, W, W, W, L, L, L, L, L, L, L, L, L, L, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, L, + ], + }); + + const spatial = new SpatialQuery(game); + const player = addPlayer(game, game.ref(4, 4)); + + const target = game.ref(17, 13); + const result = spatial.closestShoreByWater(player, target); + + expect(result).not.toBeNull(); + expect(game.isShore(result!)).toBe(true); + expect(game.ownerID(result!)).toBe(player.smallID()); + }); + }); +}); diff --git a/tests/core/pathfinding/UniversalPathFinding.Parabola.test.ts b/tests/core/pathfinding/UniversalPathFinding.Parabola.test.ts new file mode 100644 index 000000000..94e167618 --- /dev/null +++ b/tests/core/pathfinding/UniversalPathFinding.Parabola.test.ts @@ -0,0 +1,319 @@ +import { GameMapImpl } from "../../../src/core/game/GameMap"; +import { UniversalPathFinding } from "../../../src/core/pathfinding/PathFinder"; +import { PathStatus } from "../../../src/core/pathfinding/types"; + +describe("UniversalPathFinding.Parabola", () => { + function createLargeMap() { + // Create a larger map for parabola tests (need space for arcs) + const W = 0x20; + const terrain = new Uint8Array(10000).fill(W); + return new GameMapImpl(100, 100, terrain, 0); + } + + describe("findPath", () => { + it("returns parabolic arc between two points", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map); + + const from = map.ref(10, 50); + const to = map.ref(90, 50); + + const path = finder.findPath(from, to); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(39); + expect(path![0]).toBe(from); + expect(path![path!.length - 1]).toBe(to); + }); + + it("throws error for multiple start points", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map); + + const from = [map.ref(10, 50), map.ref(20, 50)]; + const to = map.ref(90, 50); + + expect(() => finder.findPath(from, to)).toThrow( + "does not support multiple start points", + ); + }); + + it("handles same start and end point", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map); + + const tile = map.ref(50, 50); + + const path = finder.findPath(tile, tile); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(26); + }); + + it("creates arc across map", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map); + + const from = map.ref(0, 50); + const to = map.ref(99, 50); + + const path = finder.findPath(from, to); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(43); + expect(path![0]).toBe(from); + expect(path![path!.length - 1]).toBe(to); + }); + }); + + describe("next (stepping)", () => { + it("returns NEXT with node when not at destination", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map); + + const from = map.ref(10, 50); + const to = map.ref(90, 50); + + const result = finder.next(from, to); + + expect(result.status).toBe(PathStatus.NEXT); + expect("node" in result).toBe(true); + }); + + it("respects speed parameter (higher speed = further movement)", () => { + const map = createLargeMap(); + const finder1 = UniversalPathFinding.Parabola(map); + const finder2 = UniversalPathFinding.Parabola(map); + + const from = map.ref(10, 50); + const to = map.ref(90, 50); + + // Step with speed 1 + const result1 = finder1.next(from, to, 1); + + // Step with speed 5 + const result2 = finder2.next(from, to, 5); + + // Both should be NEXT (not at destination yet) + expect(result1.status).toBe(PathStatus.NEXT); + expect(result2.status).toBe(PathStatus.NEXT); + + const node1 = ( + result1 as { status: typeof PathStatus.NEXT; node: number } + ).node; + const node2 = ( + result2 as { status: typeof PathStatus.NEXT; node: number } + ).node; + + // Speed 5 should move strictly further than speed 1 + const dist1 = map.manhattanDist(from, node1); + const dist2 = map.manhattanDist(from, node2); + expect(dist2).toBeGreaterThan(dist1); + + expect(finder2.currentIndex()).toBeGreaterThan(finder1.currentIndex()); + }); + }); + + describe("options", () => { + it("increment option affects path density", () => { + const map = createLargeMap(); + const finder1 = UniversalPathFinding.Parabola(map, { increment: 1 }); + const finder2 = UniversalPathFinding.Parabola(map, { increment: 10 }); + + const from = map.ref(10, 50); + const to = map.ref(90, 50); + + const path1 = finder1.findPath(from, to); + const path2 = finder2.findPath(from, to); + + expect(path1).not.toBeNull(); + expect(path2).not.toBeNull(); + + expect(path1!.length).toBeGreaterThan(path2!.length); + }); + + it("distanceBasedHeight option affects arc height", () => { + const map = createLargeMap(); + const finder1 = UniversalPathFinding.Parabola(map, { + distanceBasedHeight: true, + }); + const finder2 = UniversalPathFinding.Parabola(map, { + distanceBasedHeight: false, + }); + + const from = map.ref(10, 50); + const to = map.ref(90, 50); + + const path1 = finder1.findPath(from, to); + const path2 = finder2.findPath(from, to); + + expect(path1).not.toBeNull(); + expect(path2).not.toBeNull(); + + // With distanceBasedHeight=true, path should have Y deviation + // With distanceBasedHeight=false, path should be more direct + const getMaxYDeviation = (path: number[]) => { + const midY = map.y(from); + return Math.max(...path.map((t) => Math.abs(map.y(t) - midY))); + }; + + const dev1 = getMaxYDeviation(path1!); + const dev2 = getMaxYDeviation(path2!); + expect(dev1).toBeGreaterThan(dev2); + }); + + it("directionUp option affects arc direction", () => { + const map = createLargeMap(); + const finderUp = UniversalPathFinding.Parabola(map, { + directionUp: true, + }); + const finderDown = UniversalPathFinding.Parabola(map, { + directionUp: false, + }); + + const from = map.ref(10, 50); + const to = map.ref(90, 50); + + const pathUp = finderUp.findPath(from, to); + const pathDown = finderDown.findPath(from, to); + + expect(pathUp).not.toBeNull(); + expect(pathDown).not.toBeNull(); + + // Get midpoint Y values + const midIdx = Math.floor(pathUp!.length / 2); + const midY_Up = map.y(pathUp![midIdx]); + const midY_Down = map.y(pathDown![midIdx]); + const startY = map.y(from); + + // directionUp=true means Y decreases (goes "up" on screen) + // directionUp=false means Y increases (goes "down" on screen) + expect(midY_Up).toBeLessThan(startY); + expect(midY_Down).toBeGreaterThan(startY); + }); + }); + + describe("currentIndex", () => { + it("returns 0 when no curve", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map); + + expect(finder.currentIndex()).toBe(0); + }); + + it("increments as path is stepped", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map); + + const from = map.ref(10, 50); + const to = map.ref(90, 50); + + let current = from; + let previousIndex = 0; + + for (let i = 0; i < 50; i++) { + const result = finder.next(current, to); + expect(result.status).toBe(PathStatus.NEXT); + + const index = finder.currentIndex(); + expect(index).toBeGreaterThanOrEqual(previousIndex); + previousIndex = index; + + current = (result as { status: typeof PathStatus.NEXT; node: number }) + .node; + } + }); + }); + + describe("short distances", () => { + it("creates valid arc for distance < 50 (PARABOLA_MIN_HEIGHT)", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map, { + distanceBasedHeight: true, + }); + + // Distance of 30 is less than PARABOLA_MIN_HEIGHT (50) + const from = map.ref(50, 50); + const to = map.ref(80, 50); + + const path = finder.findPath(from, to); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(28); + expect(path![0]).toBe(from); + expect(path![path!.length - 1]).toBe(to); + }); + + it("creates valid path for adjacent tiles (distance=1)", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map); + + const from = map.ref(50, 50); + const to = map.ref(51, 50); + + const path = finder.findPath(from, to); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(26); + expect(path![0]).toBe(from); + expect(path![path!.length - 1]).toBe(to); + }); + + it("creates valid path for very short distance (distance=5)", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map, { + distanceBasedHeight: true, + }); + + const from = map.ref(50, 50); + const to = map.ref(55, 50); + + const path = finder.findPath(from, to); + + expect(path).not.toBeNull(); + expect(path![0]).toBe(from); + expect(path![path!.length - 1]).toBe(to); + }); + }); + + describe("map boundary clipping", () => { + it("arc clipped at map top boundary (directionUp near y=0)", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map, { + directionUp: true, + distanceBasedHeight: true, + }); + + // Start near top of map + const from = map.ref(10, 5); + const to = map.ref(90, 5); + + const path = finder.findPath(from, to); + + expect(path).not.toBeNull(); + + for (const t of path!) { + expect(map.y(t)).toBeGreaterThanOrEqual(0); + } + }); + + it("arc clipped at map bottom boundary (directionDown near y=max)", () => { + const map = createLargeMap(); + const finder = UniversalPathFinding.Parabola(map, { + directionUp: false, + distanceBasedHeight: true, + }); + + const from = map.ref(10, 95); + const to = map.ref(90, 95); + + const path = finder.findPath(from, to); + + expect(path).not.toBeNull(); + + for (const t of path!) { + expect(map.y(t)).toBeLessThan(100); + } + }); + }); +}); diff --git a/tests/core/pathfinding/WaterComponents.test.ts b/tests/core/pathfinding/WaterComponents.test.ts new file mode 100644 index 000000000..77fb39946 --- /dev/null +++ b/tests/core/pathfinding/WaterComponents.test.ts @@ -0,0 +1,144 @@ +import { + ConnectedComponents, + LAND_MARKER, +} from "../../../src/core/pathfinding/algorithms/ConnectedComponents"; +import { createGameMap, createIslandMap, L, W } from "./_fixtures"; + +// prettier-ignore +const twoComponentsMapData = { + width: 7, height: 5, grid: [ + W, W, L, L, L, W, W, + W, W, L, L, L, W, W, + W, W, L, L, L, W, W, + W, W, L, L, L, W, W, + W, W, L, L, L, W, W, + ], +}; + +describe("ConnectedComponents", () => { + describe("getComponentId", () => { + it("returns 0 before initialization", () => { + const map = createGameMap(createIslandMap()); + const wc = new ConnectedComponents(map); + + // Water tile at (0,0) - should return 0 (not initialized) + const waterTile = map.ref(0, 0); + expect(wc.getComponentId(waterTile)).toBe(0); + }); + + it("returns same component ID for all water tiles in single connected area", () => { + const map = createGameMap(createIslandMap()); + const wc = new ConnectedComponents(map); + wc.initialize(); + + const water1 = map.ref(0, 0); + const water2 = map.ref(4, 0); + const water3 = map.ref(0, 4); + const water4 = map.ref(4, 4); + + expect(map.isWater(water1)).toBe(true); + expect(map.isWater(water2)).toBe(true); + expect(map.isWater(water3)).toBe(true); + expect(map.isWater(water4)).toBe(true); + + const id1 = wc.getComponentId(water1); + const id2 = wc.getComponentId(water2); + const id3 = wc.getComponentId(water3); + const id4 = wc.getComponentId(water4); + + expect(id1).toBe(1); + expect(id2).toBe(id1); + expect(id3).toBe(id1); + expect(id4).toBe(id1); + }); + + it("returns different component IDs for disconnected water areas", () => { + const map = createGameMap(twoComponentsMapData); + const wc = new ConnectedComponents(map); + wc.initialize(); + + const leftWater1 = map.ref(0, 0); + const leftWater2 = map.ref(1, 2); + const rightWater1 = map.ref(5, 0); + const rightWater2 = map.ref(6, 4); + + expect(map.isWater(leftWater1)).toBe(true); + expect(map.isWater(leftWater2)).toBe(true); + expect(map.isWater(rightWater1)).toBe(true); + expect(map.isWater(rightWater2)).toBe(true); + + const leftId1 = wc.getComponentId(leftWater1); + const leftId2 = wc.getComponentId(leftWater2); + const rightId1 = wc.getComponentId(rightWater1); + const rightId2 = wc.getComponentId(rightWater2); + + expect(leftId1).not.toBe(rightId1); + + expect(leftId1).toBe(leftId2); + expect(leftId1).toBeGreaterThan(0); + expect(leftId1).not.toBe(LAND_MARKER); + + expect(rightId1).toBe(rightId2); + expect(rightId1).toBeGreaterThan(0); + expect(rightId1).not.toBe(LAND_MARKER); + }); + + it("returns LAND_MARKER for land tiles", () => { + const map = createGameMap(twoComponentsMapData); + const wc = new ConnectedComponents(map); + wc.initialize(); + + const landTile1 = map.ref(2, 0); + const landTile2 = map.ref(3, 2); + const landTile3 = map.ref(4, 4); + + expect(map.isLand(landTile1)).toBe(true); + expect(map.isLand(landTile2)).toBe(true); + expect(map.isLand(landTile3)).toBe(true); + + expect(wc.getComponentId(landTile1)).toBe(LAND_MARKER); + expect(wc.getComponentId(landTile2)).toBe(LAND_MARKER); + expect(wc.getComponentId(landTile3)).toBe(LAND_MARKER); + }); + }); + + describe("determinism", () => { + it("produces same component IDs on repeated initialization", () => { + const map = createGameMap(twoComponentsMapData); + const wc1 = new ConnectedComponents(map); + const wc2 = new ConnectedComponents(map); + + wc1.initialize(); + wc2.initialize(); + + // Check all tiles have same component ID + for (let y = 0; y < 5; y++) { + for (let x = 0; x < 7; x++) { + const tile = map.ref(x, y); + expect(wc1.getComponentId(tile)).toBe(wc2.getComponentId(tile)); + } + } + }); + }); + + describe("direct terrain access optimization", () => { + it("produces same results with accessTerrainDirectly=false", () => { + const map = createGameMap(twoComponentsMapData); + const wcDirect = new ConnectedComponents(map, true); + const wcIndirect = new ConnectedComponents(map, false); + + wcDirect.initialize(); + wcIndirect.initialize(); + + // Check all tiles have same component ID + for (let y = 0; y < 5; y++) { + for (let x = 0; x < 7; x++) { + const tile = map.ref(x, y); + expect(wcDirect.getComponentId(tile)).toBe( + wcIndirect.getComponentId(tile), + ); + } + } + }); + }); +}); diff --git a/tests/core/pathfinding/_fixtures.ts b/tests/core/pathfinding/_fixtures.ts new file mode 100644 index 000000000..ae36dd05c --- /dev/null +++ b/tests/core/pathfinding/_fixtures.ts @@ -0,0 +1,179 @@ +// Minimal test maps for pathfinding unit tests + +import { + Difficulty, + Game, + GameMapType, + GameMode, + GameType, +} from "../../../src/core/game/Game"; +import { createGame as createGameImpl } from "../../../src/core/game/GameImpl"; +import { GameMapImpl } from "../../../src/core/game/GameMap"; +import { UserSettings } from "../../../src/core/game/UserSettings"; +import { PeaceTimerDuration } from "../../../src/core/Schemas"; +import { TestConfig } from "../../util/TestConfig"; +import { TestServerConfig } from "../../util/TestServerConfig"; + +export const W = "W"; // Water +export const L = "L"; // Land + +// Terrain encoding +const WATER_BIT = 0x20; +const LAND_BIT = 0x80; +const SHORELINE_BIT = 6; + +export type TestMapData = { + width: number; + height: number; + grid: string[]; +}; + +// Compute shoreline bit for tiles adjacent to opposite terrain +function computeShoreline( + terrain: Uint8Array, + width: number, + height: number, +): void { + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + const idx = y * width + x; + const isLand = (terrain[idx] & LAND_BIT) !== 0; + const neighbors = [ + [x - 1, y], + [x + 1, y], + [x, y - 1], + [x, y + 1], + ]; + + for (const [nx, ny] of neighbors) { + if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue; + const neighborIsLand = (terrain[ny * width + nx] & LAND_BIT) !== 0; + if (isLand !== neighborIsLand) { + terrain[idx] |= 1 << SHORELINE_BIT; + break; + } + } + } + } +} + +// 5x5 simple island +export function createIslandMap(): TestMapData { + // prettier-ignore + const grid = [ + W, W, W, W, W, + W, L, L, L, W, + W, L, L, L, W, + W, L, L, L, W, + W, W, W, W, W, + ]; + return { width: 5, height: 5, grid }; +} + +// Create Game from test map data (computes shoreline bits) +export function createGame(data: TestMapData): Game { + const { width, height, grid } = data; + + // Convert string grid to terrain bytes + const terrain = new Uint8Array(width * height); + let numLand = 0; + + for (let i = 0; i < grid.length; i++) { + if (grid[i] === L) { + terrain[i] = LAND_BIT; + numLand++; + } else { + terrain[i] = WATER_BIT; + } + } + + computeShoreline(terrain, width, height); + + const gameMap = new GameMapImpl(width, height, terrain, numLand); + + // Create miniMap (2x2→1, water if ANY water) + const miniWidth = Math.ceil(width / 2); + const miniHeight = Math.ceil(height / 2); + const miniTerrain = new Uint8Array(miniWidth * miniHeight); + let miniNumLand = 0; + + for (let my = 0; my < miniHeight; my++) { + for (let mx = 0; mx < miniWidth; mx++) { + const mIdx = my * miniWidth + mx; + let hasWater = false; + + for (let dy = 0; dy < 2; dy++) { + for (let dx = 0; dx < 2; dx++) { + const x = mx * 2 + dx; + const y = my * 2 + dy; + if (x < width && y < height && !(terrain[y * width + x] & LAND_BIT)) { + hasWater = true; + } + } + } + + if (hasWater) { + miniTerrain[mIdx] = WATER_BIT; + } else { + miniTerrain[mIdx] = LAND_BIT; + miniNumLand++; + } + } + } + + computeShoreline(miniTerrain, miniWidth, miniHeight); + + const miniGameMap = new GameMapImpl( + miniWidth, + miniHeight, + miniTerrain, + miniNumLand, + ); + + const serverConfig = new TestServerConfig(); + const gameConfig = { + gameMap: GameMapType.Asia, + gameMode: GameMode.FFA, + gameType: GameType.Singleplayer, + difficulty: Difficulty.Medium, + disableNPCs: false, + bots: 0, + infiniteGold: false, + infiniteTroops: false, + instantBuild: false, + disableNavMesh: false, + peaceTimerDurationMinutes: PeaceTimerDuration.None, + startingGold: 0 as const, + goldMultiplier: 1 as const, + chatEnabled: false, + }; + const config = new TestConfig( + serverConfig, + gameConfig, + new UserSettings(), + false, + ); + + return createGameImpl([], [], gameMap, miniGameMap, config); +} + +// Create GameMapImpl from test map data (for map-only tests) +export function createGameMap(data: TestMapData): GameMapImpl { + const { width, height, grid } = data; + + const terrain = new Uint8Array(width * height); + let numLand = 0; + + for (let i = 0; i < grid.length; i++) { + if (grid[i] === L) { + terrain[i] = LAND_BIT; + numLand++; + } else { + terrain[i] = WATER_BIT; + } + } + + computeShoreline(terrain, width, height); + + return new GameMapImpl(width, height, terrain, numLand); +} diff --git a/tests/core/pathfinding/transformers/ComponentCheckTransformer.test.ts b/tests/core/pathfinding/transformers/ComponentCheckTransformer.test.ts new file mode 100644 index 000000000..a3de9b233 --- /dev/null +++ b/tests/core/pathfinding/transformers/ComponentCheckTransformer.test.ts @@ -0,0 +1,168 @@ +import { ComponentCheckTransformer } from "../../../../src/core/pathfinding/transformers/ComponentCheckTransformer"; +import { PathFinder } from "../../../../src/core/pathfinding/types"; + +describe("ComponentCheckTransformer", () => { + // Mock PathFinder that records calls and returns a simple path + function createMockPathFinder(): PathFinder & { + calls: Array<{ from: number | number[]; to: number }>; + } { + const calls: Array<{ from: number | number[]; to: number }> = []; + + return { + calls, + findPath(from: number | number[], to: number): number[] | null { + calls.push({ from, to }); + const start = Array.isArray(from) ? from[0] : from; + return [start, to]; + }, + }; + } + + // Component function: even numbers → component 0, odd → component 1 + const evenOddComponent = (t: number) => t % 2; + + describe("findPath", () => { + it("delegates when source and destination in same component", () => { + const inner = createMockPathFinder(); + const transformer = new ComponentCheckTransformer( + inner, + evenOddComponent, + ); + + const result = transformer.findPath(2, 4); // both even → component 0 + + expect(result).toEqual([2, 4]); + expect(inner.calls).toHaveLength(1); + expect(inner.calls[0]).toEqual({ from: 2, to: 4 }); + }); + + it("returns null when source and destination in different components", () => { + const inner = createMockPathFinder(); + const transformer = new ComponentCheckTransformer( + inner, + evenOddComponent, + ); + + const result = transformer.findPath(2, 3); // even → odd + + expect(result).toBeNull(); + expect(inner.calls).toHaveLength(0); // inner not called + }); + + it("filters multiple sources to only valid ones", () => { + const inner = createMockPathFinder(); + const transformer = new ComponentCheckTransformer( + inner, + evenOddComponent, + ); + + // Sources: 1, 2, 3, 4 → odd, even, odd, even + // Destination: 4 → even + // Valid sources: 2, 4 + const result = transformer.findPath([1, 2, 3, 4], 4); + + expect(result).not.toBeNull(); + expect(inner.calls).toHaveLength(1); + expect(inner.calls[0].from).toEqual([2, 4]); // filtered to valid + expect(inner.calls[0].to).toBe(4); + }); + + it("returns null when no source in same component", () => { + const inner = createMockPathFinder(); + const transformer = new ComponentCheckTransformer( + inner, + evenOddComponent, + ); + + // All sources odd, destination even + const result = transformer.findPath([1, 3, 5], 4); + + expect(result).toBeNull(); + expect(inner.calls).toHaveLength(0); + }); + + it("unwraps single valid source from array", () => { + const inner = createMockPathFinder(); + const transformer = new ComponentCheckTransformer( + inner, + evenOddComponent, + ); + + // Only one source matches + const result = transformer.findPath([1, 2, 3], 4); + + expect(result).not.toBeNull(); + expect(inner.calls).toHaveLength(1); + expect(inner.calls[0].from).toBe(2); + }); + + it("handles single source (not array)", () => { + const inner = createMockPathFinder(); + const transformer = new ComponentCheckTransformer( + inner, + evenOddComponent, + ); + + const result = transformer.findPath(4, 6); + + expect(result).toEqual([4, 6]); + expect(inner.calls[0].from).toBe(4); + }); + + it("propagates null from inner pathfinder", () => { + const inner: PathFinder = { + findPath: () => null, + }; + const transformer = new ComponentCheckTransformer( + inner, + evenOddComponent, + ); + + const result = transformer.findPath(2, 4); + + expect(result).toBeNull(); + }); + + it("propagates path from inner pathfinder", () => { + const inner: PathFinder = { + findPath: () => [10, 20, 30, 40], + }; + const transformer = new ComponentCheckTransformer( + inner, + evenOddComponent, + ); + + const result = transformer.findPath(2, 4); + + expect(result).toEqual([10, 20, 30, 40]); + }); + }); + + describe("edge cases", () => { + it("handles empty source array", () => { + const inner = createMockPathFinder(); + const transformer = new ComponentCheckTransformer( + inner, + evenOddComponent, + ); + + const result = transformer.findPath([], 4); + + expect(result).toBeNull(); + expect(inner.calls).toHaveLength(0); + }); + + it("works with custom component function", () => { + const inner = createMockPathFinder(); + // Component by tens digit: 10-19 → 1, 20-29 → 2, etc. + const tensComponent = (t: number) => Math.floor(t / 10); + const transformer = new ComponentCheckTransformer(inner, tensComponent); + + // Same component + expect(transformer.findPath(15, 18)).not.toBeNull(); + + // Different component + expect(transformer.findPath(15, 25)).toBeNull(); + }); + }); +}); diff --git a/tests/core/pathfinding/transformers/MiniMapTransformer.test.ts b/tests/core/pathfinding/transformers/MiniMapTransformer.test.ts new file mode 100644 index 000000000..bc8b57c1f --- /dev/null +++ b/tests/core/pathfinding/transformers/MiniMapTransformer.test.ts @@ -0,0 +1,178 @@ +import { GameMapImpl } from "../../../../src/core/game/GameMap"; +import { MiniMapTransformer } from "../../../../src/core/pathfinding/transformers/MiniMapTransformer"; +import { PathFinder } from "../../../../src/core/pathfinding/types"; + +describe("MiniMapTransformer", () => { + // Create test maps: main map is 10x10, minimap is 5x5 (2x downscale) + function createTestMaps() { + const W = 0x20; // Water + const mainTerrain = new Uint8Array(100).fill(W); // 10x10 all water + const miniTerrain = new Uint8Array(25).fill(W); // 5x5 all water + + const map = new GameMapImpl(10, 10, mainTerrain, 0); + const miniMap = new GameMapImpl(5, 5, miniTerrain, 0); + + return { map, miniMap }; + } + + function createMockPathFinder(): PathFinder & { + calls: Array<{ from: number | number[]; to: number }>; + returnPath: number[] | null | undefined; + } { + const mock = { + calls: [] as Array<{ from: number | number[]; to: number }>, + returnPath: undefined as number[] | null | undefined, + findPath(from: number | number[], to: number): number[] | null { + mock.calls.push({ from, to }); + if (mock.returnPath !== undefined) return mock.returnPath; + const start = Array.isArray(from) ? from[0] : from; + return [start, to]; + }, + }; + return mock; + } + + describe("findPath", () => { + it("converts coordinates to minimap scale", () => { + const { map, miniMap } = createTestMaps(); + const inner = createMockPathFinder(); + const transformer = new MiniMapTransformer(inner, map, miniMap); + + const from = map.ref(4, 6); + const to = map.ref(8, 2); + + const miniFrom = miniMap.ref(2, 3); + const miniTo = miniMap.ref(4, 1); + inner.returnPath = [miniFrom, miniTo]; + + transformer.findPath(from, to); + + expect(inner.calls).toHaveLength(1); + expect(inner.calls[0].from).toBe(miniFrom); + expect(inner.calls[0].to).toBe(miniTo); + }); + + it("upscales minimap path back to full resolution", () => { + const { map, miniMap } = createTestMaps(); + const inner = createMockPathFinder(); + const transformer = new MiniMapTransformer(inner, map, miniMap); + + const from = map.ref(0, 0); + const to = map.ref(8, 0); + + // Minimap path: (0,0) → (4,0) - straight horizontal + inner.returnPath = [ + miniMap.ref(0, 0), + miniMap.ref(1, 0), + miniMap.ref(2, 0), + miniMap.ref(3, 0), + miniMap.ref(4, 0), + ]; + + const result = transformer.findPath(from, to); + + expect(result).not.toBeNull(); + expect(result![0]).toBe(from); + expect(result![result!.length - 1]).toBe(to); + }); + + it("returns null when inner returns null", () => { + const { map, miniMap } = createTestMaps(); + const inner = createMockPathFinder(); + inner.returnPath = null; + const transformer = new MiniMapTransformer(inner, map, miniMap); + + const result = transformer.findPath(map.ref(0, 0), map.ref(8, 8)); + + expect(result).toBeNull(); + }); + + it("returns null when inner returns empty path", () => { + const { map, miniMap } = createTestMaps(); + const inner = createMockPathFinder(); + inner.returnPath = []; + const transformer = new MiniMapTransformer(inner, map, miniMap); + + const result = transformer.findPath(map.ref(0, 0), map.ref(8, 8)); + + expect(result).toBeNull(); + }); + + it("handles multiple sources", () => { + const { map, miniMap } = createTestMaps(); + const inner = createMockPathFinder(); + const transformer = new MiniMapTransformer(inner, map, miniMap); + + const from1 = map.ref(0, 0); + const from2 = map.ref(2, 0); + const to = map.ref(8, 0); + + inner.returnPath = [miniMap.ref(0, 0), miniMap.ref(4, 0)]; + + const result = transformer.findPath([from1, from2], to); + + expect(inner.calls).toHaveLength(1); + expect(Array.isArray(inner.calls[0].from)).toBe(true); + expect(result).not.toBeNull(); + }); + + it("fixes path extremes to match original from/to", () => { + const { map, miniMap } = createTestMaps(); + const inner = createMockPathFinder(); + const transformer = new MiniMapTransformer(inner, map, miniMap); + + // From odd coords - won't exactly map to minimap + const from = map.ref(1, 1); + const to = map.ref(9, 9); + + inner.returnPath = [miniMap.ref(0, 0), miniMap.ref(4, 4)]; + + const result = transformer.findPath(from, to); + + expect(result).not.toBeNull(); + expect(result![0]).toBe(from); + expect(result![result!.length - 1]).toBe(to); + }); + }); + + describe("coordinate mapping", () => { + it("maps main coords (0,0) to mini coords (0,0)", () => { + const { map, miniMap } = createTestMaps(); + const inner = createMockPathFinder(); + const transformer = new MiniMapTransformer(inner, map, miniMap); + + inner.returnPath = [miniMap.ref(0, 0)]; + + transformer.findPath(map.ref(0, 0), map.ref(0, 0)); + + expect(inner.calls[0].from).toBe(miniMap.ref(0, 0)); + expect(inner.calls[0].to).toBe(miniMap.ref(0, 0)); + }); + + it("maps main coords (1,1) to mini coords (0,0) (floor division)", () => { + const { map, miniMap } = createTestMaps(); + const inner = createMockPathFinder(); + const transformer = new MiniMapTransformer(inner, map, miniMap); + + inner.returnPath = [miniMap.ref(0, 0)]; + + transformer.findPath(map.ref(1, 1), map.ref(1, 1)); + + expect(inner.calls[0].from).toBe(miniMap.ref(0, 0)); + expect(inner.calls[0].to).toBe(miniMap.ref(0, 0)); + }); + + it("maps main coords (2,2) to mini coords (1,1)", () => { + const { map, miniMap } = createTestMaps(); + const inner = createMockPathFinder(); + const transformer = new MiniMapTransformer(inner, map, miniMap); + + inner.returnPath = [miniMap.ref(1, 1)]; + + transformer.findPath(map.ref(2, 2), map.ref(2, 2)); + + expect(inner.calls[0].from).toBe(miniMap.ref(1, 1)); + expect(inner.calls[0].to).toBe(miniMap.ref(1, 1)); + }); + }); +}); diff --git a/tests/core/pathfinding/transformers/ShoreCoercingTransformer.test.ts b/tests/core/pathfinding/transformers/ShoreCoercingTransformer.test.ts new file mode 100644 index 000000000..88c08e758 --- /dev/null +++ b/tests/core/pathfinding/transformers/ShoreCoercingTransformer.test.ts @@ -0,0 +1,244 @@ +import { ShoreCoercingTransformer } from "../../../../src/core/pathfinding/transformers/ShoreCoercingTransformer"; +import { PathFinder } from "../../../../src/core/pathfinding/types"; +import { createGameMap, createIslandMap, L, W } from "../_fixtures"; + +describe("ShoreCoercingTransformer", () => { + // Mock PathFinder that records calls and returns configurable path + function createMockPathFinder(): PathFinder & { + calls: Array<{ from: number | number[]; to: number }>; + returnPath: number[] | null | undefined; + } { + const mock = { + calls: [] as Array<{ from: number | number[]; to: number }>, + returnPath: undefined as number[] | null | undefined, + findPath(from: number | number[], to: number): number[] | null { + mock.calls.push({ from, to }); + if (mock.returnPath !== undefined) return mock.returnPath; + const start = Array.isArray(from) ? from[0] : from; + return [start, to]; + }, + }; + return mock; + } + + describe("findPath", () => { + it("passes water tiles unchanged", () => { + const mapData = createIslandMap(); + const map = createGameMap(mapData); + const inner = createMockPathFinder(); + const transformer = new ShoreCoercingTransformer(inner, map); + + const water1 = map.ref(0, 0); + const water2 = map.ref(4, 0); + inner.returnPath = [water1, water2]; + + const result = transformer.findPath(water1, water2); + + expect(result).toEqual([water1, water2]); + expect(inner.calls).toHaveLength(1); + expect(inner.calls[0].from).toBe(water1); + expect(inner.calls[0].to).toBe(water2); + }); + + it("coerces shore start to water and prepends original", () => { + const mapData = createIslandMap(); + const map = createGameMap(mapData); + const inner = createMockPathFinder(); + const transformer = new ShoreCoercingTransformer(inner, map); + + const shore = map.ref(1, 1); + const water = map.ref(4, 4); + const shoreWaterNeighbor = map.ref(1, 0); + + const result = transformer.findPath(shore, water); + + expect(result).not.toBeNull(); + expect(result![0]).toBe(shore); + expect(result![1]).toBe(shoreWaterNeighbor); + }); + + it("coerces shore destination to water and appends original", () => { + const mapData = createIslandMap(); + const map = createGameMap(mapData); + const inner = createMockPathFinder(); + const transformer = new ShoreCoercingTransformer(inner, map); + + const water = map.ref(0, 0); + const shore = map.ref(1, 1); + const shoreWaterNeighbor = map.ref(1, 0); + + const result = transformer.findPath(water, shore); + + expect(result).not.toBeNull(); + expect(result![0]).toBe(water); + expect(result![result!.length - 2]).toBe(shoreWaterNeighbor); + expect(result![result!.length - 1]).toBe(shore); + }); + + it("coerces both shore start and destination", () => { + const mapData = createIslandMap(); + const map = createGameMap(mapData); + const inner = createMockPathFinder(); + const transformer = new ShoreCoercingTransformer(inner, map); + + const shore1 = map.ref(1, 1); + const shore1WaterNeighbor = map.ref(1, 0); + const shore2 = map.ref(3, 3); + const shore2WaterNeighbor = map.ref(3, 4); + + const result = transformer.findPath(shore1, shore2); + + expect(result).not.toBeNull(); + expect(result![0]).toBe(shore1); + expect(result![1]).toBe(shore1WaterNeighbor); + expect(result![result!.length - 2]).toBe(shore2WaterNeighbor); + expect(result![result!.length - 1]).toBe(shore2); + }); + + it("returns null when source has no water neighbor", () => { + const mapData = createIslandMap(); + const map = createGameMap(mapData); + const inner = createMockPathFinder(); + const transformer = new ShoreCoercingTransformer(inner, map); + + // Center land tile (2,2) has no water neighbors + const land = map.ref(2, 2); + const water = map.ref(0, 0); + + const result = transformer.findPath(land, water); + + expect(result).toBeNull(); + expect(inner.calls).toHaveLength(0); + }); + + it("returns null when destination has no water neighbor", () => { + const mapData = createIslandMap(); + const map = createGameMap(mapData); + const inner = createMockPathFinder(); + const transformer = new ShoreCoercingTransformer(inner, map); + + // Center land tile (2,2) has no water neighbors + const land = map.ref(2, 2); + const water = map.ref(0, 0); + + const result = transformer.findPath(water, land); + + expect(result).toBeNull(); + expect(inner.calls).toHaveLength(0); + }); + + it("returns null when inner pathfinder returns null", () => { + const mapData = createIslandMap(); + const map = createGameMap(mapData); + const inner = createMockPathFinder(); + const transformer = new ShoreCoercingTransformer(inner, map); + + inner.returnPath = null; + const result = transformer.findPath(map.ref(0, 0), map.ref(4, 4)); + + expect(result).toBeNull(); + }); + + it("returns null when inner pathfinder returns empty path", () => { + const mapData = createIslandMap(); + const map = createGameMap(mapData); + const inner = createMockPathFinder(); + const transformer = new ShoreCoercingTransformer(inner, map); + + inner.returnPath = []; + const result = transformer.findPath(map.ref(0, 0), map.ref(4, 4)); + + expect(result).toBeNull(); + }); + + it("handles multiple sources, filters invalid ones", () => { + const mapData = createIslandMap(); + const map = createGameMap(mapData); + const inner = createMockPathFinder(); + const transformer = new ShoreCoercingTransformer(inner, map); + + const waterSrc = map.ref(0, 0); + const shoreSrc = map.ref(1, 1); + const landSrc = map.ref(2, 2); + const waterDest = map.ref(4, 4); + + inner.returnPath = [waterSrc, waterDest]; + + const result = transformer.findPath( + [waterSrc, shoreSrc, landSrc], + waterDest, + ); + + expect(result).not.toBeNull(); + expect(inner.calls).toHaveLength(1); + + const fromArg = inner.calls[0].from; + expect(Array.isArray(fromArg)).toBe(true); + expect((fromArg as number[]).length).toBe(2); + }); + + it("returns null when all sources are invalid", () => { + const mapData = createIslandMap(); + const map = createGameMap(mapData); + const inner = createMockPathFinder(); + const transformer = new ShoreCoercingTransformer(inner, map); + + const land = map.ref(2, 2); + + const result = transformer.findPath([land], map.ref(0, 0)); + + expect(result).toBeNull(); + expect(inner.calls).toHaveLength(0); + }); + }); + + describe("determinism", () => { + it("shore with multiple water neighbors selects consistently", () => { + // prettier-ignore + const map = createGameMap({ + width: 5, height: 5, grid: [ + L, L, W, W, W, + L, L, W, W, W, + L, L, W, L, L, + W, W, W, L, L, + W, W, W, L, L, + ], + }); + + const shoreWithMultipleWater = map.ref(1, 2); + const expectedWaterNeighbor = map.ref(1, 3); + + const inner1 = createMockPathFinder(); + const inner2 = createMockPathFinder(); + const transformer1 = new ShoreCoercingTransformer(inner1, map); + const transformer2 = new ShoreCoercingTransformer(inner2, map); + + const waterDest = map.ref(2, 4); + + transformer1.findPath(shoreWithMultipleWater, waterDest); + transformer2.findPath(shoreWithMultipleWater, waterDest); + + // Both select the same water neighbor: (1,3) + expect(inner1.calls[0].from).toBe(expectedWaterNeighbor); + expect(inner2.calls[0].from).toBe(expectedWaterNeighbor); + }); + + it("corner shore with water neighbors works correctly", () => { + const mapData = createIslandMap(); + const map = createGameMap(mapData); + const inner = createMockPathFinder(); + const transformer = new ShoreCoercingTransformer(inner, map); + + const cornerShore = map.ref(1, 1); + const waterNeighbor = map.ref(1, 0); + const waterDest = map.ref(4, 4); + + inner.returnPath = [waterNeighbor, waterDest]; + + const result = transformer.findPath(cornerShore, waterDest); + + expect(result).not.toBeNull(); + expect(result).toEqual([cornerShore, waterNeighbor, waterDest]); + }); + }); +}); diff --git a/tests/pathfinding/benchmark/compare.ts b/tests/pathfinding/benchmark/compare.ts new file mode 100644 index 000000000..e39adb49d --- /dev/null +++ b/tests/pathfinding/benchmark/compare.ts @@ -0,0 +1,180 @@ +#!/usr/bin/env node + +/** + * Compare pathfinding adapters side-by-side + * + * Usage: + * npx tsx tests/pathfinding/benchmark/compare.ts + * npx tsx tests/pathfinding/benchmark/compare.ts --synthetic + * + * Examples: + * npx tsx tests/pathfinding/benchmark/compare.ts default hpa,a.baseline + * npx tsx tests/pathfinding/benchmark/compare.ts --synthetic giantworldmap hpa,hpa.cached,a.full + */ + +import { + type BenchmarkResult, + calculateStats, + getAdapter, + getScenario, + measureExecutionTime, + measurePathLength, +} from "../utils"; + +interface AdapterResults { + adapter: string; + initTime: number; + totalTime: number; + totalDistance: number; + successfulRoutes: number; + totalRoutes: number; +} + +const DEFAULT_ITERATIONS = 1; + +async function runBenchmark( + scenarioName: string, + adapterName: string, +): Promise { + const { game, routes, initTime } = await getScenario( + scenarioName, + adapterName, + ); + const adapter = getAdapter(game, adapterName); + + const results: BenchmarkResult[] = []; + + // Measure path lengths + for (const route of routes) { + const pathLength = measurePathLength(adapter, route); + results.push({ route: route.name, pathLength, executionTime: null }); + } + + // Measure execution times + for (const route of routes) { + const result = results.find((r) => r.route === route.name); + if (result && result.pathLength !== null) { + const execTime = measureExecutionTime(adapter, route, DEFAULT_ITERATIONS); + result.executionTime = execTime; + } + } + + const stats = calculateStats(results); + + return { + adapter: adapterName, + initTime, + totalTime: stats.totalTime, + totalDistance: stats.totalDistance, + successfulRoutes: stats.successfulRoutes, + totalRoutes: stats.totalRoutes, + }; +} + +const TABLE_HEADERS = [ + "Adapter", + "Init (ms)", + "Path (ms)", + "Distance", + "Routes", +]; + +const TABLE_WIDTHS = [20, 12, 12, 12, 10]; + +function printTableHeader(scenarioName: string) { + console.log(`\nResults: ${scenarioName}`); + console.log("=".repeat(70)); + console.log(TABLE_HEADERS.map((h, i) => h.padEnd(TABLE_WIDTHS[i])).join(" ")); + console.log("-".repeat(70)); +} + +function printTableRow(r: AdapterResults) { + const row = [ + r.adapter, + r.initTime.toFixed(2), + r.totalTime.toFixed(2), + r.totalDistance.toString(), + `${r.successfulRoutes}/${r.totalRoutes}`, + ]; + console.log(row.map((c, i) => c.padEnd(TABLE_WIDTHS[i])).join(" ")); +} + +function printTableFooter() { + console.log("-".repeat(70)); +} + +function printUsage() { + console.log(` +Usage: + npx tsx tests/pathfinding/benchmark/compare.ts + npx tsx tests/pathfinding/benchmark/compare.ts --synthetic + +Arguments: + Name of the scenario (default: "default") + Comma-separated list of adapters to compare (e.g., "hpa,a.baseline") + +Examples: + npx tsx tests/pathfinding/benchmark/compare.ts default hpa,a.baseline + npx tsx tests/pathfinding/benchmark/compare.ts --synthetic giantworldmap hpa,hpa.cached,a.full + +Available adapters: + a.baseline - A* on minimap (inlined) + a.generic - A* on minimap (adapter) + a.full - A* on full map + hpa - Hierarchical pathfinding (no cache) + hpa.cached - Hierarchical pathfinding (with cache) +`); +} + +async function main() { + const args = process.argv.slice(2); + + if (args.includes("--help") || args.includes("-h")) { + printUsage(); + process.exit(0); + } + + const isSynthetic = args.includes("--synthetic"); + const nonFlagArgs = args.filter((arg) => !arg.startsWith("--")); + + if (nonFlagArgs.length < 2) { + console.error("Error: requires and arguments"); + printUsage(); + process.exit(1); + } + + const scenarioArg = nonFlagArgs[0]; + const adaptersArg = nonFlagArgs[1]; + const adapters = adaptersArg.split(",").map((a) => a.trim()); + + if (adapters.length < 1) { + console.error("Error: at least one adapter required"); + process.exit(1); + } + + const scenarioName = isSynthetic ? `synthetic/${scenarioArg}` : scenarioArg; + + console.log( + `Comparing ${adapters.length} adapters on scenario: ${scenarioName}`, + ); + console.log(`Adapters: ${adapters.join(", ")}`); + console.log(""); + + printTableHeader(scenarioName); + + for (const adapter of adapters) { + try { + const result = await runBenchmark(scenarioName, adapter); + printTableRow(result); + } catch (error) { + console.log(`${adapter.padEnd(TABLE_WIDTHS[0])} FAILED: ${error}`); + } + } + + printTableFooter(); +} + +main().catch((error) => { + console.error("Fatal error:", error); + process.exit(1); +}); diff --git a/tests/pathfinding/playground/api/maps.ts b/tests/pathfinding/playground/api/maps.ts index 7d1776931..4bafc6fed 100644 --- a/tests/pathfinding/playground/api/maps.ts +++ b/tests/pathfinding/playground/api/maps.ts @@ -2,10 +2,13 @@ import { readdirSync, readFileSync } from "fs"; import { dirname, join } from "path"; import { fileURLToPath } from "url"; import { Game } from "../../../../src/core/game/Game.js"; -import { TileRef } from "../../../../src/core/game/GameMap.js"; -import { NavMesh } from "../../../../src/core/pathfinding/navmesh/NavMesh.js"; +import { AStarWaterHierarchical } from "../../../../src/core/pathfinding/algorithms/AStar.WaterHierarchical.js"; import { setupFromPath } from "../../utils.js"; +// Available comparison adapters +// Note: "hpa" runs same algorithm without debug overhead for fair timing comparison +export const COMPARISON_ADAPTERS = ["hpa", "a.baseline", "a.generic", "a.full"]; + export interface MapInfo { name: string; displayName: string; @@ -13,7 +16,7 @@ export interface MapInfo { export interface MapCache { game: Game; - navMesh: NavMesh; + hpaStar: AStarWaterHierarchical; } const cache = new Map(); @@ -114,13 +117,20 @@ export async function loadMap(mapName: string): Promise { const mapsDir = getMapsDirectory(); // Use the existing setupFromPath utility to load the map - const game = await setupFromPath(mapsDir, mapName); + const game = await setupFromPath(mapsDir, mapName, { disableNavMesh: false }); + + // Get pre-built graph from game + const graph = game.miniWaterGraph(); + if (!graph) { + throw new Error(`No water graph available for map: ${mapName}`); + } - // Initialize NavMesh - const navMesh = new NavMesh(game, { cachePaths: config.cachePaths }); - navMesh.initialize(); + // Initialize AStarWaterHierarchical with minimap and graph + const hpaStar = new AStarWaterHierarchical(game.miniMap(), graph, { + cachePaths: config.cachePaths, + }); - const cacheEntry: MapCache = { game, navMesh }; + const cacheEntry: MapCache = { game, hpaStar }; // Store in cache cache.set(mapName, cacheEntry); @@ -132,7 +142,7 @@ export async function loadMap(mapName: string): Promise { * Get map metadata for client */ export async function getMapMetadata(mapName: string) { - const { game, navMesh } = await loadMap(mapName); + const { game, hpaStar } = await loadMap(mapName); // Extract map data const mapData: number[] = []; @@ -143,65 +153,48 @@ export async function getMapMetadata(mapName: string) { } } - // Extract static graph data from NavMesh + // Extract static graph data from GameMapHPAStar + // Access internal graph via type casting (test code only) + const graph = (hpaStar as any).graph; const miniMap = game.miniMap(); - const navMeshGraph = (navMesh as any).graph; - - // Convert gateways from Map to array - const gatewaysArray = Array.from(navMeshGraph.gateways.values()); - const allGateways = gatewaysArray.map((gw: any) => ({ - id: gw.id, - x: miniMap.x(gw.tile), - y: miniMap.y(gw.tile), - })); - // Create a lookup map from gateway ID to gateway for edge conversion - const gatewayById = new Map(gatewaysArray.map((gw: any) => [gw.id, gw])); - - // Convert edges from Map to flat array - // The edges Map has gateway IDs as keys, and arrays of edges as values - const allEdges: any[] = []; - for (const edgeArray of navMeshGraph.edges.values()) { - allEdges.push(...edgeArray); - } + // Convert nodes to client format + const allNodes = graph.getAllNodes().map((node: any) => ({ + id: node.id, + x: miniMap.x(node.tile), + y: miniMap.y(node.tile), + })); - // Deduplicate edges (they're bidirectional, so each edge appears twice) - const seenEdges = new Set(); - const edges = allEdges - .filter((edge: any) => { - const edgeKey = - edge.from < edge.to - ? `${edge.from}-${edge.to}` - : `${edge.to}-${edge.from}`; - if (seenEdges.has(edgeKey)) return false; - seenEdges.add(edgeKey); - return true; - }) - .map((edge: any) => { - const fromGateway = gatewayById.get(edge.from); - const toGateway = gatewayById.get(edge.to); - - return { - fromId: edge.from, - toId: edge.to, - from: fromGateway - ? [miniMap.x(fromGateway.tile) * 2, miniMap.y(fromGateway.tile) * 2] - : [0, 0], - to: toGateway - ? [miniMap.x(toGateway.tile) * 2, miniMap.y(toGateway.tile) * 2] - : [0, 0], - cost: edge.cost, - path: edge.path - ? edge.path.map((tile: TileRef) => [game.x(tile), game.y(tile)]) - : null, - }; + // Convert edges to client format + const edges: Array<{ + fromId: number; + toId: number; + from: number[]; + to: number[]; + cost: number; + }> = []; + for (let i = 0; i < graph.edgeCount; i++) { + const edge = graph.getEdge(i); + if (!edge) continue; + + const nodeA = graph.getNode(edge.nodeA); + const nodeB = graph.getNode(edge.nodeB); + if (!nodeA || !nodeB) continue; + + edges.push({ + fromId: edge.nodeA, + toId: edge.nodeB, + from: [miniMap.x(nodeA.tile) * 2, miniMap.y(nodeA.tile) * 2], + to: [miniMap.x(nodeB.tile) * 2, miniMap.y(nodeB.tile) * 2], + cost: edge.cost, }); + } console.log( - `Map ${mapName}: ${allGateways.length} gateways, ${edges.length} edges`, + `Map ${mapName}: ${allNodes.length} nodes, ${edges.length} edges`, ); - const sectorSize = navMeshGraph.sectorSize; + const clusterSize = graph.clusterSize; return { name: mapName, @@ -209,10 +202,11 @@ export async function getMapMetadata(mapName: string) { height: game.height(), mapData, graphDebug: { - allGateways, + allNodes, edges, - sectorSize, + clusterSize, }, + adapters: COMPARISON_ADAPTERS, }; } diff --git a/tests/pathfinding/playground/api/pathfinding.ts b/tests/pathfinding/playground/api/pathfinding.ts index 102e83310..9cc69aa53 100644 --- a/tests/pathfinding/playground/api/pathfinding.ts +++ b/tests/pathfinding/playground/api/pathfinding.ts @@ -1,39 +1,64 @@ import { TileRef } from "../../../../src/core/game/GameMap.js"; -import { MiniAStarAdapter } from "../../../../src/core/pathfinding/adapters/MiniAStarAdapter.js"; -import { loadMap } from "./maps.js"; - -interface PathfindingOptions { - includePfMini?: boolean; - includeNavMesh?: boolean; -} - -interface NavMeshResult { +import { AStarWaterHierarchical } from "../../../../src/core/pathfinding/algorithms/AStar.WaterHierarchical.js"; +import { BresenhamSmoothingTransformer } from "../../../../src/core/pathfinding/smoothing/BresenhamPathSmoother.js"; +import { ComponentCheckTransformer } from "../../../../src/core/pathfinding/transformers/ComponentCheckTransformer.js"; +import { MiniMapTransformer } from "../../../../src/core/pathfinding/transformers/MiniMapTransformer.js"; +import { ShoreCoercingTransformer } from "../../../../src/core/pathfinding/transformers/ShoreCoercingTransformer.js"; +import { + PathFinder, + SteppingPathFinder, +} from "../../../../src/core/pathfinding/types.js"; +import { getAdapter } from "../../utils.js"; +import { COMPARISON_ADAPTERS, loadMap } from "./maps.js"; + +// Primary result with debug info +interface PrimaryResult { path: Array<[number, number]> | null; - initialPath: Array<[number, number]> | null; - gateways: Array<[number, number]> | null; - timings: any; length: number; time: number; + debug: { + nodePath: Array<[number, number]> | null; + initialPath: Array<[number, number]> | null; + timings: Record; + }; } -interface PfMiniResult { +// Comparison result (path + timing only) +interface ComparisonResult { + adapter: string; path: Array<[number, number]> | null; length: number; time: number; } -// Cache pathfinding adapters per map -const pfMiniCache = new Map(); +export interface PathfindResult { + primary: PrimaryResult; + comparisons: ComparisonResult[]; +} + +// Cache adapters per map +const adapterCache = new Map< + string, + Map> +>(); /** - * Get or create MiniAStar adapter for a map + * Get or create an adapter for a map */ -function getPfMiniAdapter(mapName: string, game: any): MiniAStarAdapter { - if (!pfMiniCache.has(mapName)) { - const adapter = new MiniAStarAdapter(game, { waterPath: true }); - pfMiniCache.set(mapName, adapter); +function getOrCreateAdapter( + mapName: string, + adapterName: string, + game: any, +): SteppingPathFinder { + if (!adapterCache.has(mapName)) { + adapterCache.set(mapName, new Map()); } - return pfMiniCache.get(mapName)!; + const mapAdapters = adapterCache.get(mapName)!; + + if (!mapAdapters.has(adapterName)) { + mapAdapters.set(adapterName, getAdapter(game, adapterName)); + } + return mapAdapters.get(adapterName)!; } /** @@ -48,78 +73,124 @@ function pathToCoords( } /** - * Compute pathfinding between two points + * Build the full transformer chain like PathFinding.Water() does */ -export async function computePath( - mapName: string, - from: [number, number], - to: [number, number], - options: PathfindingOptions = {}, -): Promise { - const { game, navMesh: navMeshAdapter } = await loadMap(mapName); +function buildWrappedPathFinder( + hpaStar: AStarWaterHierarchical, + game: any, + graph: any, +): PathFinder { + const miniMap = game.miniMap(); + const componentCheckFn = (t: TileRef) => graph.getComponentId(t); + + // Chain: hpaStar -> ComponentCheck -> Bresenham -> ShoreCoercing -> MiniMap + const withComponentCheck = new ComponentCheckTransformer( + hpaStar, + componentCheckFn, + ); + const withSmoothing = new BresenhamSmoothingTransformer( + withComponentCheck, + miniMap, + ); + const withShoreCoercing = new ShoreCoercingTransformer( + withSmoothing, + miniMap, + ); + const withMiniMap = new MiniMapTransformer(withShoreCoercing, game, miniMap); + + return withMiniMap; +} - // Convert coordinates to TileRefs - const fromRef = game.ref(from[0], from[1]); - const toRef = game.ref(to[0], to[1]); +/** + * Compute primary path using AStarWaterHierarchical with debug info + * Uses the same transformer chain as PathFinding.Water() + */ +function computePrimaryPath( + hpaStar: AStarWaterHierarchical, + game: any, + graph: any, + fromRef: TileRef, + toRef: TileRef, +): PrimaryResult { + const miniMap = game.miniMap(); - // Validate that both points are water tiles - if (!game.isWater(fromRef)) { - throw new Error(`Start point (${from[0]}, ${from[1]}) is not water`); - } - if (!game.isWater(toRef)) { - throw new Error(`End point (${to[0]}, ${to[1]}) is not water`); - } + // Build wrapped pathfinder with all transformers + const wrappedPf = buildWrappedPathFinder(hpaStar, game, graph); - // Compute NavMesh path - const navMeshPath = navMeshAdapter.findPath(fromRef, toRef, true); - const path = pathToCoords(navMeshPath, game); + // Enable debug mode to capture internal state + hpaStar.debugMode = true; - const miniMap = game.miniMap(); + const start = performance.now(); + const path = wrappedPf.findPath(fromRef, toRef); + const time = performance.now() - start; - // Extract debug info - let gateways: Array<[number, number]> | null = null; - let initialPath: Array<[number, number]> | null = null; - let timings: any = {}; - - if (navMeshAdapter.debugInfo) { - // Convert gatewayPath (TileRefs on miniMap) to full map coordinates - if (navMeshAdapter.debugInfo.gatewayPath) { - gateways = navMeshAdapter.debugInfo.gatewayPath.map((tile: TileRef) => { - const x = miniMap.x(tile) * 2; - const y = miniMap.y(tile) * 2; - return [x, y] as [number, number]; - }); - } + const debugInfo = hpaStar.debugInfo; - // Convert initial path - if (navMeshAdapter.debugInfo.initialPath) { - initialPath = navMeshAdapter.debugInfo.initialPath.map( - (tile: TileRef) => [game.x(tile), game.y(tile)] as [number, number], - ); - } + // Convert node path (miniMap coords) to full map coords + let nodePath: Array<[number, number]> | null = null; + if (debugInfo?.nodePath) { + nodePath = debugInfo.nodePath.map((tile: TileRef) => { + const x = miniMap.x(tile) * 2; + const y = miniMap.y(tile) * 2; + return [x, y] as [number, number]; + }); + } - timings = navMeshAdapter.debugInfo.timings || {}; + // Convert initialPath (miniMap TileRefs) to full map coords + let initialPath: Array<[number, number]> | null = null; + if (debugInfo?.initialPath) { + initialPath = debugInfo.initialPath.map((tile: TileRef) => { + const x = miniMap.x(tile) * 2; + const y = miniMap.y(tile) * 2; + return [x, y] as [number, number]; + }); } return { - path, - initialPath, - gateways, - timings, + path: pathToCoords(path, game), + length: path ? path.length : 0, + time, + debug: { + nodePath, + initialPath, + timings: debugInfo?.timings ?? {}, + }, + }; +} + +/** + * Compute comparison path using adapter + */ +function computeComparisonPath( + adapter: SteppingPathFinder, + game: any, + fromRef: TileRef, + toRef: TileRef, + adapterName: string, +): ComparisonResult { + const start = performance.now(); + const path = adapter.findPath(fromRef, toRef); + const time = performance.now() - start; + + return { + adapter: adapterName, + path: pathToCoords(path, game), length: path ? path.length : 0, - time: timings.total ?? 0, + time, }; } /** - * Compute only PathFinder.Mini path + * Compute pathfinding between two points */ -export async function computePfMiniPath( +export async function computePath( mapName: string, from: [number, number], to: [number, number], -): Promise { - const { game } = await loadMap(mapName); + options: { adapters?: string[] } = {}, +): Promise { + const { game, hpaStar } = await loadMap(mapName); + const graph = game.miniWaterGraph(); // Convert coordinates to TileRefs const fromRef = game.ref(from[0], from[1]); @@ -133,25 +204,46 @@ export async function computePfMiniPath( throw new Error(`End point (${to[0]}, ${to[1]}) is not water`); } - // Compute PathFinder.Mini path - const pfMiniAdapter = getPfMiniAdapter(mapName, game); - const pfMiniStart = performance.now(); - const pfMiniPath = pfMiniAdapter.findPath(fromRef, toRef); - const pfMiniEnd = performance.now(); + // Compute primary path (HPA* with debug) + const primary = computePrimaryPath(hpaStar, game, graph, fromRef, toRef); - const path = pathToCoords(pfMiniPath, game); - const time = pfMiniEnd - pfMiniStart; + // Compute comparison paths + const selectedAdapters = options.adapters ?? COMPARISON_ADAPTERS; + const comparisons: ComparisonResult[] = []; - return { - path, - length: path ? path.length : 0, - time, - }; + for (const adapterName of selectedAdapters) { + if (!COMPARISON_ADAPTERS.includes(adapterName)) { + console.warn(`Unknown adapter: ${adapterName}, skipping`); + continue; + } + + try { + const adapter = getOrCreateAdapter(mapName, adapterName, game); + const result = computeComparisonPath( + adapter, + game, + fromRef, + toRef, + adapterName, + ); + comparisons.push(result); + } catch (error) { + console.error(`Error with adapter ${adapterName}:`, error); + comparisons.push({ + adapter: adapterName, + path: null, + length: 0, + time: 0, + }); + } + } + + return { primary, comparisons }; } /** * Clear pathfinding adapter caches */ export function clearAdapterCaches() { - pfMiniCache.clear(); + adapterCache.clear(); } diff --git a/tests/pathfinding/playground/public/client.js b/tests/pathfinding/playground/public/client.js index 48a222786..8c9d68d8e 100644 --- a/tests/pathfinding/playground/public/client.js +++ b/tests/pathfinding/playground/public/client.js @@ -6,19 +6,26 @@ const state = { mapHeight: 0, startPoint: null, endPoint: null, - navMeshPath: null, - navMeshResult: null, // Store full NavMesh result including timing - pfMiniPath: null, - pfMiniResult: null, // Store full PF.Mini result including timing - graphDebug: null, // Static graph data (gateways, edges, sectorSize) - loaded once per map - debugInfo: null, // Per-path debug data (timings, gatewayWaypoints, initialPath) + hpaPath: null, + hpaResult: null, // Store full HPA* result including timing + comparisons: [], // Array of comparison results + visibleComparisons: new Set(), // Which comparison paths are visible + adapters: [], // Available comparison adapters (loaded from backend) + graphDebug: null, // Static graph data (allNodes, edges, clusterSize) - loaded once per map + debugInfo: null, // Per-path debug data (timings, nodePath, initialPath) isMapLoading: false, // Loading state for map switching - isNavMeshLoading: false, // Separate loading state for NavMesh - isPfMiniLoading: false, // Separate loading state for PF.Mini - showPfMini: false, + isHpaLoading: false, // Separate loading state for HPA* activeRefreshButton: null, // Track which refresh button is spinning }; +// Colors for comparison paths +const COMPARISON_COLORS = { + hpa: "#ff8800", // orange + "a.baseline": "#ff00ff", // magenta + "a.generic": "#88ff00", // lime + "a.full": "#ffff00", // yellow +}; + // Canvas state let zoomLevel = 1.0; let panX = 0; @@ -32,7 +39,7 @@ let dragStartPanY = 0; let mapCanvas, overlayCanvas, interactiveCanvas; let mapCtx, overlayCtx, interactiveCtx; let mapRendered = false; -let hoveredGateway = null; +let hoveredNode = null; let hoveredPoint = null; // 'start', 'end', or null let draggingPoint = null; // 'start', 'end', or null let draggingPointPosition = null; // [x, y] canvas position while dragging @@ -147,21 +154,8 @@ function initializeControls() { } }); - // PF.Mini request button - document.getElementById("requestPfMini").addEventListener("click", () => { - if ( - state.startPoint && - state.endPoint && - !state.pfMiniPath && - !state.isPfMiniLoading - ) { - state.showPfMini = true; - requestPfMiniOnly(state.startPoint, state.endPoint); - } - }); - - // Refresh NavMesh button - document.getElementById("refreshNavMesh").addEventListener("click", (e) => { + // Refresh HPA* button + document.getElementById("refreshHpa").addEventListener("click", (e) => { if (state.startPoint && state.endPoint) { const btn = e.currentTarget; btn.classList.add("spinning"); @@ -170,22 +164,12 @@ function initializeControls() { } }); - // Refresh PF.Mini button - document.getElementById("refreshPfMini").addEventListener("click", (e) => { - if (state.startPoint && state.endPoint && state.pfMiniPath) { - const btn = e.currentTarget; - btn.classList.add("spinning"); - state.activeRefreshButton = btn; - requestPfMiniOnly(state.startPoint, state.endPoint); - } - }); - // Visualization toggles - all buttons [ "showInitialPath", - "showUsedGateways", + "showUsedNodes", "showColoredMap", - "showGateways", + "showNodes", "showSectorGrid", "showEdges", ].forEach((id) => { @@ -197,11 +181,11 @@ function initializeControls() { if (id === "showColoredMap") { renderMapBackground(2); } - // Static overlays (sectors, edges, all gateways) go on overlay canvas - if (["showGateways", "showSectorGrid", "showEdges"].includes(id)) { + // Static overlays (sectors, edges, all nodes) go on overlay canvas + if (["showNodes", "showSectorGrid", "showEdges"].includes(id)) { renderOverlay(2); } - // Dynamic elements (paths, highlighted gateways) go on interactive canvas + // Dynamic elements (paths, highlighted nodes) go on interactive canvas renderInteractive(); }); }); @@ -258,7 +242,8 @@ function schedulePathRecalc() { // Enough time has passed, request immediately lastPathRecalcTime = now; if (state.startPoint && state.endPoint) { - requestPathfinding(state.startPoint, state.endPoint); + // Skip comparisons during drag for snappy feel + requestPathfinding(state.startPoint, state.endPoint, true); } } // If not enough time has passed, skip this call (throttle) @@ -281,11 +266,6 @@ function initializeDragControls() { // Start dragging the point draggingPoint = pointAtMouse; wrapper.style.cursor = "move"; - - // Invalidate PF.Mini path since we're changing the route - state.pfMiniPath = null; - state.pfMiniResult = null; - updatePfMiniButton(); } else { // Start panning the map isDragging = true; @@ -355,57 +335,53 @@ function initializeDragControls() { wrapper.style.cursor = hoveredPoint ? "move" : "grab"; } - // Check for gateway hover (only if gateway visualization is enabled) - const showGateways = - document.getElementById("showGateways").dataset.active === "true"; - const showUsedGateways = - document.getElementById("showUsedGateways").dataset.active === "true"; + // Check for node hover (only if node visualization is enabled) + const showNodes = + document.getElementById("showNodes").dataset.active === "true"; + const showUsedNodes = + document.getElementById("showUsedNodes").dataset.active === "true"; if ( - (showGateways || showUsedGateways) && + (showNodes || showUsedNodes) && state.graphDebug && - state.graphDebug.allGateways + state.graphDebug.allNodes ) { - // Filter gateways based on what's visible - let gatewaysToCheck = state.graphDebug.allGateways; + // Filter nodes based on what's visible + let nodesToCheck = state.graphDebug.allNodes; if ( - showUsedGateways && - !showGateways && + showUsedNodes && + !showNodes && state.debugInfo && - state.debugInfo.gatewayWaypoints + state.debugInfo.nodePath ) { - // Only show tooltips for used gateways - // gatewayWaypoints are coordinates [x, y] matching the map format - const usedGatewayCoords = new Set( - state.debugInfo.gatewayWaypoints.map(([x, y]) => `${x},${y}`), + // Only show tooltips for used nodes + // nodePath are coordinates [x, y] matching the map format + const usedNodeCoords = new Set( + state.debugInfo.nodePath.map(([x, y]) => `${x},${y}`), ); - gatewaysToCheck = state.graphDebug.allGateways.filter((gw) => - usedGatewayCoords.has(`${gw.x * 2},${gw.y * 2}`), + nodesToCheck = state.graphDebug.allNodes.filter((node) => + usedNodeCoords.has(`${node.x * 2},${node.y * 2}`), ); } - const foundGateway = findGatewayAtPosition( - canvasX, - canvasY, - gatewaysToCheck, - ); + const foundNode = findNodeAtPosition(canvasX, canvasY, nodesToCheck); - if (foundGateway !== hoveredGateway) { - hoveredGateway = foundGateway; - if (hoveredGateway) { - showGatewayTooltip(hoveredGateway, e.clientX, e.clientY); + if (foundNode !== hoveredNode) { + hoveredNode = foundNode; + if (hoveredNode) { + showNodeTooltip(hoveredNode, e.clientX, e.clientY); } else { tooltip.classList.remove("visible"); } renderInteractive(); - } else if (hoveredGateway) { + } else if (hoveredNode) { tooltip.style.left = e.clientX + 15 + "px"; tooltip.style.top = e.clientY + 15 + "px"; } } else { - // No gateway visualization enabled, clear any existing tooltip - if (hoveredGateway) { - hoveredGateway = null; + // No node visualization enabled, clear any existing tooltip + if (hoveredNode) { + hoveredNode = null; tooltip.classList.remove("visible"); renderInteractive(); } @@ -451,8 +427,8 @@ function initializeDragControls() { tooltip.classList.remove("visible"); wrapper.style.cursor = "grab"; - const needsRender = hoveredGateway || hoveredPoint; - hoveredGateway = null; + const needsRender = hoveredNode || hoveredPoint; + hoveredNode = null; hoveredPoint = null; if (needsRender) { @@ -485,19 +461,12 @@ function initializeDragControls() { // Initialize timings panel to default state function initializeTimingsPanel() { // Set initial state to match "no path" state - updateTimingsPanel({ navMesh: null, pfMini: null }); - updatePfMiniButton(); + updateTimingsPanel({ primary: null, comparisons: [] }); } // Handle map clicks for point selection function handleMapClick(e) { - if ( - !state.currentMap || - state.isMapLoading || - state.isNavMeshLoading || - state.isPfMiniLoading - ) - return; + if (!state.currentMap || state.isMapLoading || state.isHpaLoading) return; const wrapper = document.getElementById("canvasWrapper"); const rect = wrapper.getBoundingClientRect(); @@ -555,15 +524,12 @@ function handleMapClick(e) { function clearPoints() { state.startPoint = null; state.endPoint = null; - state.navMeshPath = null; - state.navMeshResult = null; - state.pfMiniPath = null; - state.pfMiniResult = null; + state.hpaPath = null; + state.hpaResult = null; + state.comparisons = []; state.debugInfo = null; - state.showPfMini = false; updatePointDisplay(); hidePathInfo(); - updatePfMiniButton(); updateURLState(); // Remove points from URL renderInteractive(); } @@ -682,19 +648,17 @@ async function switchMap(mapName, restorePointsFromURL = false) { state.mapHeight = data.height; state.mapData = data.mapData; state.graphDebug = data.graphDebug; // Store static graph debug data + state.adapters = data.adapters || []; // Store available comparison adapters // Clear paths (but don't update URL yet if we're restoring from URL) state.startPoint = null; state.endPoint = null; - state.navMeshPath = null; - state.navMeshResult = null; - state.pfMiniPath = null; - state.pfMiniResult = null; + state.hpaPath = null; + state.hpaResult = null; + state.comparisons = []; state.debugInfo = null; - state.showPfMini = false; updatePointDisplay(); hidePathInfo(); - updatePfMiniButton(); // Size canvases mapCanvas.width = state.mapWidth * 2; @@ -779,20 +743,26 @@ function hideWelcomeScreen() { document.getElementById("welcomeScreen").classList.add("hidden"); } -// Request pathfinding computation (NavMesh only) -async function requestPathfinding(from, to) { +// Request pathfinding computation (HPA* primary + comparisons) +async function requestPathfinding(from, to, skipComparisons = false) { setStatus("Computing path...", true); - state.isNavMeshLoading = true; + state.isHpaLoading = true; try { + const body = { + map: state.currentMap, + from, + to, + }; + // Skip comparisons during drag for snappy feel + if (skipComparisons) { + body.adapters = []; + } + const response = await fetch("/api/pathfind", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - map: state.currentMap, - from, - to, - }), + body: JSON.stringify(body), }); if (!response.ok) { @@ -802,151 +772,70 @@ async function requestPathfinding(from, to) { const result = await response.json(); - // Update state - state.navMeshPath = result.path; - state.navMeshResult = result; // Store full result for later use - // Don't reset pfMiniPath - preserve it across NavMesh refreshes + // Update state with new API format + state.hpaPath = result.primary.path; + state.hpaResult = result.primary; + state.comparisons = result.comparisons; state.debugInfo = { - initialPath: result.initialPath, - gatewayWaypoints: result.gateways, - timings: result.timings, + initialPath: result.primary.debug.initialPath, + nodePath: result.primary.debug.nodePath, + timings: result.primary.debug.timings, }; - // Update UI - preserve existing PF.Mini if it exists - updatePathInfo({ navMesh: result, pfMini: state.pfMiniResult }); + // Update UI + updatePathInfo(result); renderInteractive(); setStatus("Path computed successfully"); } catch (error) { showError(`Pathfinding failed: ${error.message}`); } finally { - state.isNavMeshLoading = false; - // Stop refresh button spinning - if (state.activeRefreshButton) { - state.activeRefreshButton.classList.remove("spinning"); - state.activeRefreshButton = null; - } - } -} - -// Request PF.Mini computation only (without re-computing NavMesh) -async function requestPfMiniOnly(from, to) { - setStatus("Computing PF.Mini path...", true); - state.isPfMiniLoading = true; - updatePfMiniButton(); // Update button to show loading state - - try { - const response = await fetch("/api/pathfind-pfmini", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - map: state.currentMap, - from, - to, - }), - }); - - if (!response.ok) { - const error = await response.json(); - throw new Error(error.message || "Pathfinding failed"); - } - - const result = await response.json(); - - // Update only PF.Mini path (preserve existing NavMesh path and debug info) - state.pfMiniPath = result.path; - state.pfMiniResult = result; // Store full result - - // Update UI (preserve existing NavMesh result) - updatePathInfo({ navMesh: state.navMeshResult, pfMini: result }); - renderInteractive(); - - setStatus("PF.Mini path computed successfully"); - } catch (error) { - showError(`PF.Mini pathfinding failed: ${error.message}`); - } finally { - state.isPfMiniLoading = false; + state.isHpaLoading = false; // Stop refresh button spinning if (state.activeRefreshButton) { state.activeRefreshButton.classList.remove("spinning"); state.activeRefreshButton = null; } - // Update button state - updatePfMiniButton(); } } // Update point display function updatePointDisplay() { - updatePfMiniButton(); -} - -// Update PF.Mini button state -function updatePfMiniButton() { - const button = document.getElementById("requestPfMini"); - const requestSection = document.getElementById("pfMiniRequestSection"); - - if (state.pfMiniPath) { - // Hide button when PF.Mini is already computed - requestSection.style.display = "none"; - } else if (state.isPfMiniLoading && !state.activeRefreshButton) { - // Show loading spinner when computing PF.Mini (not a refresh) - requestSection.style.display = "block"; - button.disabled = true; - button.innerHTML = 'Computing... '; - } else if (state.startPoint && state.endPoint && state.navMeshPath) { - // Show and enable button when points are set and NavMesh path exists - requestSection.style.display = "block"; - button.disabled = false; - button.textContent = "Request PathFinder.Mini"; - } else { - // Show but disable button when points aren't set - requestSection.style.display = "block"; - button.disabled = true; - button.textContent = "Request PathFinder.Mini"; - } + // No-op now, kept for compatibility } // Update path info in UI function updatePathInfo(result) { - // Update PF.Mini legend visibility - if (result.pfMini) { - document.getElementById("pfMiniLegend").style.display = "flex"; - } else { - document.getElementById("pfMiniLegend").style.display = "none"; - } - // Update timings panel updateTimingsPanel(result); - - // Update PF.Mini button - updatePfMiniButton(); } // Update the dedicated timings panel function updateTimingsPanel(result) { - const navMesh = result.navMesh; + const primary = result.primary; + const timings = primary && primary.debug ? primary.debug.timings : {}; - // Show NavMesh time and path length (or 0.00 in light gray if no data) - const navMeshTimeEl = document.getElementById("navMeshTime"); - if (navMesh && navMesh.time > 0) { - navMeshTimeEl.textContent = `${navMesh.time.toFixed(2)}ms`; - navMeshTimeEl.classList.remove("faded"); + // Use timings.total (excludes debug overhead) instead of raw time + const hpaTime = timings.total || 0; + + // Show HPA* time and path length (or 0.00 in light gray if no data) + const hpaTimeEl = document.getElementById("hpaTime"); + if (hpaTime > 0) { + hpaTimeEl.textContent = `${hpaTime.toFixed(2)}ms`; + hpaTimeEl.classList.remove("faded"); } else { - navMeshTimeEl.textContent = "0.00ms"; - navMeshTimeEl.classList.add("faded"); + hpaTimeEl.textContent = "0.00ms"; + hpaTimeEl.classList.add("faded"); } - const navMeshTilesEl = document.getElementById("navMeshTiles"); - if (navMesh && navMesh.length > 0) { - navMeshTilesEl.textContent = `- ${navMesh.length} tiles`; + const hpaTilesEl = document.getElementById("hpaTiles"); + if (primary && primary.length > 0) { + hpaTilesEl.textContent = `- ${primary.length} tiles`; } else { - navMeshTilesEl.textContent = ""; + hpaTilesEl.textContent = ""; } // Show timing breakdown - always visible with gray dashes when no data - const timings = navMesh && navMesh.timings ? navMesh.timings : {}; - // Early Exit const earlyExitEl = document.getElementById("timingEarlyExit"); const earlyExitValueEl = document.getElementById("timingEarlyExitValue"); @@ -959,30 +848,30 @@ function updateTimingsPanel(result) { earlyExitValueEl.style.color = "#666"; } - // Find Gateways - const findGatewaysEl = document.getElementById("timingFindGateways"); - const findGatewaysValueEl = document.getElementById( - "timingFindGatewaysValue", - ); - findGatewaysEl.style.display = "flex"; - if (timings.findGateways !== undefined) { - findGatewaysValueEl.textContent = `${timings.findGateways.toFixed(2)}ms`; - findGatewaysValueEl.style.color = "#f5f5f5"; + // Find Nodes + const findNodesEl = document.getElementById("timingFindNodes"); + const findNodesValueEl = document.getElementById("timingFindNodesValue"); + findNodesEl.style.display = "flex"; + if (timings.findNodes !== undefined) { + findNodesValueEl.textContent = `${timings.findNodes.toFixed(2)}ms`; + findNodesValueEl.style.color = "#f5f5f5"; } else { - findGatewaysValueEl.textContent = "—"; - findGatewaysValueEl.style.color = "#666"; + findNodesValueEl.textContent = "—"; + findNodesValueEl.style.color = "#666"; } - // Gateway Path - const gatewayPathEl = document.getElementById("timingGatewayPath"); - const gatewayPathValueEl = document.getElementById("timingGatewayPathValue"); - gatewayPathEl.style.display = "flex"; - if (timings.findGatewayPath !== undefined) { - gatewayPathValueEl.textContent = `${timings.findGatewayPath.toFixed(2)}ms`; - gatewayPathValueEl.style.color = "#f5f5f5"; + // Abstract Path + const abstractPathEl = document.getElementById("timingAbstractPath"); + const abstractPathValueEl = document.getElementById( + "timingAbstractPathValue", + ); + abstractPathEl.style.display = "flex"; + if (timings.findAbstractPath !== undefined) { + abstractPathValueEl.textContent = `${timings.findAbstractPath.toFixed(2)}ms`; + abstractPathValueEl.style.color = "#f5f5f5"; } else { - gatewayPathValueEl.textContent = "—"; - gatewayPathValueEl.style.color = "#666"; + abstractPathValueEl.textContent = "—"; + abstractPathValueEl.style.color = "#666"; } // Initial Path @@ -997,55 +886,90 @@ function updateTimingsPanel(result) { initialPathValueEl.style.color = "#666"; } - // Smooth Path - const smoothPathEl = document.getElementById("timingSmoothPath"); - const smoothPathValueEl = document.getElementById("timingSmoothPathValue"); - smoothPathEl.style.display = "flex"; - if (timings.buildSmoothPath !== undefined) { - smoothPathValueEl.textContent = `${timings.buildSmoothPath.toFixed(2)}ms`; - smoothPathValueEl.style.color = "#f5f5f5"; - } else { - smoothPathValueEl.textContent = "—"; - smoothPathValueEl.style.color = "#666"; + // Show comparisons section + const comparisonsSection = document.getElementById("comparisonsSection"); + const comparisonsContainer = document.getElementById("comparisonsContainer"); + + // Only show comparisons section if we have adapters loaded + if (!state.adapters || state.adapters.length === 0) { + comparisonsSection.style.display = "none"; + return; } + comparisonsSection.style.display = "block"; - // Show PF.Mini time and speedup if available - if (result.pfMini && result.pfMini.time > 0) { - const pfMiniTimeEl = document.getElementById("pfMiniTime"); - pfMiniTimeEl.textContent = `${result.pfMini.time.toFixed(2)}ms`; - pfMiniTimeEl.classList.remove("faded"); - - document.getElementById("pfMiniTiles").textContent = - `- ${result.pfMini.length} tiles`; - document.getElementById("pfMiniTimingSection").style.display = "block"; - - // Calculate and show speedup - if (navMesh && navMesh.time > 0) { - const speedup = result.pfMini.time / navMesh.time; - document.getElementById("speedupValue").textContent = - `${speedup.toFixed(1)}x`; - document.getElementById("speedupSection").style.display = "block"; - } else { - document.getElementById("speedupSection").style.display = "none"; + // Build lookup map for comparison data + const compMap = {}; + if (result.comparisons) { + for (const comp of result.comparisons) { + compMap[comp.adapter] = comp; } - } else if (result.pfMini) { - // PF.Mini exists but time is 0 - const pfMiniTimeEl = document.getElementById("pfMiniTime"); - pfMiniTimeEl.textContent = "—"; - pfMiniTimeEl.classList.add("faded"); - document.getElementById("pfMiniTiles").textContent = ""; - document.getElementById("pfMiniTimingSection").style.display = "block"; - document.getElementById("speedupSection").style.display = "none"; + } + + // Find fastest time overall (including HPA*) when we have data + const compTimes = result.comparisons + ? result.comparisons.map((c) => c.time).filter((t) => t > 0) + : []; + const fastestCompTime = + compTimes.length > 0 ? Math.min(...compTimes) : Infinity; + + // Update HPA* time color - green if fastest, red if slower than any comparison + const hpaIsFastest = hpaTime > 0 && hpaTime <= fastestCompTime; + const hpaSlower = hpaTime > 0 && fastestCompTime < hpaTime; + const fastestTime = Math.min(hpaTime || Infinity, fastestCompTime); + + if (hpaIsFastest) { + hpaTimeEl.style.color = "#00ff88"; + } else if (hpaSlower) { + hpaTimeEl.style.color = "#ff6666"; } else { - document.getElementById("pfMiniTimingSection").style.display = "none"; - document.getElementById("speedupSection").style.display = "none"; + hpaTimeEl.style.color = "#f5f5f5"; + } + + // Build comparison rows for all known adapters + let html = ""; + for (const adapter of state.adapters) { + const comp = compMap[adapter]; + const pathColor = COMPARISON_COLORS[adapter] || "#ffffff"; + const isActive = state.visibleComparisons.has(adapter); + + // Show actual values or placeholders + const hasData = comp && comp.time > 0; + const isFastest = hasData && comp.time === fastestTime; + const timeColor = isFastest ? "#00ff88" : hasData ? "#f5f5f5" : "#666"; + const tilesText = hasData ? comp.length : "—"; + const timeText = hasData ? `${comp.time.toFixed(2)}ms` : "—"; + + html += ` +
+ + ${adapter} + ${tilesText} + ${timeText} +
+ `; } + comparisonsContainer.innerHTML = html; + + // Add click handlers to toggle path visibility + comparisonsContainer.querySelectorAll(".comparison-row").forEach((row) => { + row.addEventListener("click", () => { + const adapter = row.dataset.adapter; + if (state.visibleComparisons.has(adapter)) { + state.visibleComparisons.delete(adapter); + row.classList.remove("active"); + } else { + state.visibleComparisons.add(adapter); + row.classList.add("active"); + } + renderInteractive(); + }); + }); } // Reset path info to show dashes function hidePathInfo() { // Don't hide the panel, just reset to show dashes - updateTimingsPanel({ navMesh: null, pfMini: null }); + updateTimingsPanel({ primary: null, comparisons: [] }); } // Set status message @@ -1132,7 +1056,7 @@ function renderMapBackground(scale) { mapCtx.putImageData(imageData, 0, 0); } -// Render static debug overlays (sectors, edges, all gateways) at map scale +// Render static debug overlays (clusters, edges, all nodes) at map scale function renderOverlay(scale) { overlayCtx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height); @@ -1142,19 +1066,19 @@ function renderOverlay(scale) { document.getElementById("showSectorGrid").dataset.active === "true"; const showEdges = document.getElementById("showEdges").dataset.active === "true"; - const showGateways = - document.getElementById("showGateways").dataset.active === "true"; + const showNodes = + document.getElementById("showNodes").dataset.active === "true"; - // Draw sector grid (sectorSize is in mini map coords, scale 2x for real map) - if (showSectorGrid && state.graphDebug.sectorSize) { - const sectorSize = state.graphDebug.sectorSize * 2; + // Draw cluster grid (clusterSize is in mini map coords, scale 2x for real map) + if (showSectorGrid && state.graphDebug.clusterSize) { + const clusterSize = state.graphDebug.clusterSize * 2; overlayCtx.strokeStyle = "#777777"; overlayCtx.lineWidth = scale * 0.5; overlayCtx.globalAlpha = 0.7; overlayCtx.setLineDash([5 * scale, 5 * scale]); // Vertical lines - for (let x = 0; x <= state.mapWidth; x += sectorSize) { + for (let x = 0; x <= state.mapWidth; x += clusterSize) { overlayCtx.beginPath(); overlayCtx.moveTo(x * scale, 0); overlayCtx.lineTo(x * scale, state.mapHeight * scale); @@ -1162,7 +1086,7 @@ function renderOverlay(scale) { } // Horizontal lines - for (let y = 0; y <= state.mapHeight; y += sectorSize) { + for (let y = 0; y <= state.mapHeight; y += clusterSize) { overlayCtx.beginPath(); overlayCtx.moveTo(0, y * scale); overlayCtx.lineTo(state.mapWidth * scale, y * scale); @@ -1192,17 +1116,17 @@ function renderOverlay(scale) { overlayCtx.globalAlpha = 1.0; } - // Draw all gateways - if (showGateways && state.graphDebug.allGateways) { + // Draw all nodes + if (showNodes && state.graphDebug.allNodes) { overlayCtx.fillStyle = "#aaaaaa"; - const gatewayRadius = scale * 1.5; + const nodeRadius = scale * 1.5; - for (const gw of state.graphDebug.allGateways) { + for (const node of state.graphDebug.allNodes) { overlayCtx.beginPath(); overlayCtx.arc( - (gw.x * 2 + 0.5) * scale, - (gw.y * 2 + 0.5) * scale, - gatewayRadius, + (node.x * 2 + 0.5) * scale, + (node.y * 2 + 0.5) * scale, + nodeRadius, 0, Math.PI * 2, ); @@ -1234,24 +1158,19 @@ function renderInteractive() { const markerSize = Math.max(4, 3 * zoomLevel); // Check what to show - const showUsedGateways = - document.getElementById("showUsedGateways").dataset.active === "true"; + const showUsedNodes = + document.getElementById("showUsedNodes").dataset.active === "true"; const showInitialPath = document.getElementById("showInitialPath").dataset.active === "true"; const showEdges = document.getElementById("showEdges").dataset.active === "true"; - const showGateways = - document.getElementById("showGateways").dataset.active === "true"; + const showNodes = + document.getElementById("showNodes").dataset.active === "true"; - // Draw highlighted edges for hovered gateway only - if ( - hoveredGateway && - showEdges && - state.graphDebug && - state.graphDebug.edges - ) { + // Draw highlighted edges for hovered node only + if (hoveredNode && showEdges && state.graphDebug && state.graphDebug.edges) { const connectedEdges = state.graphDebug.edges.filter( - (e) => e.fromId === hoveredGateway.id || e.toId === hoveredGateway.id, + (e) => e.fromId === hoveredNode.id || e.toId === hoveredNode.id, ); interactiveCtx.strokeStyle = "#00ffaa"; @@ -1270,31 +1189,30 @@ function renderInteractive() { interactiveCtx.globalAlpha = 1.0; } - // Draw highlighted gateways (hovered + connected) only + // Draw highlighted nodes (hovered + connected) only if ( - hoveredGateway && - showGateways && + hoveredNode && + showNodes && state.graphDebug && - state.graphDebug.allGateways + state.graphDebug.allNodes ) { - // Get connected gateways - let connectedGatewayIds = new Set(); + // Get connected nodes + let connectedNodeIds = new Set(); if (state.graphDebug.edges) { const connectedEdges = state.graphDebug.edges.filter( - (e) => e.fromId === hoveredGateway.id || e.toId === hoveredGateway.id, + (e) => e.fromId === hoveredNode.id || e.toId === hoveredNode.id, ); connectedEdges.forEach((edge) => { - if (edge.fromId !== hoveredGateway.id) - connectedGatewayIds.add(edge.fromId); - if (edge.toId !== hoveredGateway.id) connectedGatewayIds.add(edge.toId); + if (edge.fromId !== hoveredNode.id) connectedNodeIds.add(edge.fromId); + if (edge.toId !== hoveredNode.id) connectedNodeIds.add(edge.toId); }); } - // Draw connected gateways - for (const gwId of connectedGatewayIds) { - const gw = state.graphDebug.allGateways.find((g) => g.id === gwId); - if (gw) { - const screen = mapToScreen(gw.x * 2, gw.y * 2); + // Draw connected nodes + for (const nodeId of connectedNodeIds) { + const node = state.graphDebug.allNodes.find((n) => n.id === nodeId); + if (node) { + const screen = mapToScreen(node.x * 2, node.y * 2); interactiveCtx.fillStyle = "#00ff88"; interactiveCtx.strokeStyle = "#ffffff"; interactiveCtx.lineWidth = Math.max(1, zoomLevel * 0.3); @@ -1311,8 +1229,8 @@ function renderInteractive() { } } - // Draw hovered gateway on top - const screen = mapToScreen(hoveredGateway.x * 2, hoveredGateway.y * 2); + // Draw hovered node on top + const screen = mapToScreen(hoveredNode.x * 2, hoveredNode.y * 2); interactiveCtx.fillStyle = "#ffff00"; interactiveCtx.strokeStyle = "#ffffff"; interactiveCtx.lineWidth = Math.max(1, zoomLevel * 0.5); @@ -1353,36 +1271,43 @@ function renderInteractive() { interactiveCtx.stroke(); } - // Draw NavMesh path - if (state.navMeshPath && state.navMeshPath.length > 0) { - interactiveCtx.strokeStyle = "#00ffff"; - interactiveCtx.lineWidth = Math.max(1, zoomLevel); + // Draw comparison paths (before HPA* so primary is on top) + if (state.comparisons && state.visibleComparisons.size > 0) { interactiveCtx.lineCap = "round"; interactiveCtx.lineJoin = "round"; - interactiveCtx.beginPath(); - for (let i = 0; i < state.navMeshPath.length; i++) { - const [x, y] = state.navMeshPath[i]; - const screen = mapToScreen(x + 0.5, y + 0.5); - if (i === 0) { - interactiveCtx.moveTo(screen.x, screen.y); - } else { - interactiveCtx.lineTo(screen.x, screen.y); + for (const comp of state.comparisons) { + if (!state.visibleComparisons.has(comp.adapter)) continue; + if (!comp.path || comp.path.length === 0) continue; + + const color = COMPARISON_COLORS[comp.adapter] || "#ffffff"; + interactiveCtx.strokeStyle = color; + interactiveCtx.lineWidth = Math.max(1, zoomLevel); + interactiveCtx.beginPath(); + + for (let i = 0; i < comp.path.length; i++) { + const [x, y] = comp.path[i]; + const screen = mapToScreen(x + 0.5, y + 0.5); + if (i === 0) { + interactiveCtx.moveTo(screen.x, screen.y); + } else { + interactiveCtx.lineTo(screen.x, screen.y); + } } + interactiveCtx.stroke(); } - interactiveCtx.stroke(); } - // Draw PF.Mini path - if (state.pfMiniPath && state.pfMiniPath.length > 0) { - interactiveCtx.strokeStyle = "#ffaa00"; + // Draw HPA* path + if (state.hpaPath && state.hpaPath.length > 0) { + interactiveCtx.strokeStyle = "#00ffff"; interactiveCtx.lineWidth = Math.max(1, zoomLevel); interactiveCtx.lineCap = "round"; interactiveCtx.lineJoin = "round"; interactiveCtx.beginPath(); - for (let i = 0; i < state.pfMiniPath.length; i++) { - const [x, y] = state.pfMiniPath[i]; + for (let i = 0; i < state.hpaPath.length; i++) { + const [x, y] = state.hpaPath[i]; const screen = mapToScreen(x + 0.5, y + 0.5); if (i === 0) { interactiveCtx.moveTo(screen.x, screen.y); @@ -1393,16 +1318,16 @@ function renderInteractive() { interactiveCtx.stroke(); } - // Draw used gateways (highlighted) - if (showUsedGateways && state.debugInfo && state.debugInfo.gatewayWaypoints) { + // Draw used nodes (highlighted) + if (showUsedNodes && state.debugInfo && state.debugInfo.nodePath) { interactiveCtx.fillStyle = "#ffff00"; - const usedGatewayRadius = Math.max(3, zoomLevel * 2.5); + const usedNodeRadius = Math.max(3, zoomLevel * 2.5); - for (const [x, y] of state.debugInfo.gatewayWaypoints) { - // Gateways are coordinates [x, y] in the same format as path + for (const [x, y] of state.debugInfo.nodePath) { + // Nodes are coordinates [x, y] in the same format as path const screen = mapToScreen(x + 0.5, y + 0.5); interactiveCtx.beginPath(); - interactiveCtx.arc(screen.x, screen.y, usedGatewayRadius, 0, Math.PI * 2); + interactiveCtx.arc(screen.x, screen.y, usedNodeRadius, 0, Math.PI * 2); interactiveCtx.fill(); } } @@ -1472,41 +1397,40 @@ function renderInteractive() { } } -function findGatewayAtPosition(canvasX, canvasY, gatewaysToCheck = null) { - const gateways = - gatewaysToCheck || (state.graphDebug && state.graphDebug.allGateways); - if (!gateways) { +function findNodeAtPosition(canvasX, canvasY, nodesToCheck = null) { + const nodes = nodesToCheck || (state.graphDebug && state.graphDebug.allNodes); + if (!nodes) { return null; } const threshold = 10; - for (const gw of gateways) { - const gwX = gw.x * 2; - const gwY = gw.y * 2; - const dx = Math.abs(canvasX - gwX); - const dy = Math.abs(canvasY - gwY); + for (const node of nodes) { + const nodeX = node.x * 2; + const nodeY = node.y * 2; + const dx = Math.abs(canvasX - nodeX); + const dy = Math.abs(canvasY - nodeY); if (dx < threshold && dy < threshold) { - return gw; + return node; } } return null; } -// Show gateway tooltip -function showGatewayTooltip(gateway, mouseX, mouseY) { +// Show node tooltip +function showNodeTooltip(node, mouseX, mouseY) { const tooltip = document.getElementById("tooltip"); const connectedEdges = state.graphDebug.edges.filter( - (e) => e.fromId === gateway.id || e.toId === gateway.id, + (e) => e.fromId === node.id || e.toId === node.id, ); const selfLoops = connectedEdges.filter((e) => e.fromId === e.toId); - let html = `Gateway ${gateway.id}
`; - html += `Position: (${gateway.x * 2}, ${gateway.y * 2})
`; + let html = `Node ${node.id}
`; + html += `Position: (${node.x * 2}, ${node.y * 2})
`; html += `Edges: ${connectedEdges.length}`; if (selfLoops.length > 0) { @@ -1516,46 +1440,24 @@ function showGatewayTooltip(gateway, mouseX, mouseY) { if (connectedEdges.length > 0) { html += '
'; - const outgoing = connectedEdges.filter( - (e) => e.fromId === gateway.id && e.toId !== gateway.id, - ); - const incoming = connectedEdges.filter( - (e) => e.toId === gateway.id && e.fromId !== gateway.id, - ); - - if (outgoing.length > 0) { - html += `
Outgoing (${outgoing.length}):
`; - outgoing.slice(0, 5).forEach((edge) => { - const pathLen = edge.path ? edge.path.length : 0; - html += ` → GW ${edge.toId}: cost ${edge.cost.toFixed(1)}`; - if (pathLen > 0) html += ` (${pathLen} tiles)`; - html += "
"; - }); - if (outgoing.length > 5) { - html += ` ... and ${outgoing.length - 5} more
`; - } - } + // Edges are bidirectional now, just show connected nodes + const connected = connectedEdges.filter((e) => e.fromId !== e.toId); - if (incoming.length > 0) { - html += `
Incoming (${incoming.length}):
`; - incoming.slice(0, 5).forEach((edge) => { - const pathLen = edge.path ? edge.path.length : 0; - html += ` ← GW ${edge.fromId}: cost ${edge.cost.toFixed(1)}`; - if (pathLen > 0) html += ` (${pathLen} tiles)`; - html += "
"; + if (connected.length > 0) { + html += `
Connected (${connected.length}):
`; + connected.slice(0, 8).forEach((edge) => { + const otherId = edge.fromId === node.id ? edge.toId : edge.fromId; + html += ` ↔ Node ${otherId}: cost ${edge.cost.toFixed(1)}
`; }); - if (incoming.length > 5) { - html += ` ... and ${incoming.length - 5} more
`; + if (connected.length > 8) { + html += ` ... and ${connected.length - 8} more
`; } } if (selfLoops.length > 0) { html += `
Self-loops (${selfLoops.length}):
`; selfLoops.forEach((edge) => { - const pathLen = edge.path ? edge.path.length : 0; - html += ` ⟲ cost ${edge.cost.toFixed(1)}`; - if (pathLen > 0) html += ` (${pathLen} tiles)`; - html += "
"; + html += ` ⟲ cost ${edge.cost.toFixed(1)}
`; }); } diff --git a/tests/pathfinding/playground/public/index.html b/tests/pathfinding/playground/public/index.html index b3180dc45..6dbe07701 100644 --- a/tests/pathfinding/playground/public/index.html +++ b/tests/pathfinding/playground/public/index.html @@ -129,13 +129,13 @@

Pathfinding Playground

-
- - NavMesh + HPA*
- +
+ - - -
-

jyNAg%RoWO0jZfav6r!>t+V+^H&(QcXHJ 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 D!_DLD literal 0 HcmV?d00001 diff --git a/map-generator/assets/test_maps/world/info.json b/map-generator/assets/test_maps/world/info.json new file mode 100644 index 000000000..f6ed3d43e --- /dev/null +++ b/map-generator/assets/test_maps/world/info.json @@ -0,0 +1,310 @@ +{ + "name": "World", + "nations": [ + { + "coordinates": [375, 272], + "flag": "us", + "name": "United States" + }, + { + "coordinates": [372, 136], + "flag": "ca", + "name": "Canada" + }, + { + "coordinates": [375, 374], + "flag": "mx", + "name": "Mexico" + }, + { + "coordinates": [500, 378], + "flag": "cu", + "name": "Cuba" + }, + { + "coordinates": [524, 474], + "flag": "co", + "name": "Colombia" + }, + { + "coordinates": [593, 473], + "flag": "ve", + "name": "Venezuela" + }, + { + "coordinates": [596, 705], + "flag": "ar", + "name": "Argentina" + }, + { + "coordinates": [637, 567], + "flag": "br", + "name": "Brazil" + }, + { + "coordinates": [1280, 975], + "flag": "aq", + "name": "Antarctica" + }, + { + "coordinates": [709, 57], + "flag": "gl", + "name": "Greenland" + }, + { + "coordinates": [831, 112], + "flag": "is", + "name": "Iceland" + }, + { + "coordinates": [925, 186], + "flag": "gb", + "name": "United Kingdom" + }, + { + "coordinates": [887, 183], + "flag": "ie", + "name": "Ireland" + }, + { + "coordinates": [908, 264], + "flag": "es", + "name": "Spain" + }, + { + "coordinates": [1004, 250], + "flag": "it", + "name": "Italy" + }, + { + "coordinates": [958, 220], + "flag": "fr", + "name": "France" + }, + { + "coordinates": [997, 205], + "flag": "de", + "name": "Germany" + }, + { + "coordinates": [1064, 101], + "flag": "se", + "name": "Sweden" + }, + { + "coordinates": [1046, 193], + "flag": "pl", + "name": "Poland" + }, + { + "coordinates": [1061, 188], + "flag": "by", + "name": "Belarus" + }, + { + "coordinates": [1073, 243], + "flag": "ro", + "name": "Romania" + }, + { + "coordinates": [1161, 274], + "flag": "tr", + "name": "Turkey" + }, + { + "coordinates": [969, 133], + "flag": "no", + "name": "Norway" + }, + { + "coordinates": [1062, 133], + "flag": "fi", + "name": "Finland" + }, + { + "coordinates": [1099, 211], + "flag": "ua", + "name": "Ukraine" + }, + { + "coordinates": [1344, 136], + "flag": "ru", + "name": "Russia" + }, + { + "coordinates": [1537, 186], + "flag": "mn", + "name": "Mongolia" + }, + { + "coordinates": [1524, 328], + "flag": "cn", + "name": "China" + }, + { + "coordinates": [1368, 373], + "flag": "in", + "name": "India" + }, + { + "coordinates": [1276, 239], + "flag": "kz", + "name": "Kazakhstan" + }, + { + "coordinates": [1238, 309], + "flag": "ir", + "name": "Islamic Republic Of Iran" + }, + { + "coordinates": [1178, 351], + "flag": "sa", + "name": "Saudi Arabia" + }, + { + "coordinates": [1679, 657], + "flag": "au", + "name": "Australia" + }, + { + "coordinates": [1890, 775], + "flag": "nz", + "name": "New Zealand" + }, + { + "coordinates": [918, 342], + "flag": "dz", + "name": "Algeria" + }, + { + "coordinates": [1030, 332], + "flag": "ly", + "name": "Libyan Arab Jamahiriya" + }, + { + "coordinates": [1092, 335], + "flag": "eg", + "name": "Egypt" + }, + { + "coordinates": [963, 410], + "flag": "ne", + "name": "Niger" + }, + { + "coordinates": [1112, 406], + "flag": "sd", + "name": "Sudan" + }, + { + "coordinates": [1074, 508], + "flag": "cd", + "name": "DR Congo" + }, + { + "coordinates": [1154, 443], + "flag": "et", + "name": "Ethiopia" + }, + { + "coordinates": [1075, 707], + "flag": "za", + "name": "South Africa" + }, + { + "coordinates": [1194, 627], + "flag": "mg", + "name": "Madagascar" + }, + { + "coordinates": [1052, 420], + "flag": "td", + "name": "Chad" + }, + { + "coordinates": [1030, 665], + "flag": "na", + "name": "Namibia" + }, + { + "coordinates": [1632, 465], + "flag": "ph", + "name": "Philippines" + }, + { + "coordinates": [1537, 426], + "flag": "th", + "name": "Thailand" + }, + { + "coordinates": [1610, 364], + "flag": "tw", + "name": "Taiwan" + }, + { + "coordinates": [1710, 290], + "flag": "jp", + "name": "Japan" + }, + { + "coordinates": [1869, 119], + "flag": "ru", + "name": "Siberia" + }, + { + "coordinates": [74, 117], + "flag": "polar_bears", + "name": "Polar Bears" + }, + { + "coordinates": [419, 975], + "flag": "aq", + "name": "West Antarctica" + }, + { + "coordinates": [542, 603], + "flag": "pe", + "name": "Peru" + }, + { + "coordinates": [1075, 615], + "flag": "zm", + "name": "Zambia" + }, + { + "coordinates": [1099, 165], + "flag": "lv", + "name": "Latvia" + }, + { + "coordinates": [1427, 336], + "flag": "bt", + "name": "Bhutan" + }, + { + "coordinates": [1511, 524], + "flag": "id", + "name": "Indonesia" + }, + { + "coordinates": [1809, 977], + "flag": "aq", + "name": "East Antarctica" + }, + { + "coordinates": [1255, 382], + "flag": "om", + "name": "Oman" + }, + { + "coordinates": [853, 373], + "flag": "ma", + "name": "Morocco" + }, + { + "coordinates": [656, 678], + "flag": "uy", + "name": "Uruguay" + } + ] +} diff --git a/src/client/Transport.ts b/src/client/Transport.ts index 333de32a1..2d6adc980 100644 --- a/src/client/Transport.ts +++ b/src/client/Transport.ts @@ -690,7 +690,7 @@ export class Transport { type: "donate_gold", clientID: this.lobbyConfig.clientID, recipient: event.recipient.id(), - gold: event.gold, + gold: event.gold !== null ? Number(event.gold) : null, }); } diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index e6496cdcf..82d0260c2 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -243,6 +243,7 @@ export const GameConfigSchema = z.object({ instantResearchHumanOnly: z.boolean().optional(), // If true, all players start with all techs researched researchAllTechs: z.boolean().optional(), + disableNavMesh: z.boolean().optional(), maxPlayers: z.number().optional(), disabledUnits: z.enum(UnitType).array().optional(), playerTeams: TeamCountConfigSchema.optional(), diff --git a/src/core/configuration/Config.ts b/src/core/configuration/Config.ts index 330d82d26..000cecd36 100644 --- a/src/core/configuration/Config.ts +++ b/src/core/configuration/Config.ts @@ -85,6 +85,7 @@ export interface Config { infiniteTroops(): boolean; instantBuild(): boolean; startingGold(): number; + disableNavMesh(): boolean; numSpawnPhaseTurns(): number; userSettings(): UserSettings; playerTeams(): TeamCountConfig; @@ -144,7 +145,8 @@ export interface Config { donateCooldown(): Tick; defaultDonationAmount(sender: Player): number; unitInfo(type: UnitType): UnitInfo; - tradeShipGold(dist: number): Gold; + tradeShipShortRangeDebuff(): number; + tradeShipGold(dist: number, numPorts?: number): Gold; tradeShipSpawnRate(numberOfPorts: number): number; // Trade rework: gravity-based demand and port-supplied ships tradeGravityK(): number; // Coefficient K in K * ip_i * ip_j / distance / world_industrial_production diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index 0310337f9..796876c9d 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -346,6 +346,9 @@ export class DefaultConfig implements Config { instantBuild(): boolean { return this._gameConfig.instantBuild; } + disableNavMesh(): boolean { + return this._gameConfig.disableNavMesh ?? false; + } infiniteGold(): boolean { return this._gameConfig.infiniteGold; } @@ -355,8 +358,18 @@ export class DefaultConfig implements Config { startingGold(): number { return this._gameConfig.startingGold ?? 0; } - tradeShipGold(dist: number): Gold { - return BigInt(Math.floor(10000 + 150 * Math.pow(dist, 1.1))); + tradeShipShortRangeDebuff(): number { + return 300; + } + tradeShipGold(dist: number, numPorts: number = 1): Gold { + // Sigmoid: concave start, sharp S-curve middle, linear end + const debuff = this.tradeShipShortRangeDebuff(); + const baseGold = + 100_000 / (1 + Math.exp(-0.03 * (dist - debuff))) + 100 * dist; + const numPortBonus = numPorts - 1; + // Hyperbolic decay, midpoint at 5 ports, 3x bonus max. + const bonus = 1 + 2 * (numPortBonus / (numPortBonus + 5)); + return BigInt(Math.floor(baseGold * bonus)); } tradeShipSpawnRate(numberOfPorts: number): number { return Math.round(10 * Math.pow(numberOfPorts, 0.37)); diff --git a/src/core/execution/ExecutionManager.ts b/src/core/execution/ExecutionManager.ts index 65599e929..9563fe982 100644 --- a/src/core/execution/ExecutionManager.ts +++ b/src/core/execution/ExecutionManager.ts @@ -141,7 +141,11 @@ export class Executor { intent.troops, ); case "donate_gold": - return new DonateGoldExecution(player, intent.recipient, intent.gold); + return new DonateGoldExecution( + player, + intent.recipient, + intent.gold !== null ? BigInt(intent.gold) : null, + ); case "troop_ratio": return new SetTargetTroopRatioExecution(player, intent.ratio); case "investment_rate": diff --git a/src/core/execution/SubmarineExecution.ts b/src/core/execution/SubmarineExecution.ts index 42e60fba8..070c20dd5 100644 --- a/src/core/execution/SubmarineExecution.ts +++ b/src/core/execution/SubmarineExecution.ts @@ -10,7 +10,7 @@ import { import { GameImpl } from "../game/GameImpl"; import { TileRef } from "../game/GameMap"; import { PathFindResultType } from "../pathfinding/AStar"; -import { PathFinder } from "../pathfinding/PathFinding"; +import { MiniPathFinder } from "../pathfinding/PathFinding"; import { PseudoRandom } from "../PseudoRandom"; import { ShellExecution } from "./ShellExecution"; @@ -19,7 +19,7 @@ export class SubmarineExecution implements Execution { private random: PseudoRandom; private submarine: Unit; private mg: GameImpl; - private pathfinder: PathFinder; + private pathfinder: MiniPathFinder; private lastShellAttack = 0; private alreadySentShell = new Set(); @@ -40,7 +40,7 @@ export class SubmarineExecution implements Execution { init(mg: Game, ticks: number): void { this.mg = mg as GameImpl; - this.pathfinder = PathFinder.Mini(mg, 10_000, true, 100); + this.pathfinder = new MiniPathFinder(mg, 10_000, true, 100); this.random = new PseudoRandom(mg.ticks()); if (isUnit(this.input)) { this.submarine = this.input; diff --git a/src/core/execution/TradeManagerExecution.ts b/src/core/execution/TradeManagerExecution.ts index 85fa12116..6b249ff8e 100644 --- a/src/core/execution/TradeManagerExecution.ts +++ b/src/core/execution/TradeManagerExecution.ts @@ -12,7 +12,7 @@ import { } from "../game/Game"; import { TileRef } from "../game/GameMap"; import { PathFindResultType } from "../pathfinding/AStar"; -import { PathFinder } from "../pathfinding/PathFinding"; +import { MiniPathFinder } from "../pathfinding/PathFinding"; import { PseudoRandom } from "../PseudoRandom"; import { roadEffectModifiers, tradeIncomeModifiers } from "../tech/TechEffects"; @@ -693,7 +693,7 @@ export class TradeManagerExecution implements Execution { export class AssignedTradeRouteExecution implements Execution { private mg!: Game; - private path!: PathFinder; + private path!: MiniPathFinder; private active = true; private phase: "toStart" | "toEnd" = "toStart"; private lastMoveTick = 0; @@ -708,7 +708,7 @@ export class AssignedTradeRouteExecution implements Execution { init(mg: Game, ticks: number): void { this.mg = mg; - this.path = PathFinder.Mini(mg, 30000, true, 100); + this.path = new MiniPathFinder(mg, 30000, true, 100); this.lastMoveTick = ticks; // Ensure ship is not in a stale 'returning' state from a prior turnaround this.ship.setReturning(false); diff --git a/src/core/execution/TradeShipExecution.ts b/src/core/execution/TradeShipExecution.ts new file mode 100644 index 000000000..f1230c6f4 --- /dev/null +++ b/src/core/execution/TradeShipExecution.ts @@ -0,0 +1,188 @@ +import { renderNumber } from "../../client/Utils"; +import { + Execution, + Game, + MessageType, + Player, + Unit, + UnitType, +} from "../game/Game"; +import { TileRef } from "../game/GameMap"; +import { PathFinder, PathFinders, PathStatus } from "../pathfinding/PathFinder"; +import { distSortUnit } from "../Util"; + +export class TradeShipExecution implements Execution { + private active = true; + private mg: Game; + private tradeShip: Unit | undefined; + private wasCaptured = false; + private pathFinder: PathFinder; + private tilesTraveled = 0; + + constructor( + private origOwner: Player, + private srcPort: Unit, + private _dstPort: Unit, + ) {} + + init(mg: Game, ticks: number): void { + this.mg = mg; + this.pathFinder = PathFinders.Water(mg); + } + + tick(ticks: number): void { + if (this.tradeShip === undefined) { + const spawn = this.origOwner.canBuild( + UnitType.TradeShip, + this.srcPort.tile(), + ); + if (spawn === false) { + console.warn(`cannot build trade ship`); + this.active = false; + return; + } + this.tradeShip = this.origOwner.buildUnit(UnitType.TradeShip, spawn, { + targetUnit: this._dstPort, + lastSetSafeFromPirates: ticks, + }); + this.mg.stats().boatSendTrade(this.origOwner, this._dstPort.owner()); + } + + if (!this.tradeShip.isActive()) { + this.active = false; + return; + } + + const tradeShipOwner = this.tradeShip.owner(); + const dstPortOwner = this._dstPort.owner(); + if (this.wasCaptured !== true && this.origOwner !== tradeShipOwner) { + // Store as variable in case ship is recaptured by previous owner + this.wasCaptured = true; + } + + // If a player captures another player's port while trading we should delete + // the ship. + if (dstPortOwner.id() === this.srcPort.owner().id()) { + this.tradeShip.delete(false); + this.active = false; + return; + } + + if ( + !this.wasCaptured && + (!this._dstPort.isActive() || !tradeShipOwner.canTrade(dstPortOwner)) + ) { + this.tradeShip.delete(false); + this.active = false; + return; + } + + if ( + this.wasCaptured && + (tradeShipOwner !== dstPortOwner || !this._dstPort.isActive()) + ) { + const ports = this.tradeShip + .owner() + .units(UnitType.Port) + .sort(distSortUnit(this.mg, this.tradeShip)); + if (ports.length === 0) { + this.tradeShip.delete(false); + this.active = false; + return; + } else { + this._dstPort = ports[0]; + this.tradeShip.setTargetUnit(this._dstPort); + } + } + + const curTile = this.tradeShip.tile(); + if (curTile === this.dstPort()) { + this.complete(); + return; + } + + const result = this.pathFinder.next(curTile, this._dstPort.tile()); + + switch (result.status) { + case PathStatus.PENDING: + // Fire unit event to rerender. + this.tradeShip.move(curTile); + break; + case PathStatus.NEXT: + // Update safeFromPirates status + if (this.mg.isWater(result.node) && this.mg.isShoreline(result.node)) { + this.tradeShip.setSafeFromPirates(); + } + this.tradeShip.move(result.node); + this.tilesTraveled++; + break; + case PathStatus.COMPLETE: + this.complete(); + break; + case PathStatus.NOT_FOUND: + console.warn("captured trade ship cannot find route"); + if (this.tradeShip.isActive()) { + this.tradeShip.delete(false); + } + this.active = false; + break; + } + } + + private complete() { + this.active = false; + this.tradeShip!.delete(false); + const gold = this.mg + .config() + .tradeShipGold( + this.tilesTraveled, + this.tradeShip!.owner().unitCount(UnitType.Port), + ); + + if (this.wasCaptured) { + this.tradeShip!.owner().addGold(gold, this._dstPort.tile()); + this.mg.displayMessage( + `Received ${renderNumber(gold)} gold from ship captured from ${this.origOwner.displayName()}`, + MessageType.CAPTURED_ENEMY_UNIT, + this.tradeShip!.owner().id(), + gold, + ); + // Record stats + this.mg + .stats() + .boatCapturedTrade(this.tradeShip!.owner(), this.origOwner, gold); + } else { + this.srcPort.owner().addGold(gold); + this._dstPort.owner().addGold(gold, this._dstPort.tile()); + this.mg.displayMessage( + `Received ${renderNumber(gold)} gold from trade with ${this.srcPort.owner().displayName()}`, + MessageType.RECEIVED_GOLD_FROM_TRADE, + this._dstPort.owner().id(), + gold, + ); + this.mg.displayMessage( + `Received ${renderNumber(gold)} gold from trade with ${this._dstPort.owner().displayName()}`, + MessageType.RECEIVED_GOLD_FROM_TRADE, + this.srcPort.owner().id(), + gold, + ); + // Record stats + this.mg + .stats() + .boatArriveTrade(this.srcPort.owner(), this._dstPort.owner(), gold); + } + return; + } + + isActive(): boolean { + return this.active; + } + + activeDuringSpawnPhase(): boolean { + return false; + } + + dstPort(): TileRef { + return this._dstPort.tile(); + } +} diff --git a/src/core/execution/TransportShipExecution.ts b/src/core/execution/TransportShipExecution.ts index 280ad2d81..3c6cc73f3 100644 --- a/src/core/execution/TransportShipExecution.ts +++ b/src/core/execution/TransportShipExecution.ts @@ -11,8 +11,7 @@ import { } from "../game/Game"; import { TileRef } from "../game/GameMap"; import { targetTransportTile } from "../game/TransportShipUtils"; -import { PathFindResultType } from "../pathfinding/AStar"; -import { PathFinder } from "../pathfinding/PathFinding"; +import { PathFinder, PathFinders, PathStatus } from "../pathfinding/PathFinder"; import { AttackExecution } from "./AttackExecution"; export class TransportShipExecution implements Execution { @@ -79,7 +78,7 @@ export class TransportShipExecution implements Execution { this.lastMove = ticks; this.mg = mg; - this.pathFinder = PathFinder.Mini(mg, 10_000, true, 100); + this.pathFinder = PathFinders.Water(mg); if ( this.attacker.unitCount(UnitType.TransportShip) >= @@ -188,9 +187,9 @@ export class TransportShipExecution implements Execution { this.dst = this.src!; // src is guaranteed to be set at this point } - const result = this.pathFinder.nextTile(this.boat.tile(), this.dst); - switch (result.type) { - case PathFindResultType.Completed: + const result = this.pathFinder.next(this.boat.tile(), this.dst); + switch (result.status) { + case PathStatus.COMPLETE: if (this.mg.owner(this.dst) === this.attacker) { this.attacker.addTroops(this.boat.troops()); this.boat.delete(false); @@ -224,12 +223,12 @@ export class TransportShipExecution implements Execution { .stats() .boatArriveTroops(this.attacker, this.target, this.boat.troops()); return; - case PathFindResultType.NextTile: + case PathStatus.NEXT: this.boat.move(result.node); break; - case PathFindResultType.Pending: + case PathStatus.PENDING: break; - case PathFindResultType.PathNotFound: + case PathStatus.NOT_FOUND: // TODO: add to poisoned port list console.warn(`path not found to dst`); this.attacker.addTroops(this.boat.troops()); diff --git a/src/core/execution/WarshipExecution.ts b/src/core/execution/WarshipExecution.ts index 7a6fb7d55..120a75e50 100644 --- a/src/core/execution/WarshipExecution.ts +++ b/src/core/execution/WarshipExecution.ts @@ -9,10 +9,10 @@ import { UnitType, UpgradeType, } from "../game/Game"; -import { GameImpl } from "../game/GameImpl"; import { TileRef } from "../game/GameMap"; import { PathFindResultType } from "../pathfinding/AStar"; -import { PathFinder } from "../pathfinding/PathFinding"; +import { PathFinder, PathFinders, PathStatus } from "../pathfinding/PathFinder"; +import { MiniPathFinder } from "../pathfinding/PathFinding"; import { PseudoRandom } from "../PseudoRandom"; import { SAMMissileExecution } from "./SAMMissileExecution"; import { ShellExecution } from "./ShellExecution"; @@ -21,7 +21,7 @@ export class WarshipExecution implements Execution { executionName = "WarshipExecution"; private random: PseudoRandom; private warship: Unit; - private mg: GameImpl; + private mg: Game; private pathfinder: PathFinder; private lastShellAttack = 0; private alreadySentShell = new Set(); @@ -40,8 +40,8 @@ export class WarshipExecution implements Execution { ) {} init(mg: Game, ticks: number): void { - this.mg = mg as GameImpl; - this.pathfinder = PathFinder.Mini(mg, 10_000, true, 100); + this.mg = mg; + this.pathfinder = PathFinders.Water(mg); this.random = new PseudoRandom(mg.ticks()); if (isUnit(this.input)) { this.warship = this.input; @@ -363,62 +363,24 @@ export class WarshipExecution implements Execution { for (let i = 0; i < 2; i++) { // target is trade ship so capture it. - const result = this.pathfinder.nextTile( + const result = this.pathfinder.next( this.warship.tile(), this.warship.targetUnit()!.tile(), 5, ); - switch (result.type) { - case PathFindResultType.Completed: { - const targetShip = this.warship.targetUnit()!; - const myOwner = this.warship.owner(); - const shipOwner = targetShip.owner(); - if (myOwner.isAtWarWith(shipOwner)) { - // Enemy trade ship -> capture - this.warship.owner().captureUnit(targetShip); - // Clear any trade route metadata on the captured ship - targetShip.setTradeRouteOwners(null, null); - // Send captured ship back to a home port of the new owner; cargo will be awarded on arrival - this.mg.addExecution( - new CapturedTradeShipReturnExecution(targetShip), - ); - this.warship.setTargetUnit(undefined); - this.warship.move(this.warship.tile()); - return; - } - // Neutral trade ship headed to/from my enemy -> turn around upon contact - const startOwner = targetShip.tradeRouteStartOwner(); - const endOwner = targetShip.tradeRouteEndOwner(); - const atWarWithAnyEndpoint = [startOwner, endOwner] - .filter((p): p is Player => !!p) - .some((p) => myOwner.isAtWarWith(p)); - const embargoAgainstAnyEndpoint = [startOwner, endOwner] - .filter((p): p is Player => !!p) - .some( - (p) => - myOwner.hasEmbargoAgainst(p) || p.hasEmbargoAgainst(myOwner), - ); - if ( - (atWarWithAnyEndpoint || embargoAgainstAnyEndpoint) && - !myOwner.isFriendly(shipOwner) - ) { - targetShip.setReturning(true); - this.warship.setTargetUnit(undefined); - this.warship.move(this.warship.tile()); - return; - } - // Otherwise, disengage + switch (result.status) { + case PathStatus.COMPLETE: + this.warship.owner().captureUnit(this.warship.targetUnit()!); this.warship.setTargetUnit(undefined); this.warship.move(this.warship.tile()); return; - } - case PathFindResultType.NextTile: + case PathStatus.NEXT: this.warship.move(result.node); break; - case PathFindResultType.Pending: + case PathStatus.PENDING: this.warship.touch(); break; - case PathFindResultType.PathNotFound: + case PathStatus.NOT_FOUND: console.log(`path not found to target`); break; } @@ -433,22 +395,22 @@ export class WarshipExecution implements Execution { } } - const result = this.pathfinder.nextTile( + const result = this.pathfinder.next( this.warship.tile(), this.warship.targetTile()!, ); - switch (result.type) { - case PathFindResultType.Completed: + switch (result.status) { + case PathStatus.COMPLETE: this.warship.setTargetTile(undefined); this.warship.move(result.node); break; - case PathFindResultType.NextTile: + case PathStatus.NEXT: this.warship.move(result.node); break; - case PathFindResultType.Pending: + case PathStatus.PENDING: this.warship.touch(); return; - case PathFindResultType.PathNotFound: + case PathStatus.NOT_FOUND: console.warn(`path not found to target tile`); this.warship.setTargetTile(undefined); break; @@ -612,7 +574,7 @@ export class WarshipExecution implements Execution { class CapturedTradeShipReturnExecution implements Execution { executionName = "CapturedTradeShipReturnExecution"; private mg!: Game; - private pathfinder!: PathFinder; + private pathfinder!: MiniPathFinder; private active = true; private lastMoveTick = 0; private destPort: Unit | null = null; @@ -621,7 +583,7 @@ class CapturedTradeShipReturnExecution implements Execution { init(mg: Game, ticks: number): void { this.mg = mg; - this.pathfinder = PathFinder.Mini(mg, 2500); + this.pathfinder = new MiniPathFinder(mg, 2500, true, 100); this.lastMoveTick = ticks; // Pick nearest active port owned by the ship's owner this.destPort = this.selectNearestPort(this.ship.owner()); diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index 317b771bd..01b11c95f 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -1,4 +1,5 @@ import { Config } from "../configuration/Config"; +import { NavMesh } from "../pathfinding/navmesh/NavMesh"; import { AllPlayersStats, ClientID } from "../Schemas"; import { Category } from "../tech/ResearchTree"; import { Cell, GameMap, MapPos, TerrainType, TileRef } from "./GameMap"; @@ -621,7 +622,7 @@ export interface Player { // Research: investment ratio (0..1) of per-tick income allocated to research (cost only) researchInvestmentRate(): number; setResearchInvestmentRate(rate: number): void; - addGold(toAdd: Gold): void; + addGold(toAdd: Gold, tile?: TileRef): void; removeGold(toRemove: Gold): Gold; addWorkers(toAdd: number): void; removeWorkers(toRemove: number): void; @@ -879,6 +880,9 @@ export interface Game extends GameMap { ): void; doomsdayExplosion(tile: TileRef, radius: number, owner: Player): void; conquer(newOwner: Player, tile: TileRef): void; + + addUpdate(update: GameUpdate): void; + navMesh(): NavMesh | null; } export interface PlayerActions { diff --git a/src/core/game/GameImpl.ts b/src/core/game/GameImpl.ts index 1f3d49227..20e810572 100644 --- a/src/core/game/GameImpl.ts +++ b/src/core/game/GameImpl.ts @@ -1,5 +1,6 @@ import { Config } from "../configuration/Config"; import { AttackExecution } from "../execution/AttackExecution"; +import { NavMesh } from "../pathfinding/navmesh/NavMesh"; import { AllPlayersStats, ClientID, Winner } from "../Schemas"; import { simpleHash } from "../Util"; import { AllianceImpl } from "./AllianceImpl"; @@ -90,6 +91,9 @@ export class GameImpl implements Game { private playerTeams: Team[]; private botTeam: Team = ColoredTeams.Bot; + private _isPaused: boolean = false; + private _navMesh: NavMesh | null = null; + constructor( private _humans: PlayerInfo[], private _nations: Nation[], @@ -118,6 +122,11 @@ export class GameImpl implements Game { this.populateTeams(); } this.addPlayers(); + + if (!_config.disableNavMesh()) { + this._navMesh = new NavMesh(this, { cachePaths: true }); + this._navMesh.initialize(); + } } private populateTeams() { @@ -1214,6 +1223,9 @@ export class GameImpl implements Game { public alliances(): AllianceImpl[] { return this.alliances_; } + navMesh(): NavMesh | null { + return this._navMesh; + } public hasRoadOnTile(tile: TileRef): boolean { return this.roadManager.hasRoadOnTile(tile); diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts index dcb5b1586..56548a145 100644 --- a/src/core/game/PlayerImpl.ts +++ b/src/core/game/PlayerImpl.ts @@ -1191,7 +1191,7 @@ export class PlayerImpl implements Player { return this._gold; } - addGold(toAdd: Gold): void { + addGold(toAdd: Gold, _tile?: TileRef): void { this._gold += toAdd; } diff --git a/src/core/pathfinding/PathFinder.ts b/src/core/pathfinding/PathFinder.ts new file mode 100644 index 000000000..7422e836b --- /dev/null +++ b/src/core/pathfinding/PathFinder.ts @@ -0,0 +1,43 @@ +import { Game } from "../game/Game"; +import { TileRef } from "../game/GameMap"; +import { MiniAStarAdapter } from "./adapters/MiniAStarAdapter"; +import { NavMeshAdapter } from "./adapters/NavMeshAdapter"; + +export enum PathStatus { + NEXT, + PENDING, + COMPLETE, + NOT_FOUND, +} + +export type PathResult = + | { status: PathStatus.PENDING } + | { status: PathStatus.NEXT; node: TileRef } + | { status: PathStatus.COMPLETE; node: TileRef } + | { status: PathStatus.NOT_FOUND }; + +export interface PathFinder { + next(from: TileRef, to: TileRef, dist?: number): PathResult; + findPath(from: TileRef, to: TileRef): TileRef[] | null; +} + +export interface MiniAStarOptions { + waterPath?: boolean; + iterations?: number; + maxTries?: number; +} + +export class PathFinders { + static Water(game: Game): PathFinder { + if (!game.navMesh()) { + // Fall back to old water pathfinder if navmesh is not available + return PathFinders.WaterLegacy(game); + } + + return new NavMeshAdapter(game); + } + + static WaterLegacy(game: Game, options?: MiniAStarOptions): PathFinder { + return new MiniAStarAdapter(game, options); + } +} diff --git a/src/core/pathfinding/PathFinding.ts b/src/core/pathfinding/PathFinding.ts index 44c4f3f52..97e1422f8 100644 --- a/src/core/pathfinding/PathFinding.ts +++ b/src/core/pathfinding/PathFinding.ts @@ -158,7 +158,7 @@ export class StraightPathFinder { } } } -export class PathFinder { +export class MiniPathFinder { private curr: TileRef | null = null; private dst: TileRef | null = null; private path: TileRef[] | null = null; @@ -166,28 +166,23 @@ export class PathFinder { private aStar: AStar; private computeFinished = true; - private constructor( + constructor( private game: Game, - private newAStar: (curr: TileRef, dst: TileRef) => AStar, + private iterations: number, + private waterPath: boolean, + private maxTries: number, ) {} - public static Mini( - game: Game, - iterations: number, - waterPath: boolean = true, - maxTries: number = 20, - ) { - return new PathFinder(game, (curr: TileRef, dst: TileRef) => { - return new MiniAStar( - game.map(), - game.miniMap(), - curr, - dst, - iterations, - maxTries, - waterPath, - ); - }); + private createAStar(curr: TileRef, dst: TileRef): AStar { + return new MiniAStar( + this.game.map(), + this.game.miniMap(), + curr, + dst, + this.iterations, + this.maxTries, + this.waterPath, + ); } nextTile( @@ -214,7 +209,7 @@ export class PathFinder { this.dst = dst; this.path = null; this.path_idx = 0; - this.aStar = this.newAStar(curr, dst); + this.aStar = this.createAStar(curr, dst); this.computeFinished = false; return this.nextTile(curr, dst); } else { @@ -229,7 +224,7 @@ export class PathFinder { this.dst = dst; this.path = null; this.path_idx = 0; - this.aStar = this.newAStar(curr, dst); + this.aStar = this.createAStar(curr, dst); this.computeFinished = false; return this.nextTile(curr, dst); } diff --git a/src/core/pathfinding/adapters/MiniAStarAdapter.ts b/src/core/pathfinding/adapters/MiniAStarAdapter.ts new file mode 100644 index 000000000..b1c1841d6 --- /dev/null +++ b/src/core/pathfinding/adapters/MiniAStarAdapter.ts @@ -0,0 +1,66 @@ +import { Game } from "../../game/Game"; +import { TileRef } from "../../game/GameMap"; +import { PathFindResultType } from "../AStar"; +import { + MiniAStarOptions, + PathFinder, + PathResult, + PathStatus, +} from "../PathFinder"; +import { MiniPathFinder } from "../PathFinding"; + +const DEFAULT_ITERATIONS = 10_000; +const DEFAULT_MAX_TRIES = 100; + +export class MiniAStarAdapter implements PathFinder { + private miniPathFinder: MiniPathFinder; + + constructor(game: Game, options?: MiniAStarOptions) { + this.miniPathFinder = new MiniPathFinder( + game, + options?.iterations ?? DEFAULT_ITERATIONS, + options?.waterPath ?? true, + options?.maxTries ?? DEFAULT_MAX_TRIES, + ); + } + + next(from: TileRef, to: TileRef, dist?: number): PathResult { + const result = this.miniPathFinder.nextTile(from, to, dist); + + switch (result.type) { + case PathFindResultType.Pending: + return { status: PathStatus.PENDING }; + case PathFindResultType.NextTile: + return { status: PathStatus.NEXT, node: result.node }; + case PathFindResultType.Completed: + return { status: PathStatus.COMPLETE, node: result.node }; + case PathFindResultType.PathNotFound: + return { status: PathStatus.NOT_FOUND }; + } + } + + findPath(from: TileRef, to: TileRef): TileRef[] | null { + const path: TileRef[] = [from]; + let current = from; + const maxSteps = 100_000; + + for (let i = 0; i < maxSteps; i++) { + const result = this.next(current, to); + + if (result.status === PathStatus.COMPLETE) { + return path; + } + + if (result.status === PathStatus.NOT_FOUND) { + return null; + } + + if (result.status === PathStatus.NEXT) { + current = result.node; + path.push(current); + } + } + + return null; + } +} diff --git a/src/core/pathfinding/adapters/NavMeshAdapter.ts b/src/core/pathfinding/adapters/NavMeshAdapter.ts new file mode 100644 index 000000000..4e081eb4a --- /dev/null +++ b/src/core/pathfinding/adapters/NavMeshAdapter.ts @@ -0,0 +1,99 @@ +import { Game } from "../../game/Game"; +import { TileRef } from "../../game/GameMap"; +import { NavMesh } from "../navmesh/NavMesh"; +import { PathFinder, PathResult, PathStatus } from "../PathFinder"; + +export class NavMeshAdapter implements PathFinder { + private navMesh: NavMesh; + private pathIndex = 0; + private path: TileRef[] | null = null; + private lastTo: TileRef | null = null; + + constructor(private game: Game) { + const navMesh = game.navMesh(); + if (!navMesh) { + throw new Error("NavMeshAdapter requires game.navMesh() to be available"); + } + this.navMesh = navMesh; + } + + next(from: TileRef, to: TileRef, dist?: number): PathResult { + if (typeof from !== "number" || typeof to !== "number") { + return { status: PathStatus.NOT_FOUND }; + } + + if (!this.game.isValidRef(from) || !this.game.isValidRef(to)) { + return { status: PathStatus.NOT_FOUND }; + } + + if (from === to) { + return { status: PathStatus.COMPLETE, node: to }; + } + + if (dist !== undefined && dist > 0) { + const distance = this.game.manhattanDist(from, to); + + if (distance <= dist) { + return { status: PathStatus.COMPLETE, node: from }; + } + } + + if (this.lastTo !== to) { + this.path = null; + this.pathIndex = 0; + this.lastTo = to; + } + + if (this.path === null) { + this.cachePath(from, to); + + if (this.path === null) { + return { status: PathStatus.NOT_FOUND }; + } + } + + // Recompute if deviated from planned path + const expectedPos = this.path[this.pathIndex - 1]; + if (this.pathIndex > 0 && from !== expectedPos) { + this.cachePath(from, to); + + if (this.path === null) { + return { status: PathStatus.NOT_FOUND }; + } + } + + if (this.pathIndex >= this.path.length) { + return { status: PathStatus.COMPLETE, node: to }; + } + + const nextNode = this.path[this.pathIndex]; + this.pathIndex++; + + return { status: PathStatus.NEXT, node: nextNode }; + } + + findPath(from: TileRef, to: TileRef): TileRef[] | null { + return this.navMesh.findPath(from, to); + } + + private cachePath(from: TileRef, to: TileRef): boolean { + try { + this.path = this.navMesh.findPath(from, to); + } catch { + return false; + } + + if (this.path === null) { + return false; + } + + this.pathIndex = 0; + + // Path starts with 'from', skip to next tile + if (this.path.length > 0 && this.path[0] === from) { + this.pathIndex = 1; + } + + return true; + } +} diff --git a/src/core/pathfinding/navmesh/FastAStar.ts b/src/core/pathfinding/navmesh/FastAStar.ts new file mode 100644 index 000000000..770248e79 --- /dev/null +++ b/src/core/pathfinding/navmesh/FastAStar.ts @@ -0,0 +1,202 @@ +// A* optimized for performance for small to medium graphs. +// Works with node IDs represented as integers (0 to numNodes-1) + +export interface FastAStarAdapter { + getNeighbors(node: number): number[]; + getCost(from: number, to: number): number; + heuristic(node: number, goal: number): number; +} + +// Simple binary min-heap for open set using typed arrays +class MinHeap { + private heap: Int32Array; + private scores: Float32Array; + private size = 0; + + constructor(capacity: number, scores: Float32Array) { + this.heap = new Int32Array(capacity); + this.scores = scores; + } + + push(node: number): void { + let i = this.size++; + this.heap[i] = node; + + // Bubble up + while (i > 0) { + const parent = (i - 1) >> 1; + if (this.scores[this.heap[parent]] <= this.scores[this.heap[i]]) { + break; + } + + // Swap + const tmp = this.heap[parent]; + this.heap[parent] = this.heap[i]; + this.heap[i] = tmp; + i = parent; + } + } + + pop(): number { + const result = this.heap[0]; + this.heap[0] = this.heap[--this.size]; + + // Bubble down + let i = 0; + while (true) { + const left = (i << 1) + 1; + const right = left + 1; + let smallest = i; + + if ( + left < this.size && + this.scores[this.heap[left]] < this.scores[this.heap[smallest]] + ) { + smallest = left; + } + + if ( + right < this.size && + this.scores[this.heap[right]] < this.scores[this.heap[smallest]] + ) { + smallest = right; + } + + if (smallest === i) { + break; + } + + // Swap + const tmp = this.heap[smallest]; + this.heap[smallest] = this.heap[i]; + this.heap[i] = tmp; + i = smallest; + } + + return result; + } + + isEmpty(): boolean { + return this.size === 0; + } + + clear(): void { + this.size = 0; + } +} + +export class FastAStar { + private stamp = 1; + private readonly closedStamp: Uint32Array; // Tracks fully processed nodes + private readonly gScoreStamp: Uint32Array; // Tracks valid gScores + private readonly gScore: Float32Array; + private readonly fScore: Float32Array; + private readonly cameFrom: Int32Array; + private readonly openHeap: MinHeap; + + constructor(numNodes: number) { + this.closedStamp = new Uint32Array(numNodes); + this.gScoreStamp = new Uint32Array(numNodes); + this.gScore = new Float32Array(numNodes); + this.fScore = new Float32Array(numNodes); + this.cameFrom = new Int32Array(numNodes); + this.openHeap = new MinHeap(numNodes, this.fScore); + } + + private nextStamp(): number { + const stamp = this.stamp++; + + if (this.stamp === 0) { + // Overflow - reset (extremely rare) + this.closedStamp.fill(0); + this.gScoreStamp.fill(0); + this.stamp = 1; + } + + return stamp; + } + + search( + start: number, + goal: number, + adapter: FastAStarAdapter, + maxIterations: number = 100000, + ): number[] | null { + const stamp = this.nextStamp(); + + this.openHeap.clear(); + this.gScore[start] = 0; + this.gScoreStamp[start] = stamp; + this.fScore[start] = adapter.heuristic(start, goal); + this.cameFrom[start] = -1; + this.openHeap.push(start); + + let iterations = 0; + + while (!this.openHeap.isEmpty() && iterations < maxIterations) { + iterations++; + + const current = this.openHeap.pop(); + + // Skip if already processed (duplicate from heap) + if (this.closedStamp[current] === stamp) { + continue; + } + + // Mark as processed + this.closedStamp[current] = stamp; + + // Found goal + if (current === goal) { + return this.reconstructPath(start, goal); + } + + const neighbors = adapter.getNeighbors(current); + const currentGScore = this.gScore[current]; + + for (const neighbor of neighbors) { + // Skip already processed neighbors + if (this.closedStamp[neighbor] === stamp) { + continue; + } + + const tentativeGScore = + currentGScore + adapter.getCost(current, neighbor); + + // If we haven't visited this neighbor yet, or found a better path + const hasValidGScore = this.gScoreStamp[neighbor] === stamp; + if (!hasValidGScore || tentativeGScore < this.gScore[neighbor]) { + this.cameFrom[neighbor] = current; + this.gScore[neighbor] = tentativeGScore; + this.gScoreStamp[neighbor] = stamp; + this.fScore[neighbor] = + tentativeGScore + adapter.heuristic(neighbor, goal); + + // Add to heap (allow duplicates for better paths) + this.openHeap.push(neighbor); + } + } + } + + return null; + } + + private reconstructPath(start: number, goal: number): number[] { + const path: number[] = []; + let current = goal; + + while (current !== start) { + path.push(current); + current = this.cameFrom[current]; + + // Safety check + if (current === -1) { + return []; + } + } + + path.push(start); + path.reverse(); + return path; + } +} diff --git a/src/core/pathfinding/navmesh/FastAStarAdapter.ts b/src/core/pathfinding/navmesh/FastAStarAdapter.ts new file mode 100644 index 000000000..95b962233 --- /dev/null +++ b/src/core/pathfinding/navmesh/FastAStarAdapter.ts @@ -0,0 +1,120 @@ +import { GameMap, TileRef } from "../../game/GameMap"; +import { FastAStarAdapter } from "./FastAStar"; +import { GatewayGraph } from "./GatewayGraph"; + +export class GatewayGraphAdapter implements FastAStarAdapter { + constructor(private graph: GatewayGraph) {} + + getNeighbors(node: number): number[] { + const edges = this.graph.getEdges(node); + return edges.map((edge) => edge.to); + } + + getCost(from: number, to: number): number { + const edges = this.graph.getEdges(from); + const edge = edges.find((edge) => edge.to === to); + return edge?.cost ?? 1; + } + + heuristic(node: number, goal: number): number { + const nodeGw = this.graph.getGateway(node); + const goalGw = this.graph.getGateway(goal); + + if (!nodeGw || !goalGw) { + throw new Error( + `Invalid gateway ID in heuristic: node=${node} (${nodeGw ? "exists" : "missing"}), goal=${goal} (${goalGw ? "exists" : "missing"})`, + ); + } + + // Manhattan distance heuristic + const dx = Math.abs(nodeGw.x - goalGw.x); + const dy = Math.abs(nodeGw.y - goalGw.y); + return dx + dy; + } +} + +export class BoundedGameMapAdapter implements FastAStarAdapter { + private readonly minX: number; + private readonly minY: number; + private readonly width: number; + private readonly height: number; + private readonly startTile: TileRef; + private readonly goalTile: TileRef; + + readonly numNodes: number; + + constructor( + private map: GameMap, + startTile: TileRef, + goalTile: TileRef, + bounds: { minX: number; maxX: number; minY: number; maxY: number }, + ) { + this.startTile = startTile; + this.goalTile = goalTile; + + this.minX = bounds.minX; + this.minY = bounds.minY; + this.width = bounds.maxX - bounds.minX + 1; + this.height = bounds.maxY - bounds.minY + 1; + + this.numNodes = this.width * this.height; + } + + // Convert global TileRef to local node ID + tileToNode(tile: TileRef): number { + const x = this.map.x(tile) - this.minX; + const y = this.map.y(tile) - this.minY; + + // Allow start and goal tiles to be outside bounds (matching graph building behavior) + const isOutsideBounds = + x < 0 || x >= this.width || y < 0 || y >= this.height; + const isStartOrGoal = tile === this.startTile || tile === this.goalTile; + if (isOutsideBounds && !isStartOrGoal) { + return -1; // Outside bounds + } + + // Clamp coordinates for start/goal tiles that are outside bounds + const clampedX = Math.max(0, Math.min(this.width - 1, x)); + const clampedY = Math.max(0, Math.min(this.height - 1, y)); + + return clampedY * this.width + clampedX; + } + + // Convert local node ID to global TileRef + nodeToTile(node: number): TileRef { + const localX = node % this.width; + const localY = Math.floor(node / this.width); + return this.map.ref(localX + this.minX, localY + this.minY); + } + + getNeighbors(node: number): number[] { + const tile = this.nodeToTile(node); + const neighbors = this.map.neighbors(tile); + const result: number[] = []; + + for (const neighborTile of neighbors) { + if (!this.map.isWater(neighborTile)) continue; + + const neighborNode = this.tileToNode(neighborTile); + if (neighborNode !== -1) { + result.push(neighborNode); + } + } + + return result; + } + + getCost(_from: number, _to: number): number { + return 1; // Uniform cost for water tiles + } + + heuristic(node: number, goal: number): number { + const nodeTile = this.nodeToTile(node); + const goalTile = this.nodeToTile(goal); + + const dx = Math.abs(this.map.x(nodeTile) - this.map.x(goalTile)); + const dy = Math.abs(this.map.y(nodeTile) - this.map.y(goalTile)); + + return dx + dy; // Manhattan distance + } +} diff --git a/src/core/pathfinding/navmesh/FastBFS.ts b/src/core/pathfinding/navmesh/FastBFS.ts new file mode 100644 index 000000000..11ff34725 --- /dev/null +++ b/src/core/pathfinding/navmesh/FastBFS.ts @@ -0,0 +1,118 @@ +export interface FastBFSAdapter { + visitor(node: number, dist: number): T | null | undefined; + isValidNode(node: number): boolean; +} + +// Optimized BFS using stamp-based visited tracking and typed array queue +export class FastBFS { + private stamp = 1; + private readonly visitedStamp: Uint32Array; + private readonly queue: Int32Array; + private readonly dist: Uint16Array; + + constructor(numNodes: number) { + this.visitedStamp = new Uint32Array(numNodes); + this.queue = new Int32Array(numNodes); + this.dist = new Uint16Array(numNodes); + } + + search( + width: number, + height: number, + start: number, + maxDistance: number, + isValidNode: FastBFSAdapter["isValidNode"], + visitor: FastBFSAdapter["visitor"], + ): T | null { + const stamp = this.nextStamp(); + const lastRowStart = (height - 1) * width; + + let head = 0; + let tail = 0; + + this.visitedStamp[start] = stamp; + this.dist[start] = 0; + this.queue[tail++] = start; + + while (head < tail) { + const node = this.queue[head++]; + const currentDist = this.dist[node]; + + if (currentDist > maxDistance) { + continue; + } + + // Call visitor: + // - Returns T: Found target, return immediately + // - Returns null: Reject tile, don't explore neighbors + // - Returns undefined: Valid tile, explore neighbors + const result = visitor(node, currentDist); + + if (result !== null && result !== undefined) { + return result; + } + + // If visitor returned null, reject this tile and don't explore neighbors + if (result === null) { + continue; + } + + const nextDist = currentDist + 1; + const x = node % width; + + // North + if (node >= width) { + const n = node - width; + if (this.visitedStamp[n] !== stamp && isValidNode(n)) { + this.visitedStamp[n] = stamp; + this.dist[n] = nextDist; + this.queue[tail++] = n; + } + } + + // South + if (node < lastRowStart) { + const s = node + width; + if (this.visitedStamp[s] !== stamp && isValidNode(s)) { + this.visitedStamp[s] = stamp; + this.dist[s] = nextDist; + this.queue[tail++] = s; + } + } + + // West + if (x !== 0) { + const wv = node - 1; + if (this.visitedStamp[wv] !== stamp && isValidNode(wv)) { + this.visitedStamp[wv] = stamp; + this.dist[wv] = nextDist; + this.queue[tail++] = wv; + } + } + + // East + if (x !== width - 1) { + const ev = node + 1; + if (this.visitedStamp[ev] !== stamp && isValidNode(ev)) { + this.visitedStamp[ev] = stamp; + this.dist[ev] = nextDist; + this.queue[tail++] = ev; + } + } + } + + return null; + } + + private nextStamp(): number { + const stamp = this.stamp++; + + if (this.stamp === 0) { + // Overflow - reset (extremely rare) + this.visitedStamp.fill(0); + this.stamp = 1; + } + + return stamp; + } +} diff --git a/src/core/pathfinding/navmesh/GatewayGraph.ts b/src/core/pathfinding/navmesh/GatewayGraph.ts new file mode 100644 index 000000000..c08b60a99 --- /dev/null +++ b/src/core/pathfinding/navmesh/GatewayGraph.ts @@ -0,0 +1,587 @@ +import { Game } from "../../game/Game"; +import { GameMap, TileRef } from "../../game/GameMap"; +import { FastBFS } from "./FastBFS"; +import { WaterComponents } from "./WaterComponents"; + +export interface Gateway { + id: number; + x: number; + y: number; + tile: TileRef; + componentId: number; +} + +export interface Edge { + from: number; + to: number; + cost: number; + path?: TileRef[]; + sectorX: number; + sectorY: number; +} + +export interface Sector { + x: number; + y: number; + gateways: Gateway[]; + edges: Edge[]; +} + +export type BuildDebugInfo = { + sectors: number | null; + gateways: number | null; + edges: number | null; + actualBFSCalls: number | null; + potentialBFSCalls: number | null; + skippedByComponentFilter: number | null; + timings: { [key: string]: number }; +}; + +export class GatewayGraph { + constructor( + readonly sectors: ReadonlyMap, + readonly gateways: ReadonlyMap, + readonly edges: ReadonlyMap, + readonly sectorSize: number, + readonly sectorsX: number, + ) {} + + getSectorKey(sectorX: number, sectorY: number): number { + return sectorY * this.sectorsX + sectorX; + } + + getSector(sectorX: number, sectorY: number): Sector | undefined { + return this.sectors.get(this.getSectorKey(sectorX, sectorY)); + } + + getGateway(id: number): Gateway | undefined { + return this.gateways.get(id); + } + + getEdges(gatewayId: number): Edge[] { + return this.edges.get(gatewayId) ?? []; + } + + getNearbySectorGateways(sectorX: number, sectorY: number): Gateway[] { + const nearby: Gateway[] = []; + for (let dy = -1; dy <= 1; dy++) { + for (let dx = -1; dx <= 1; dx++) { + const sector = this.getSector(sectorX + dx, sectorY + dy); + if (sector) { + nearby.push(...sector.gateways); + } + } + } + return nearby; + } + + getAllGateways(): Gateway[] { + return Array.from(this.gateways.values()); + } +} + +export class GatewayGraphBuilder { + static readonly SECTOR_SIZE = 32; + + // Derived immutable state + private readonly miniMap: GameMap; + private readonly width: number; + private readonly height: number; + private readonly sectorsX: number; + private readonly sectorsY: number; + private readonly fastBFS: FastBFS; + private readonly waterComponents: WaterComponents; + + // Mutable build state + private sectors = new Map(); + private gateways = new Map(); + private tileToGateway = new Map(); + private edges = new Map(); + private nextGatewayId = 0; + + // Programatically accessible debug info + public debugInfo: BuildDebugInfo | null = null; + + constructor( + private readonly game: Game, + private readonly sectorSize: number, + ) { + this.miniMap = game.miniMap(); + this.width = this.miniMap.width(); + this.height = this.miniMap.height(); + this.sectorsX = Math.ceil(this.width / sectorSize); + this.sectorsY = Math.ceil(this.height / sectorSize); + this.fastBFS = new FastBFS(this.width * this.height); + this.waterComponents = new WaterComponents(this.miniMap); + } + + build(debug: boolean): GatewayGraph { + performance.mark("navsat:build:start"); + + if (debug) { + console.log( + `[DEBUG] Building gateway graph with sector size ${this.sectorSize} (${this.sectorsX}x${this.sectorsY} sectors)`, + ); + + this.debugInfo = { + sectors: null, + gateways: null, + edges: null, + actualBFSCalls: null, + potentialBFSCalls: null, + skippedByComponentFilter: null, + timings: {}, + }; + } + + // Initialize water components before building gateway graph + performance.mark("navsat:build:water-component:start"); + this.waterComponents.initialize(); + performance.mark("navsat:build:water-component:end"); + const measure = performance.measure( + "navsat:build:water-component", + "navsat:build:water-component:start", + "navsat:build:water-component:end", + ); + + if (debug) { + console.log( + `[DEBUG] Water Component Identification: ${measure.duration.toFixed(2)}ms`, + ); + } + + performance.mark("navsat:build:gateways:start"); + for (let sy = 0; sy < this.sectorsY; sy++) { + for (let sx = 0; sx < this.sectorsX; sx++) { + this.processSector(sx, sy); + } + } + performance.mark("navsat:build:gateways:end"); + const gatewaysMeasure = performance.measure( + "navsat:build:gateways", + "navsat:build:gateways:start", + "navsat:build:gateways:end", + ); + + if (debug) { + console.log( + `[DEBUG] Gateway identification: ${gatewaysMeasure.duration.toFixed(2)}ms`, + ); + + this.debugInfo!.edges = 0; + this.debugInfo!.potentialBFSCalls = 0; + this.debugInfo!.skippedByComponentFilter = 0; + } + + performance.mark("navsat:build:edges:start"); + for (const sector of this.sectors.values()) { + const gws = sector.gateways; + const numGateways = gws.length; + + if (debug) { + this.debugInfo!.potentialBFSCalls! += + (numGateways * (numGateways - 1)) / 2; + + for (let i = 0; i < gws.length; i++) { + for (let j = i + 1; j < gws.length; j++) { + if (gws[i].componentId !== gws[j].componentId) { + this.debugInfo!.skippedByComponentFilter!++; + } + } + } + } + + this.buildSectorConnections(sector); + + if (debug) { + // Divide by 2 because bidirectional + this.debugInfo!.edges! += sector.edges.length / 2; + } + } + + if (debug) { + this.debugInfo!.actualBFSCalls = + this.debugInfo!.potentialBFSCalls! - + this.debugInfo!.skippedByComponentFilter!; + } + + performance.mark("navsat:build:edges:end"); + const edgesMeasure = performance.measure( + "navsat:build:edges", + "navsat:build:edges:start", + "navsat:build:edges:end", + ); + + if (debug) { + console.log( + `[DEBUG] Edges Identification: ${edgesMeasure.duration.toFixed(2)}ms`, + ); + console.log( + `[DEBUG] Potential BFS calls: ${this.debugInfo!.potentialBFSCalls}`, + ); + console.log( + `[DEBUG] Skipped by component filter: ${this.debugInfo!.skippedByComponentFilter} (${((this.debugInfo!.skippedByComponentFilter! / this.debugInfo!.potentialBFSCalls!) * 100).toFixed(1)}%)`, + ); + console.log( + `[DEBUG] Actual BFS calls: ${this.debugInfo!.actualBFSCalls}`, + ); + console.log( + `[DEBUG] Edges Found: ${this.debugInfo!.edges} (${((this.debugInfo!.edges! / this.debugInfo!.actualBFSCalls!) * 100).toFixed(1)}% success rate)`, + ); + } + + performance.mark("navsat:build:end"); + const totalMeasure = performance.measure( + "navsat:build:total", + "navsat:build:start", + "navsat:build:end", + ); + + if (debug) { + console.log( + `[DEBUG] Gateway graph built in ${totalMeasure.duration.toFixed(2)}ms`, + ); + console.log(`[DEBUG] Gateways: ${this.gateways.size}`); + console.log(`[DEBUG] Sectors: ${this.sectors.size}`); + } + + return new GatewayGraph( + this.sectors, + this.gateways, + this.edges, + this.sectorSize, + this.sectorsX, + ); + } + + private getSectorKey(sectorX: number, sectorY: number): number { + return sectorY * this.sectorsX + sectorX; + } + + private getOrCreateGateway(x: number, y: number): Gateway { + const tile = this.miniMap.ref(x, y); + + // O(1) lookup using tile reference + const existing = this.tileToGateway.get(tile); + if (existing) { + return existing; + } + + const gateway: Gateway = { + id: this.nextGatewayId++, + x: x, + y: y, + tile: tile, + componentId: this.waterComponents.getComponentId(tile), + }; + + this.gateways.set(gateway.id, gateway); + this.tileToGateway.set(tile, gateway); + return gateway; + } + + private addGatewayToSector(sector: Sector, gateway: Gateway): void { + // Check for duplicates: a gateway at a sector corner can be + // detected by both horizontal and vertical edge scans + for (const existingGw of sector.gateways) { + if (existingGw.x === gateway.x && existingGw.y === gateway.y) { + return; + } + } + + // Gateway doesn't exist in sector yet, add it + sector.gateways.push(gateway); + } + + private processSector(sx: number, sy: number): void { + const sectorKey = this.getSectorKey(sx, sy); + let sector = this.sectors.get(sectorKey); + + if (!sector) { + sector = { x: sx, y: sy, gateways: [], edges: [] }; + this.sectors.set(sectorKey, sector); + } + + const baseX = sx * this.sectorSize; + const baseY = sy * this.sectorSize; + + if (sx < this.sectorsX - 1) { + const edgeX = Math.min(baseX + this.sectorSize - 1, this.width - 1); + const newGateways = this.findGatewaysOnVerticalEdge(edgeX, baseY); + + for (const gateway of newGateways) { + this.addGatewayToSector(sector, gateway); + + const rightSectorKey = this.getSectorKey(sx + 1, sy); + let rightSector = this.sectors.get(rightSectorKey); + + if (!rightSector) { + rightSector = { x: sx + 1, y: sy, gateways: [], edges: [] }; + this.sectors.set(rightSectorKey, rightSector); + } + + this.addGatewayToSector(rightSector, gateway); + } + } + + if (sy < this.sectorsY - 1) { + const edgeY = Math.min(baseY + this.sectorSize - 1, this.height - 1); + const newGateways = this.findGatewaysOnHorizontalEdge(edgeY, baseX); + + for (const gateway of newGateways) { + this.addGatewayToSector(sector, gateway); + + const bottomSectorKey = this.getSectorKey(sx, sy + 1); + let bottomSector = this.sectors.get(bottomSectorKey); + + if (!bottomSector) { + bottomSector = { x: sx, y: sy + 1, gateways: [], edges: [] }; + this.sectors.set(bottomSectorKey, bottomSector); + } + + this.addGatewayToSector(bottomSector, gateway); + } + } + } + + private findGatewaysOnVerticalEdge(x: number, baseY: number): Gateway[] { + const gateways: Gateway[] = []; + const maxY = Math.min(baseY + this.sectorSize, this.height); + + let gatewayStart = -1; + + const tryAddGateway = (y: number) => { + if (gatewayStart === -1) return; + + const gatewayLength = y - gatewayStart; + const midY = gatewayStart + Math.floor(gatewayLength / 2); + + gatewayStart = -1; + + const gateway = this.getOrCreateGateway(x, midY); + gateways.push(gateway); + }; + + for (let y = baseY; y < maxY; y++) { + const tile = this.miniMap.ref(x, y); + const nextTile = + x + 1 < this.miniMap.width() ? this.miniMap.ref(x + 1, y) : -1; + const isGateway = + this.miniMap.isWater(tile) && + nextTile !== -1 && + this.miniMap.isWater(nextTile); + + if (isGateway) { + if (gatewayStart === -1) { + gatewayStart = y; + } + } else { + tryAddGateway(y); + } + } + + tryAddGateway(maxY); + + return gateways; + } + + private findGatewaysOnHorizontalEdge(y: number, baseX: number): Gateway[] { + const gateways: Gateway[] = []; + const maxX = Math.min(baseX + this.sectorSize, this.width); + + let gatewayStart = -1; + + const tryAddGateway = (x: number) => { + if (gatewayStart === -1) return; + + const gatewayLength = x - gatewayStart; + const midX = gatewayStart + Math.floor(gatewayLength / 2); + + gatewayStart = -1; + + const gateway = this.getOrCreateGateway(midX, y); + gateways.push(gateway); + }; + + for (let x = baseX; x < maxX; x++) { + const tile = this.miniMap.ref(x, y); + const nextTile = + y + 1 < this.miniMap.height() ? this.miniMap.ref(x, y + 1) : -1; + const isGateway = + this.miniMap.isWater(tile) && + nextTile !== -1 && + this.miniMap.isWater(nextTile); + + if (isGateway) { + if (gatewayStart === -1) { + gatewayStart = x; + } + } else { + tryAddGateway(x); + } + } + + tryAddGateway(maxX); + + return gateways; + } + + private buildSectorConnections(sector: Sector): void { + const gateways = sector.gateways; + + // Calculate bounding box once for this sector + const sectorMinX = sector.x * this.sectorSize; + const sectorMinY = sector.y * this.sectorSize; + const sectorMaxX = Math.min( + this.width - 1, + sectorMinX + this.sectorSize - 1, + ); + const sectorMaxY = Math.min( + this.height - 1, + sectorMinY + this.sectorSize - 1, + ); + + for (let i = 0; i < gateways.length; i++) { + const fromGateway = gateways[i]; + + // Build list of target gateways (only those we haven't processed yet) + const targetGateways: Gateway[] = []; + for (let j = i + 1; j < gateways.length; j++) { + // Skip if gateways are in different water components + if (gateways[i].componentId !== gateways[j].componentId) { + continue; + } + + targetGateways.push(gateways[j]); + } + + if (targetGateways.length === 0) { + continue; + } + + // Single BFS to find all reachable target gateways + const reachableGateways = this.findAllReachableGatewaysInBounds( + fromGateway.tile, + targetGateways, + sectorMinX, + sectorMaxX, + sectorMinY, + sectorMaxY, + ); + + // Create edges for all reachable gateways + for (const [targetId, cost] of reachableGateways.entries()) { + if (!this.edges.has(fromGateway.id)) { + this.edges.set(fromGateway.id, []); + } + + if (!this.edges.has(targetId)) { + this.edges.set(targetId, []); + } + + // Check for existing edges - gateways may live in 2 sectors, keep only cheaper connection + const existingEdgeFromI = this.edges + .get(fromGateway.id)! + .find((e) => e.to === targetId); + const existingEdgeFromJ = this.edges + .get(targetId)! + .find((e) => e.to === fromGateway.id); + + // If edge doesn't exist or new cost is cheaper, update it + if (!existingEdgeFromI || cost < existingEdgeFromI.cost) { + const edge1: Edge = { + from: fromGateway.id, + to: targetId, + cost: cost, + sectorX: sector.x, + sectorY: sector.y, + }; + + const edge2: Edge = { + from: targetId, + to: fromGateway.id, + cost: cost, + sectorX: sector.x, + sectorY: sector.y, + }; + + // Add to sector edges for tracking + sector.edges.push(edge1, edge2); + + if (existingEdgeFromI) { + const idx1 = this.edges + .get(fromGateway.id)! + .indexOf(existingEdgeFromI); + this.edges.get(fromGateway.id)![idx1] = edge1; + + const idx2 = this.edges.get(targetId)!.indexOf(existingEdgeFromJ!); + this.edges.get(targetId)![idx2] = edge2; + } else { + this.edges.get(fromGateway.id)!.push(edge1); + this.edges.get(targetId)!.push(edge2); + } + } + } + } + } + + private findAllReachableGatewaysInBounds( + from: TileRef, + targetGateways: Gateway[], + minX: number, + maxX: number, + minY: number, + maxY: number, + ): Map { + const fromX = this.miniMap.x(from); + const fromY = this.miniMap.y(from); + + // Create a map of tile positions to gateway IDs for fast lookup + const tileToGateway = new Map(); + let maxManhattanDist = 0; + + for (const gateway of targetGateways) { + tileToGateway.set(gateway.tile, gateway.id); + const dx = Math.abs(gateway.x - fromX); + const dy = Math.abs(gateway.y - fromY); + maxManhattanDist = Math.max(maxManhattanDist, dx + dy); + } + + const maxDistance = maxManhattanDist * 4; // Allow path deviation + const reachable = new Map(); + let foundCount = 0; + + this.fastBFS.search( + this.miniMap.width(), + this.miniMap.height(), + from, + maxDistance, + (tile: number) => this.miniMap.isWater(tile), + (tile: number, dist: number) => { + const x = this.miniMap.x(tile); + const y = this.miniMap.y(tile); + + // Reject if outside of bounding box + const isStartOrEnd = tile === from || tileToGateway.has(tile); + if (!isStartOrEnd && (x < minX || x > maxX || y < minY || y > maxY)) { + return null; + } + + // Check if this tile is one of our target gateways + const gatewayId = tileToGateway.get(tile); + + if (gatewayId !== undefined) { + reachable.set(gatewayId, dist); + foundCount++; + + // Early exit if we've found all target gateways + if (foundCount === targetGateways.length) { + return dist; // Return to stop BFS + } + } + }, + ); + + return reachable; + } +} diff --git a/src/core/pathfinding/navmesh/NavMesh.ts b/src/core/pathfinding/navmesh/NavMesh.ts new file mode 100644 index 000000000..574dbfccc --- /dev/null +++ b/src/core/pathfinding/navmesh/NavMesh.ts @@ -0,0 +1,819 @@ +import { Game } from "../../game/Game"; +import { TileRef } from "../../game/GameMap"; +import { FastAStar } from "./FastAStar"; +import { BoundedGameMapAdapter, GatewayGraphAdapter } from "./FastAStarAdapter"; +import { FastBFS } from "./FastBFS"; +import { Gateway, GatewayGraph, GatewayGraphBuilder } from "./GatewayGraph"; + +type PathDebugInfo = { + gatewayPath: TileRef[] | null; + initialPath: TileRef[] | null; + smoothPath: TileRef[] | null; + graph: { + sectorSize: number; + gateways: Array<{ id: number; tile: TileRef }>; + edges: Array<{ + fromId: number; + toId: number; + from: TileRef; + to: TileRef; + cost: number; + path: TileRef[] | null; + }>; + }; + timings: { [key: string]: number }; +}; + +export class NavMesh { + private graph!: GatewayGraph; + private initialized = false; + private fastBFS!: FastBFS; + private gatewayAStar!: FastAStar; + private localAStar!: FastAStar; + private localAStarMultiSector!: FastAStar; + + public debugInfo: PathDebugInfo | null = null; + + constructor( + private game: Game, + private options: { + cachePaths?: boolean; + } = {}, + ) {} + + initialize(debug: boolean = false) { + const gatewayGraphBuilder = new GatewayGraphBuilder( + this.game, + GatewayGraphBuilder.SECTOR_SIZE, + ); + this.graph = gatewayGraphBuilder.build(debug); + + const miniMap = this.game.miniMap(); + this.fastBFS = new FastBFS(miniMap.width() * miniMap.height()); + + const gatewayCount = this.graph.getAllGateways().length; + this.gatewayAStar = new FastAStar(gatewayCount); + + // Fixed-size FastAStar for sector-bounded local pathfinding + // Single sector: 32×32 = 1,024 nodes + const sectorSize = GatewayGraphBuilder.SECTOR_SIZE; + const maxLocalNodes = sectorSize * sectorSize; // 1,024 nodes + this.localAStar = new FastAStar(maxLocalNodes); + + // Multi-sector FastAStar for cross-sector pathfinding (same gateway, different sectors) + // 3×3 sectors: 96×96 = 9,216 nodes + const multiSectorSize = sectorSize * 3; + const maxMultiSectorNodes = multiSectorSize * multiSectorSize; + this.localAStarMultiSector = new FastAStar(maxMultiSectorNodes); + + this.initialized = true; + } + + findPath( + from: TileRef, + to: TileRef, + debug: boolean = false, + ): TileRef[] | null { + if (!this.initialized) { + throw new Error( + "NavMesh not initialized. Call initialize() before using findPath().", + ); + } + + if (debug) { + // Collect all edges with their paths for visualization + const allEdges: Array<{ + fromId: number; + toId: number; + from: TileRef; + to: TileRef; + cost: number; + path: TileRef[] | null; + }> = []; + + for (const [fromId, edges] of this.graph.edges.entries()) { + const fromGw = this.graph.getGateway(fromId); + if (!fromGw) continue; + + for (const edge of edges) { + const toGw = this.graph.getGateway(edge.to); + if (!toGw) continue; + + // Only add each edge once (not both directions) + // Include self-loops (fromId === edge.to) for debugging + if (fromId <= edge.to) { + allEdges.push({ + fromId: fromId, + toId: edge.to, + from: fromGw.tile, + to: toGw.tile, + cost: edge.cost, + path: edge.path ?? null, + }); + } + } + } + + this.debugInfo = { + gatewayPath: null, + initialPath: null, + smoothPath: null, + graph: { + sectorSize: this.graph.sectorSize, + gateways: this.graph + .getAllGateways() + .map((gw) => ({ id: gw.id, tile: gw.tile })), + edges: allEdges, + }, + timings: { + total: 0, + }, + }; + } + + const dist = this.game.manhattanDist(from, to); + + // Early exit for very short distances that fit within multi-sector range + if (dist <= this.graph.sectorSize) { + performance.mark("navsat:findPath:earlyExitLocalPath:start"); + const map = this.game.map(); + const startMiniX = Math.floor(map.x(from) / 2); + const startMiniY = Math.floor(map.y(from) / 2); + const sectorX = Math.floor(startMiniX / this.graph.sectorSize); + const sectorY = Math.floor(startMiniY / this.graph.sectorSize); + const localPath = this.findLocalPath( + from, + to, + sectorX, + sectorY, + 2000, + true, + ); + performance.mark("navsat:findPath:earlyExitLocalPath:end"); + const measure = performance.measure( + "navsat:findPath:earlyExitLocalPath", + "navsat:findPath:earlyExitLocalPath:start", + "navsat:findPath:earlyExitLocalPath:end", + ); + + if (debug) { + this.debugInfo!.timings.earlyExitLocalPath = measure.duration; + this.debugInfo!.timings.total += measure.duration; + } + + if (localPath) { + if (debug) { + console.log( + `[DEBUG] Direct local path found for dist=${dist}, length=${localPath.length}`, + ); + } + + return localPath; + } + + if (debug) { + console.log( + `[DEBUG] Direct path failed for dist=${dist}, falling back to gateway graph`, + ); + } + } + + performance.mark("navsat:findPath:findGateways:start"); + const startGateway = this.findNearestGateway(from); + const endGateway = this.findNearestGateway(to); + performance.mark("navsat:findPath:findGateways:end"); + const findGatewaysMeasure = performance.measure( + "navsat:findPath:findGateways", + "navsat:findPath:findGateways:start", + "navsat:findPath:findGateways:end", + ); + + if (debug) { + this.debugInfo!.timings.findGateways = findGatewaysMeasure.duration; + this.debugInfo!.timings.total += findGatewaysMeasure.duration; + } + + if (!startGateway) { + if (debug) { + console.log( + `[DEBUG] Cannot find start gateway for (${this.game.x(from)}, ${this.game.y(from)})`, + ); + } + + return null; + } + + if (!endGateway) { + if (debug) { + console.log( + `[DEBUG] Cannot find end gateway for (${this.game.x(to)}, ${this.game.y(to)})`, + ); + } + + return null; + } + + if (startGateway.id === endGateway.id) { + if (debug) { + console.log( + `[DEBUG] Start and end gateways are the same (ID=${startGateway.id}), finding local path with multi-sector search`, + ); + } + + performance.mark("navsat:findPath:sameGatewayLocalPath:start"); + const sectorX = Math.floor(startGateway.x / this.graph.sectorSize); + const sectorY = Math.floor(startGateway.y / this.graph.sectorSize); + const path = this.findLocalPath(from, to, sectorX, sectorY, 10000, true); + performance.mark("navsat:findPath:sameGatewayLocalPath:end"); + const sameGatewayMeasure = performance.measure( + "navsat:findPath:sameGatewayLocalPath", + "navsat:findPath:sameGatewayLocalPath:start", + "navsat:findPath:sameGatewayLocalPath:end", + ); + + if (debug) { + this.debugInfo!.timings.sameGatewayLocalPath = + sameGatewayMeasure.duration; + this.debugInfo!.timings.total += sameGatewayMeasure.duration; + } + + return path; + } + + performance.mark("navsat:findPath:findGatewayPath:start"); + const gatewayPath = this.findGatewayPath(startGateway.id, endGateway.id); + performance.mark("navsat:findPath:findGatewayPath:end"); + const findGatewayPathMeasure = performance.measure( + "navsat:findPath:findGatewayPath", + "navsat:findPath:findGatewayPath:start", + "navsat:findPath:findGatewayPath:end", + ); + + if (debug) { + this.debugInfo!.timings.findGatewayPath = findGatewayPathMeasure.duration; + this.debugInfo!.timings.total += findGatewayPathMeasure.duration; + + this.debugInfo!.gatewayPath = gatewayPath + ? gatewayPath + .map((gwId) => { + const gw = this.graph.getGateway(gwId); + return gw ? gw.tile : -1; + }) + .filter((tile) => tile !== -1) + : null; + } + + if (!gatewayPath) { + if (debug) { + console.log( + `[DEBUG] No gateway path between gateways ${startGateway.id} and ${endGateway.id}`, + ); + } + + return null; + } + + if (debug) { + console.log( + `[DEBUG] Gateway path found: ${gatewayPath.length} waypoints`, + ); + } + + const initialPath: TileRef[] = []; + const map = this.game.map(); + const miniMap = this.game.miniMap(); + + performance.mark("navsat:findPath:buildInitialPath:start"); + + // 1. Find path from start to first gateway + const firstGateway = this.graph.getGateway(gatewayPath[0])!; + const firstGatewayTile = map.ref( + miniMap.x(firstGateway.tile) * 2, + miniMap.y(firstGateway.tile) * 2, + ); + + // Use start position's sector with multi-sector search (gateway may be on border) + const startMiniX = Math.floor(map.x(from) / 2); + const startMiniY = Math.floor(map.y(from) / 2); + const startSectorX = Math.floor(startMiniX / this.graph.sectorSize); + const startSectorY = Math.floor(startMiniY / this.graph.sectorSize); + const startSegment = this.findLocalPath( + from, + firstGatewayTile, + startSectorX, + startSectorY, + ); + + if (!startSegment) { + return null; + } + + initialPath.push(...startSegment); + + // 2. Build path through gateways + for (let i = 0; i < gatewayPath.length - 1; i++) { + const fromGwId = gatewayPath[i]; + const toGwId = gatewayPath[i + 1]; + + const edges = this.graph.getEdges(fromGwId); + const edge = edges.find((edge) => edge.to === toGwId); + + if (!edge) { + return null; + } + + if (edge.path) { + // Use cached path if available + initialPath.push(...edge.path.slice(1)); + continue; + } + + const fromGw = this.graph.getGateway(fromGwId)!; + const toGw = this.graph.getGateway(toGwId)!; + const fromTile = map.ref( + miniMap.x(fromGw.tile) * 2, + miniMap.y(fromGw.tile) * 2, + ); + const toTile = map.ref( + miniMap.x(toGw.tile) * 2, + miniMap.y(toGw.tile) * 2, + ); + + const segmentPath = this.findLocalPath( + fromTile, + toTile, + edge.sectorX, + edge.sectorY, + ); + + if (!segmentPath) { + return null; + } + + // Skip first tile to avoid duplication + initialPath.push(...segmentPath.slice(1)); + + if (this.options.cachePaths) { + // Cache the path for future reuse on both directional edges + edge.path = segmentPath; + + // Also cache the reversed path on the opposite direction edge + const reverseEdges = this.graph.getEdges(toGwId); + const reverseEdge = reverseEdges.find((e) => e.to === fromGwId); + if (reverseEdge) { + reverseEdge.path = segmentPath.slice().reverse(); + } + } + } + + // 3. Find path from last gateway to end + const lastGateway = this.graph.getGateway( + gatewayPath[gatewayPath.length - 1], + )!; + const lastGatewayTile = map.ref( + miniMap.x(lastGateway.tile) * 2, + miniMap.y(lastGateway.tile) * 2, + ); + + // Use end position's sector with multi-sector search (gateway may be on border) + const endMiniX = Math.floor(map.x(to) / 2); + const endMiniY = Math.floor(map.y(to) / 2); + const endSectorX = Math.floor(endMiniX / this.graph.sectorSize); + const endSectorY = Math.floor(endMiniY / this.graph.sectorSize); + const endSegment = this.findLocalPath( + lastGatewayTile, + to, + endSectorX, + endSectorY, + ); + + if (!endSegment) { + return null; + } + + // Skip first tile to avoid duplication + initialPath.push(...endSegment.slice(1)); + + performance.mark("navsat:findPath:buildInitialPath:end"); + const buildInitialPathMeasure = performance.measure( + "navsat:findPath:buildInitialPath", + "navsat:findPath:buildInitialPath:start", + "navsat:findPath:buildInitialPath:end", + ); + + if (debug) { + this.debugInfo!.timings.buildInitialPath = + buildInitialPathMeasure.duration; + this.debugInfo!.timings.total += buildInitialPathMeasure.duration; + this.debugInfo!.initialPath = initialPath; + console.log(`[DEBUG] Initial path: ${initialPath.length} tiles`); + } + + performance.mark("navsat:findPath:smoothPath:start"); + const smoothedPath = this.smoothPath(initialPath); + performance.mark("navsat:findPath:smoothPath:end"); + const smoothPathMeasure = performance.measure( + "navsat:findPath:smoothPath", + "navsat:findPath:smoothPath:start", + "navsat:findPath:smoothPath:end", + ); + + if (debug) { + this.debugInfo!.timings.buildSmoothPath = smoothPathMeasure.duration; + this.debugInfo!.timings.total += smoothPathMeasure.duration; + this.debugInfo!.smoothPath = smoothedPath; + console.log( + `[DEBUG] Smoothed path: ${initialPath.length} → ${smoothedPath.length} tiles`, + ); + } + + return smoothedPath; + } + + private findNearestGateway(tile: TileRef): Gateway | null { + const map = this.game.map(); + const x = map.x(tile); + const y = map.y(tile); + + // Convert to miniMap coordinates + const miniMap = this.game.miniMap(); + const miniX = Math.floor(x / 2); + const miniY = Math.floor(y / 2); + const miniFrom = miniMap.ref(miniX, miniY); + + // Check gateways in the tile's own sector (using miniMap coordinates) + const sectorX = Math.floor(miniX / this.graph.sectorSize); + const sectorY = Math.floor(miniY / this.graph.sectorSize); + + // Calculate single sector bounds + const sectorSize = this.graph.sectorSize; + const minX = sectorX * sectorSize; + const minY = sectorY * sectorSize; + const maxX = Math.min(miniMap.width() - 1, minX + sectorSize - 1); + const maxY = Math.min(miniMap.height() - 1, minY + sectorSize - 1); + + // Get gateways from the tile's own sector only (includes border gateways) + const sector = this.graph.getSector(sectorX, sectorY); + + if (!sector) { + return null; + } + + const candidateGateways = sector.gateways; + if (candidateGateways.length === 0) { + return null; + } + + // Use BFS to find the nearest reachable gateway (by water path distance) + // Search space is bounded by sector bounds, so maxDistance can be large + const maxDistance = sectorSize * sectorSize; + + return this.fastBFS.search( + miniMap.width(), + miniMap.height(), + miniFrom, + maxDistance, + (tile: TileRef) => miniMap.isWater(tile), + (tile: TileRef, _dist: number) => { + const tileX = miniMap.x(tile); + const tileY = miniMap.y(tile); + + // Check if any candidate gateway is at this position first + for (const gateway of candidateGateways) { + if (gateway.x === tileX && gateway.y === tileY) { + return gateway; + } + } + + // Reject non-gateway tiles outside the sector bounds + if (tileX < minX || tileX > maxX || tileY < minY || tileY > maxY) { + return null; + } + }, + ); + } + + private findGatewayPath( + fromGatewayId: number, + toGatewayId: number, + ): number[] | null { + const adapter = new GatewayGraphAdapter(this.graph); + return this.gatewayAStar.search( + fromGatewayId, + toGatewayId, + adapter, + 100000, + ); + } + + private findLocalPath( + from: TileRef, + to: TileRef, + sectorX: number, + sectorY: number, + maxIterations: number = 10000, + multiSector: boolean = false, + ): TileRef[] | null { + const map = this.game.map(); + const miniMap = this.game.miniMap(); + + // Convert full map coordinates to miniMap coordinates + const miniFrom = miniMap.ref( + Math.floor(map.x(from) / 2), + Math.floor(map.y(from) / 2), + ); + + const miniTo = miniMap.ref( + Math.floor(map.x(to) / 2), + Math.floor(map.y(to) / 2), + ); + + // Calculate sector bounds + const sectorSize = this.graph.sectorSize; + + let minX: number; + let minY: number; + let maxX: number; + let maxY: number; + + if (multiSector) { + // 3×3 sectors centered on the starting sector + minX = Math.max(0, (sectorX - 1) * sectorSize); + minY = Math.max(0, (sectorY - 1) * sectorSize); + maxX = Math.min(miniMap.width() - 1, (sectorX + 2) * sectorSize - 1); + maxY = Math.min(miniMap.height() - 1, (sectorY + 2) * sectorSize - 1); + } else { + // Single sector + minX = sectorX * sectorSize; + minY = sectorY * sectorSize; + maxX = Math.min(miniMap.width() - 1, minX + sectorSize - 1); + maxY = Math.min(miniMap.height() - 1, minY + sectorSize - 1); + } + + const adapter = new BoundedGameMapAdapter(miniMap, miniFrom, miniTo, { + minX, + maxX, + minY, + maxY, + }); + + // Convert to local node IDs + const startNode = adapter.tileToNode(miniFrom); + const goalNode = adapter.tileToNode(miniTo); + + if (startNode === -1 || goalNode === -1) { + return null; // Start or goal outside bounds + } + + // Choose the appropriate FastAStar buffer based on search area + const selectedAStar = multiSector + ? this.localAStarMultiSector + : this.localAStar; + + // Run FastAStar on bounded region + const path = selectedAStar.search( + startNode, + goalNode, + adapter, + maxIterations, + ); + + if (!path) { + return null; + } + + // Convert path from local node IDs back to miniMap TileRefs + const miniPath = path.map((node: number) => adapter.nodeToTile(node)); + + // Upscale from miniMap to full map (same logic as MiniAStar) + const result = this.upscalePathToFullMap(miniPath, from, to); + + return result; + } + + private upscalePathToFullMap( + miniPath: TileRef[], + from: TileRef, + to: TileRef, + ): TileRef[] { + const map = this.game.map(); + const miniMap = this.game.miniMap(); + + // Convert miniMap path to cells + const miniCells = miniPath.map((tile) => ({ + x: miniMap.x(tile), + y: miniMap.y(tile), + })); + + // FIRST: Scale all points (2x) + const scaledPath = miniCells.map((point) => ({ + x: point.x * 2, + y: point.y * 2, + })); + + // SECOND: Interpolate between scaled points + const smoothPath: Array<{ x: number; y: number }> = []; + for (let i = 0; i < scaledPath.length - 1; i++) { + const current = scaledPath[i]; + const next = scaledPath[i + 1]; + + // Add the current point + smoothPath.push(current); + + // Calculate dx/dy from SCALED coordinates + const dx = next.x - current.x; + const dy = next.y - current.y; + const distance = Math.max(Math.abs(dx), Math.abs(dy)); + const steps = distance; + + // Add intermediate points + for (let step = 1; step < steps; step++) { + smoothPath.push({ + x: Math.round(current.x + (dx * step) / steps), + y: Math.round(current.y + (dy * step) / steps), + }); + } + } + + // Add last point + if (scaledPath.length > 0) { + smoothPath.push(scaledPath[scaledPath.length - 1]); + } + + const scaledCells = smoothPath; + + // Fix extremes to ensure exact start/end + const fromCell = { x: map.x(from), y: map.y(from) }; + const toCell = { x: map.x(to), y: map.y(to) }; + + // Ensure start is correct + const startIdx = scaledCells.findIndex( + (c) => c.x === fromCell.x && c.y === fromCell.y, + ); + if (startIdx === -1) { + scaledCells.unshift(fromCell); + } else if (startIdx !== 0) { + scaledCells.splice(0, startIdx); + } + + // Ensure end is correct + const endIdx = scaledCells.findIndex( + (c) => c.x === toCell.x && c.y === toCell.y, + ); + if (endIdx === -1) { + scaledCells.push(toCell); + } else if (endIdx !== scaledCells.length - 1) { + scaledCells.splice(endIdx + 1); + } + + // Convert back to TileRefs + return scaledCells.map((cell) => map.ref(cell.x, cell.y)); + } + + private tracePath(from: TileRef, to: TileRef): TileRef[] | null { + const x0 = this.game.x(from); + const y0 = this.game.y(from); + const x1 = this.game.x(to); + const y1 = this.game.y(to); + + const tiles: TileRef[] = []; + + // Bresenham's line algorithm - trace and collect all tiles + const dx = Math.abs(x1 - x0); + const dy = Math.abs(y1 - y0); + const sx = x0 < x1 ? 1 : -1; + const sy = y0 < y1 ? 1 : -1; + let err = dx - dy; + + let x = x0; + let y = y0; + + // Safety limit to prevent excessive memory allocation + const maxTiles = 100000; + let iterations = 0; + + while (true) { + if (iterations++ > maxTiles) { + return null; // Path too long + } + const tile = this.game.ref(x, y); + if (!this.game.isWater(tile)) { + return null; // Path blocked + } + + tiles.push(tile); + + if (x === x1 && y === y1) { + break; + } + + const e2 = 2 * err; + const shouldMoveX = e2 > -dy; + const shouldMoveY = e2 < dx; + + if (shouldMoveX && shouldMoveY) { + // Diagonal move - need to expand into two 4-directional moves + // Try moving X first, then Y + x += sx; + err -= dy; + + const intermediateTile = this.game.ref(x, y); + if (!this.game.isWater(intermediateTile)) { + // X first doesn't work, try Y first instead + x -= sx; // undo + err += dy; // undo + + y += sy; + err += dx; + + const altTile = this.game.ref(x, y); + if (!this.game.isWater(altTile)) { + return null; // Neither direction works + } + tiles.push(altTile); + + // Now move X + x += sx; + err -= dy; + } else { + tiles.push(intermediateTile); + + // Now move Y + y += sy; + err += dx; + } + } else { + // Single-axis move + if (shouldMoveX) { + x += sx; + err -= dy; + } + + if (shouldMoveY) { + y += sy; + err += dx; + } + } + } + + return tiles; + } + + private smoothPath(path: TileRef[]): TileRef[] { + if (path.length <= 2) { + return path; + } + + const smoothed: TileRef[] = []; + let current = 0; + + while (current < path.length - 1) { + // Look as far ahead as possible while maintaining line of sight + let farthest = current + 1; + let bestTrace: TileRef[] | null = null; + + for ( + let i = current + 2; + i < path.length; + i += Math.max(1, Math.floor(path.length / 20)) + ) { + const trace = this.tracePath(path[current], path[i]); + + if (trace !== null) { + farthest = i; + bestTrace = trace; + } else { + break; + } + } + + // Also try the final tile if we haven't already + if ( + farthest < path.length - 1 && + (path.length - 1 - current) % 10 !== 0 + ) { + const trace = this.tracePath(path[current], path[path.length - 1]); + if (trace !== null) { + farthest = path.length - 1; + bestTrace = trace; + } + } + + // Add the traced path (or just current tile if no improvement) + if (bestTrace !== null && farthest > current + 1) { + // Add all tiles from the trace except the last one (to avoid duplication) + smoothed.push(...bestTrace.slice(0, -1)); + } else { + // No LOS improvement, just add current tile + smoothed.push(path[current]); + } + + current = farthest; + } + + // Add the final tile + smoothed.push(path[path.length - 1]); + + return smoothed; + } +} diff --git a/src/core/pathfinding/navmesh/WaterComponents.ts b/src/core/pathfinding/navmesh/WaterComponents.ts new file mode 100644 index 000000000..e58cdf96f --- /dev/null +++ b/src/core/pathfinding/navmesh/WaterComponents.ts @@ -0,0 +1,200 @@ +import { GameMap, TileRef } from "../../game/GameMap"; + +const LAND_MARKER = 0xff; // Must fit in Uint8Array + +/** + * Manages water component identification using flood-fill. + * Pre-allocates buffers and provides explicit initialization. + */ +export class WaterComponents { + private readonly width: number; + private readonly height: number; + private readonly numTiles: number; + private readonly lastRowStart: number; + private readonly queue: Int32Array; + private componentIds: Uint8Array | Uint16Array | null = null; + + constructor( + private readonly map: GameMap, + private readonly accessTerrainDirectly: boolean = true, + ) { + this.width = map.width(); + this.height = map.height(); + this.numTiles = this.width * this.height; + this.lastRowStart = (this.height - 1) * this.width; + this.queue = new Int32Array(this.numTiles); + } + + initialize(): void { + let ids: Uint8Array | Uint16Array = this.createPrefilledIds(); + + let nextId = 0; + + // Scan all tiles and flood-fill each unvisited water component + for (let start = 0; start < this.numTiles; start++) { + const value = ids[start]; + + // Skip if already visited (land=0xFF or water component >0) + if (value === LAND_MARKER || value > 0) { + continue; + } + + nextId++; + + // Dynamically upgrade to Uint16Array when we hit component 254 + if (nextId === 254 && ids instanceof Uint8Array) { + ids = this.upgradeToUint16Array(ids); + } + + this.floodFillComponent(ids, start, nextId); + } + + this.componentIds = ids; + } + + /** + * Create and prefill a Uint8Array with land markers. + * Uses direct terrain access for performance. + */ + private createPrefilledIds(): Uint8Array { + const ids = new Uint8Array(this.numTiles); + + if (this.accessTerrainDirectly) { + this.premarkLandTilesDirect(ids); + } else { + this.premarkLandTiles(ids); + } + + return ids; + } + + /** + * Pre-mark all land tiles in the ids array. + * Land tiles are marked with 0xFF, water tiles remain 0. + */ + private premarkLandTiles(ids: Uint8Array): void { + for (let i = 0; i < this.numTiles; i++) { + ids[i] = this.map.isWater(i) ? 0 : LAND_MARKER; + } + } + + /** + * Pre-mark all land tiles in the ids array. + * Land tiles are marked with 0xFF, water tiles remain 0. + * + * This implementation accesses the terrain data **directly** without GameMap abstraction. + * In tests it is 30% to 50% faster than using isWater() method calls. + * As of 2026-01-05 it reduces avg. time for GWM from 15ms to 10ms. + */ + private premarkLandTilesDirect(ids: Uint8Array): void { + const terrain = (this.map as any).terrain as Uint8Array; + + // Write 4 bytes at once using Uint32Array view for better performance + const numChunks = Math.floor(this.numTiles / 4); + const terrain32 = new Uint32Array( + terrain.buffer, + terrain.byteOffset, + numChunks, + ); + const ids32 = new Uint32Array(ids.buffer, ids.byteOffset, numChunks); + + for (let i = 0; i < numChunks; i++) { + const chunk = terrain32[i]; + + // Extract bit 7 from each byte, negate, and combine into single 32-bit write + // bit 7 = 0 (water) → -(0) = 0x00 + // bit 7 = 1 (land) → -(1) = 0xFF (truncated to 8 bits) + const b0 = -((chunk >> 7) & 1) & 0xff; + const b1 = -((chunk >> 15) & 1) & 0xff; + const b2 = -((chunk >> 23) & 1) & 0xff; + const b3 = -((chunk >> 31) & 1); // Upper byte, no mask needed + + ids32[i] = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); + } + + // Handle remaining tiles (when numTiles not divisible by 4) + for (let i = numChunks * 4; i < this.numTiles; i++) { + ids[i] = -(terrain[i] >> 7); + } + } + + /** + * Upgrade from Uint8Array to Uint16Array when we exceed 254 components. + * Direct copy works because both use 0xFF for land marker. + */ + private upgradeToUint16Array(ids: Uint8Array): Uint16Array { + const newIds = new Uint16Array(this.numTiles); + for (let i = 0; i < this.numTiles; i++) { + newIds[i] = ids[i]; + } + return newIds; + } + + /** + * Flood-fill a single connected water component using scan-line algorithm. + * Processes horizontal spans of tiles for better memory locality and cache performance. + * + * Note: Land tiles are pre-marked, so ids[x] === 0 guarantees water tile. + */ + private floodFillComponent( + ids: Uint8Array | Uint16Array, + start: number, + componentId: number, + ): void { + let head = 0; + let tail = 0; + this.queue[tail++] = start; + + while (head < tail) { + const seed = this.queue[head++]!; + + // Skip if already processed + if (ids[seed] !== 0) continue; + + // Scan left to find the start of this horizontal water span + // No isWaterFast check needed - ids[x] === 0 guarantees water + let left = seed; + const rowStart = seed - (seed % this.width); + while (left > rowStart && ids[left - 1] === 0) { + left--; + } + + // Scan right to find the end of this horizontal water span + let right = seed; + const rowEnd = rowStart + this.width - 1; + while (right < rowEnd && ids[right + 1] === 0) { + right++; + } + + // Fill the entire horizontal span and check above/below for new spans + for (let x = left; x <= right; x++) { + ids[x] = componentId; + + // Check tile above (if not in first row) + if (x >= this.width) { + const above = x - this.width; + if (ids[above] === 0) { + this.queue[tail++] = above; + } + } + + // Check tile below (if not in last row) + if (x < this.lastRowStart) { + const below = x + this.width; + if (ids[below] === 0) { + this.queue[tail++] = below; + } + } + } + } + } + + /** + * Get the component ID for a tile. + * Returns 0 for land tiles or if not initialized. + */ + getComponentId(tile: TileRef): number { + if (!this.componentIds) return 0; + return this.componentIds[tile] ?? 0; + } +} diff --git a/tests/core/executions/TradeShipExecution.test.ts b/tests/core/executions/TradeShipExecution.test.ts new file mode 100644 index 000000000..2ea187a51 --- /dev/null +++ b/tests/core/executions/TradeShipExecution.test.ts @@ -0,0 +1,125 @@ +import { TradeShipExecution } from "../../../src/core/execution/TradeShipExecution"; +import { Game, Player, Unit } from "../../../src/core/game/Game"; +import { PathStatus } from "../../../src/core/pathfinding/PathFinder"; +import { setup } from "../../util/Setup"; + +describe("TradeShipExecution", () => { + let game: Game; + let origOwner: Player; + let dstOwner: Player; + let pirate: Player; + let srcPort: Unit; + let piratePort: Unit; + let tradeShip: Unit; + let dstPort: Unit; + let tradeShipExecution: TradeShipExecution; + + beforeEach(async () => { + // Mock Game, Player, Unit, and required methods + + game = await setup("ocean_and_land", { + infiniteGold: true, + instantBuild: true, + }); + game.displayMessage = jest.fn(); + origOwner = { + canBuild: jest.fn(() => true), + buildUnit: jest.fn((type, spawn, opts) => tradeShip), + displayName: jest.fn(() => "Origin"), + addGold: jest.fn(), + units: jest.fn(() => [dstPort]), + unitCount: jest.fn(() => 1), + id: jest.fn(() => 1), + clientID: jest.fn(() => 1), + canTrade: jest.fn(() => true), + } as any; + + dstOwner = { + id: jest.fn(() => 2), + addGold: jest.fn(), + displayName: jest.fn(() => "Destination"), + units: jest.fn(() => [dstPort]), + unitCount: jest.fn(() => 1), + clientID: jest.fn(() => 2), + canTrade: jest.fn(() => true), + } as any; + + pirate = { + id: jest.fn(() => 3), + addGold: jest.fn(), + displayName: jest.fn(() => "Destination"), + units: jest.fn(() => [piratePort]), + unitCount: jest.fn(() => 1), + canTrade: jest.fn(() => true), + } as any; + + piratePort = { + tile: jest.fn(() => 40011), + owner: jest.fn(() => pirate), + isActive: jest.fn(() => true), + } as any; + + srcPort = { + tile: jest.fn(() => 20011), + owner: jest.fn(() => origOwner), + isActive: jest.fn(() => true), + } as any; + + dstPort = { + tile: jest.fn(() => 30015), // 15x15 + owner: jest.fn(() => dstOwner), + isActive: jest.fn(() => true), + } as any; + + tradeShip = { + isActive: jest.fn(() => true), + owner: jest.fn(() => origOwner), + move: jest.fn(), + setTargetUnit: jest.fn(), + setSafeFromPirates: jest.fn(), + delete: jest.fn(), + tile: jest.fn(() => 2001), + } as any; + + tradeShipExecution = new TradeShipExecution(origOwner, srcPort, dstPort); + tradeShipExecution.init(game, 0); + tradeShipExecution["pathFinder"] = { + next: jest.fn(() => ({ status: PathStatus.NEXT, node: 2001 })), + } as any; + tradeShipExecution["tradeShip"] = tradeShip; + }); + + it("should initialize and tick without errors", () => { + tradeShipExecution.tick(1); + expect(tradeShipExecution.isActive()).toBe(true); + }); + + it("should deactivate if tradeShip is not active", () => { + tradeShip.isActive = jest.fn(() => false); + tradeShipExecution.tick(1); + expect(tradeShipExecution.isActive()).toBe(false); + }); + + it("should delete ship if port owner changes to current owner", () => { + dstPort.owner = jest.fn(() => origOwner); + tradeShipExecution.tick(1); + expect(tradeShip.delete).toHaveBeenCalledWith(false); + expect(tradeShipExecution.isActive()).toBe(false); + }); + + it("should pick another port if ship is captured", () => { + tradeShip.owner = jest.fn(() => pirate); + tradeShipExecution.tick(1); + expect(tradeShip.setTargetUnit).toHaveBeenCalledWith(piratePort); + }); + + it("should complete trade and award gold", () => { + tradeShipExecution["pathFinder"] = { + next: jest.fn(() => ({ status: PathStatus.COMPLETE, node: 2001 })), + } as any; + tradeShipExecution.tick(1); + expect(tradeShip.delete).toHaveBeenCalledWith(false); + expect(tradeShipExecution.isActive()).toBe(false); + expect(game.displayMessage).toHaveBeenCalled(); + }); +}); diff --git a/tests/core/pathfinding/PathFinder.test.ts b/tests/core/pathfinding/PathFinder.test.ts new file mode 100644 index 000000000..2c13486f8 --- /dev/null +++ b/tests/core/pathfinding/PathFinder.test.ts @@ -0,0 +1,332 @@ +import { Game } from "../../../src/core/game/Game"; +import { TileRef } from "../../../src/core/game/GameMap"; +import { MiniAStarAdapter } from "../../../src/core/pathfinding/adapters/MiniAStarAdapter"; +import { NavMeshAdapter } from "../../../src/core/pathfinding/adapters/NavMeshAdapter"; +import { + PathFinder, + PathStatus, +} from "../../../src/core/pathfinding/PathFinder"; +import { setup } from "../../util/Setup"; +import { gameFromString } from "./utils"; + +type AdapterFactory = { + name: string; + create: (game: Game) => PathFinder; +}; + +const adapters: AdapterFactory[] = [ + { + name: "MiniAStarAdapter", + create: (game) => new MiniAStarAdapter(game, { waterPath: true }), + }, + { + name: "NavMeshAdapter", + create: (game) => new NavMeshAdapter(game), + }, +]; + +// Shared world game instance +let worldGame: Game; + +beforeAll(async () => { + worldGame = await setup("world", { disableNavMesh: false }); +}); + +describe.each(adapters)("$name", ({ create }) => { + describe("findPath()", () => { + test("finds path between adjacent tiles", async () => { + const game = await gameFromString(["WWWW"]); + const adapter = create(game); + const src = game.ref(0, 0); + const dst = game.ref(1, 0); + + const path = adapter.findPath(src, dst); + + expect(path).not.toBeNull(); + expect(path![0]).toBe(src); + expect(path![path!.length - 1]).toBe(dst); + }); + + test("finds path across multiple tiles", async () => { + const game = await gameFromString(["WWWWWW", "WWWWWW", "WWWWWW"]); + const adapter = create(game); + const src = game.ref(0, 0); + const dst = game.ref(5, 2); + + const path = adapter.findPath(src, dst); + + expect(path).not.toBeNull(); + expect(path![0]).toBe(src); + expect(path![path!.length - 1]).toBe(dst); + }); + + test("returns single-element path for same tile", async () => { + // Old quirk of MiniAStar, we return dst tile twice + // Should probably be fixed to return [] instead + + const game = await gameFromString(["WW"]); + const adapter = create(game); + const tile = game.ref(0, 0); + + const path = adapter.findPath(tile, tile); + + expect(path).not.toBeNull(); + expect(path!.length).toBe(1); + expect(path![0]).toBe(tile); + }); + + test("returns null for blocked path", async () => { + const game = await gameFromString(["WWLLWW"]); + const adapter = create(game); + const src = game.ref(0, 0); + const dst = game.ref(5, 0); + + const path = adapter.findPath(src, dst); + + expect(path).toBeNull(); + }); + + test("returns null for water to land", () => { + const adapter = create(worldGame); + const src = worldGame.ref(926, 283); // water + const dst = worldGame.ref(950, 230); // land + + const path = adapter.findPath(src, dst); + + expect(path).toBeNull(); + }); + + test("traverses 3-tile path in 3 tiles", async () => { + // Expected: [1, 2, 3] + const game = await gameFromString(["WWWW"]); + const adapter = create(game); + const src = game.ref(0, 0); + const dst = game.ref(3, 0); + + const path = adapter.findPath(src, dst); + + expect(path).not.toBeNull(); + expect(path).toEqual([ + game.ref(0, 0), + game.ref(1, 0), + game.ref(2, 0), + game.ref(3, 0), + ]); + }); + }); + + describe("next() state machine", () => { + test("returns NEXT on first call", async () => { + const game = await gameFromString(["WWWW"]); + const adapter = create(game); + const src = game.ref(0, 0); + const dst = game.ref(3, 0); + + const result = adapter.next(src, dst); + + expect(result.status).toBe(PathStatus.NEXT); + }); + + test("returns COMPLETE when at destination", async () => { + const game = await gameFromString(["WW"]); + const adapter = create(game); + const tile = game.ref(0, 0); + + const result = adapter.next(tile, tile); + + expect(result.status).toBe(PathStatus.COMPLETE); + }); + + test("returns NOT_FOUND for blocked path", async () => { + const game = await gameFromString(["WWLLWW"]); + const adapter = create(game); + const src = game.ref(0, 0); + const dst = game.ref(5, 0); + + const result = adapter.next(src, dst); + + expect(result.status).toBe(PathStatus.NOT_FOUND); + }); + + test("traverses 3-tile path in 4 calls", async () => { + // Expected: NEXT(1) -> NEXT(2) -> NEXT(3) -> COMPLETE(4) + const game = await gameFromString(["WWWW"]); + const adapter = create(game); + const src = game.ref(0, 0); + const dst = game.ref(3, 0); + + let current = src; + const steps: string[] = []; + + // 3 NEXT calls to reach destination + for (let i = 1; i <= 4; i++) { + const result = adapter.next(current, dst); + expect([PathStatus.NEXT, PathStatus.COMPLETE]).toContain(result.status); + + current = (result as { node: TileRef }).node; + steps.push(`${PathStatus[result.status]}(${current})`); + } + + expect(steps).toEqual(["NEXT(1)", "NEXT(2)", "NEXT(3)", "COMPLETE(3)"]); + }); + }); + + describe("Destination changes", () => { + test("reaches new destination when dest changes", async () => { + const game = await gameFromString(["WWWWWWWW"]); // 8 wide + const adapter = create(game); + const src = game.ref(0, 0); + const dst1 = game.ref(4, 0); + const dst2 = game.ref(7, 0); + + // First path exists + expect(adapter.findPath(src, dst1)).not.toBeNull(); + + // Can still find path to new destination + expect(adapter.findPath(dst1, dst2)).not.toBeNull(); + }); + + test("recomputes when destination changes mid-path", async () => { + const game = await gameFromString(["WWWWWWWWWWWWWWWWWWWW"]); // 20 wide + const adapter = create(game); + const src = game.ref(0, 0); + const dst1 = game.ref(10, 0); + const dst2 = game.ref(19, 0); + + // Start pathing to dst1, take one step + const result1 = adapter.next(src, dst1); + expect(result1.status).toBe(PathStatus.NEXT); + + // Change destination mid-path, continue from current position + let current = (result1 as { node: TileRef }).node; + let result = adapter.next(current, dst2); + for (let i = 0; i < 100 && result.status === PathStatus.NEXT; i++) { + current = (result as { node: TileRef }).node; + result = adapter.next(current, dst2); + } + + expect(result.status).toBe(PathStatus.COMPLETE); + expect(current).toBe(dst2); + }); + }); + + describe("Error handling", () => { + // MiniAStar logs console error when nulls passed, muted in test + + test("returns NOT_FOUND for null source", async () => { + const game = await gameFromString(["WWWW"]); + const adapter = create(game); + const dst = game.ref(0, 0); + + const consoleSpy = jest + .spyOn(console, "error") + .mockImplementation(() => {}); + const result = adapter.next(null as unknown as TileRef, dst); + expect(result.status).toBe(PathStatus.NOT_FOUND); + consoleSpy.mockRestore(); + }); + + test("returns NOT_FOUND for null destination", async () => { + const game = await gameFromString(["WWWW"]); + const adapter = create(game); + const src = game.ref(0, 0); + + const consoleSpy = jest + .spyOn(console, "error") + .mockImplementation(() => {}); + const result = adapter.next(src, null as unknown as TileRef); + expect(result.status).toBe(PathStatus.NOT_FOUND); + consoleSpy.mockRestore(); + }); + }); + + describe("dist parameter", () => { + test("returns COMPLETE when within dist", () => { + const adapter = create(worldGame); + const src = worldGame.ref(926, 283); + const dst = worldGame.ref(928, 283); // 2 tiles away + + const result = adapter.next(src, dst, 5); + + expect(result.status).toBe(PathStatus.COMPLETE); + }); + + test("returns NEXT when beyond dist", () => { + const adapter = create(worldGame); + const src = worldGame.ref(926, 283); + const dst = worldGame.ref(950, 257); + + // Adapter may need a few ticks to compute path + let result = adapter.next(src, dst, 5); + for (let i = 0; i < 100 && result.status === PathStatus.PENDING; i++) { + result = adapter.next(src, dst, 5); + } + + expect(result.status).toBe(PathStatus.NEXT); + }); + }); + + describe("World map routes", () => { + test("Spain to France (Mediterranean)", () => { + const adapter = create(worldGame); + const path = adapter.findPath( + worldGame.ref(926, 283), + worldGame.ref(950, 257), + ); + expect(path).not.toBeNull(); + }); + + test("Miami to Rio (Atlantic)", () => { + const adapter = create(worldGame); + const path = adapter.findPath( + worldGame.ref(488, 355), + worldGame.ref(680, 658), + ); + expect(path).not.toBeNull(); + expect(path!.length).toBeGreaterThan(100); + }); + + test("France to Poland (around Europe)", () => { + const adapter = create(worldGame); + const path = adapter.findPath( + worldGame.ref(950, 257), + worldGame.ref(1033, 175), + ); + expect(path).not.toBeNull(); + }); + + test("Miami to Spain (transatlantic)", () => { + const adapter = create(worldGame); + const path = adapter.findPath( + worldGame.ref(488, 355), + worldGame.ref(926, 283), + ); + expect(path).not.toBeNull(); + }); + + test("Rio to Poland (South Atlantic to Baltic)", () => { + const adapter = create(worldGame); + const path = adapter.findPath( + worldGame.ref(680, 658), + worldGame.ref(1033, 175), + ); + expect(path).not.toBeNull(); + }); + }); + + describe("Known bugs", () => { + test("path can cross 1-tile land barrier", async () => { + const game = await gameFromString(["WLLWLWWLLW"]); + const adapter = create(game); + const path = adapter.findPath(game.ref(0, 0), game.ref(9, 0)); + expect(path).not.toBeNull(); + }); + + test("path can cross diagonal land barrier", async () => { + const game = await gameFromString(["WL", "LW"]); + const adapter = create(game); + const path = adapter.findPath(game.ref(0, 0), game.ref(1, 1)); + expect(path).not.toBeNull(); + }); + }); +}); diff --git a/tests/core/pathfinding/utils.ts b/tests/core/pathfinding/utils.ts new file mode 100644 index 000000000..c7fbd1741 --- /dev/null +++ b/tests/core/pathfinding/utils.ts @@ -0,0 +1,135 @@ +import { + Difficulty, + Game, + GameMapType, + GameMode, + GameType, +} from "../../../src/core/game/Game"; +import { createGame } from "../../../src/core/game/GameImpl"; +import { GameMapImpl } from "../../../src/core/game/GameMap"; +import { UserSettings } from "../../../src/core/game/UserSettings"; +import { PeaceTimerDuration } from "../../../src/core/Schemas"; +import { TestConfig } from "../../util/TestConfig"; +import { TestServerConfig } from "../../util/TestServerConfig"; + +const LAND_BIT = 7; +const OCEAN_BIT = 5; + +/** + * Creates a Game from inline map strings. + * Each char = 1 tile: W=water (ocean), L=land + * miniMap automatically generated (2x2→1, water if ANY tile water) + * + * Example: + * const game = await gameFromString([ + * 'WWWWW', + * 'WLLLW', + * 'WWWWW' + * ]); + */ +export async function gameFromString(mapRows: string[]): Promise { + const height = mapRows.length; + const width = mapRows[0].length; + + for (const row of mapRows) { + if (row.length !== width) { + throw new Error( + `All rows must have same width. Expected ${width}, got ${row.length}`, + ); + } + } + + const terrainData = new Uint8Array(width * height); + let numLandTiles = 0; + + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + const idx = y * width + x; + const char = mapRows[y][x]; + + if (char === "L") { + terrainData[idx] = 1 << LAND_BIT; // Set land bit + numLandTiles++; + } else if (char === "W") { + terrainData[idx] = 1 << OCEAN_BIT; // Set ocean bit (water) + } else { + throw new Error( + `Unknown char '${char}' at (${x},${y}). Use W=water, L=land`, + ); + } + } + } + + const gameMap = new GameMapImpl(width, height, terrainData, numLandTiles); + + // Create miniMap (2x2→1, water if ANY tile water) + const miniWidth = Math.ceil(width / 2); + const miniHeight = Math.ceil(height / 2); + const miniTerrainData = new Uint8Array(miniWidth * miniHeight); + let miniNumLandTiles = 0; + + for (let miniY = 0; miniY < miniHeight; miniY++) { + for (let miniX = 0; miniX < miniWidth; miniX++) { + const miniIdx = miniY * miniWidth + miniX; + + // Check 2x2 chunk: if ANY tile is water, miniMap tile is water + let water = false; + + for (let dy = 0; dy < 2; dy++) { + for (let dx = 0; dx < 2; dx++) { + const x = miniX * 2 + dx; + const y = miniY * 2 + dy; + + if (x < width && y < height) { + const idx = y * width + x; + if (!(terrainData[idx] & (1 << LAND_BIT))) { + water = true; + } + } + } + } + + // Water if ANY tile is water + if (water) { + miniTerrainData[miniIdx] = 1 << OCEAN_BIT; // ocean + } else { + miniTerrainData[miniIdx] = 1 << LAND_BIT; // land + miniNumLandTiles++; + } + } + } + + const miniGameMap = new GameMapImpl( + miniWidth, + miniHeight, + miniTerrainData, + miniNumLandTiles, + ); + + // Create game config + const serverConfig = new TestServerConfig(); + const gameConfig = { + gameMap: GameMapType.Asia, + gameMode: GameMode.FFA, + gameType: GameType.Singleplayer, + difficulty: Difficulty.Medium, + disableNPCs: false, + bots: 0, + infiniteGold: false, + infiniteTroops: false, + instantBuild: false, + disableNavMesh: false, + peaceTimerDurationMinutes: PeaceTimerDuration.None, + startingGold: 0 as const, + goldMultiplier: 1 as const, + chatEnabled: false, + }; + const config = new TestConfig( + serverConfig, + gameConfig, + new UserSettings(), + false, + ); + + return createGame([], [], gameMap, miniGameMap, config); +} diff --git a/tests/pathfinding/README.md b/tests/pathfinding/README.md new file mode 100644 index 000000000..b0587aa00 --- /dev/null +++ b/tests/pathfinding/README.md @@ -0,0 +1,152 @@ +# Pathfinding Tests + +This directory contains benchmarking tools, scenario generators, and an interactive playground for testing and optimizing pathfinding algorithms in OpenFrontIO. + +## TLDR + +```bash +npx tsx tests/pathfinding/benchmark/run.ts --synthetic --all +npx tsx tests/pathfinding/playground/server.ts +``` + +## Directory Structure + +``` +tests/pathfinding/ +├── benchmark.ts # Benchmarking tool +├── scenarios/ # Scenarios for benchmarks +│ ├── default.ts # Hand-picked scenario +│ └── synthetic/ # Auto-generated synthetic scenarios +└── playground/ # Interactive web-based visualization +``` + +## Available algorithms + +- **NavSat** - **future** implementation - NavigationSatellite (HPA\*) +- **PF.Mini** - **current** implementation - PathFinder.Mini (A\*) + +## Benchmarking + +### Running a Single Scenario + +```bash +# Run default scenario with default adapter (NavSat) +npx tsx tests/pathfinding/benchmark/run.ts + +# Run specific scenario +npx tsx tests/pathfinding/benchmark/run.ts default + +# Run with specific adapter +npx tsx tests/pathfinding/benchmark/run.ts default legacy +``` + +### Running Synthetic Scenarios + +Synthetic scenarios are auto-generated from maps with random port selections and routes. + +```bash +# Run single synthetic scenario +npx tsx tests/pathfinding/benchmark/run.ts --synthetic iceland + +# Run single synthetic scenario with specific adapter +npx tsx tests/pathfinding/benchmark/run.ts --synthetic iceland legacy + +# Run ALL synthetic scenarios (comprehensive benchmark) +npx tsx tests/pathfinding/benchmark/run.ts --synthetic --all + +# Run all with specific adapter +npx tsx tests/pathfinding/benchmark/run.ts --synthetic --all legacy +``` + +### Benchmark Metrics + +The benchmark measures three key metrics: + +1. **Initialization Time** - How long it takes to preprocess the map +2. **Path Distance** - Total distance across all routes (quality metric) +3. **Pathfinding Time** - How long it takes to compute paths (performance metric) + +### Example Output + +``` +================================================================================ +METRIC 1: INITIALIZATION TIME +================================================================================ + +Initialization time: 45.32ms + +================================================================================ +METRIC 2: PATH DISTANCE +================================================================================ + +Route Path Length +Miami → Boston 346 tiles +Miami → Houston 212 tiles +... + +Total distance: 52432 tiles +Routes completed: 22 / 22 + +================================================================================ +METRIC 3: PATHFINDING TIME +================================================================================ + +Route Time +Miami → Boston 2.45ms +Miami → Houston 1.82ms +... + +Total time: 156.34ms +Average time: 7.11ms +Routes benchmarked: 22 / 22 + +================================================================================ +SUMMARY +================================================================================ + +Adapter: default +Scenario: default + +Scores: + Initialization: 45.32ms + Pathfinding: 156.34ms + Distance: 52432 tiles +``` + +## Generating Scenarios + +### Generate Synthetic Scenarios + +Synthetic scenarios are generated by: + +1. Finding all water shoreline tiles on a map +2. Randomly selecting 200 ports +3. Creating 1000 routes connecting nearby ports + +```bash +# Generate scenario for a single map +npx tsx tests/pathfinding/benchmark/generate.ts iceland + +# Generate scenarios for all maps +npx tsx tests/pathfinding/benchmark/generate.ts --all + +# Force overwrite existing scenarios +npx tsx tests/pathfinding/benchmark/generate.ts iceland --force +npx tsx tests/pathfinding/benchmark/generate.ts --all --force +``` + +## Interactive Playground + +The playground provides a web-based UI for visualizing pathfinding results, comparing algorithms, and debugging. + +### Starting the Playground + +```bash +# Start with path caching enabled (default) +npx tsx tests/pathfinding/playground/server.ts + +# Start without path caching (to measure uncached performance) +npx tsx tests/pathfinding/playground/server.ts --no-cache +``` + +Then open http://localhost:5555 in your browser. diff --git a/tests/pathfinding/benchmark/generate.ts b/tests/pathfinding/benchmark/generate.ts new file mode 100644 index 000000000..97d452504 --- /dev/null +++ b/tests/pathfinding/benchmark/generate.ts @@ -0,0 +1,310 @@ +#!/usr/bin/env node + +/** + * Generate synthetic benchmark scenarios for pathfinding tests + * + * Usage: + * npx tsx tests/pathfinding/benchmark/generate.ts [--force] + * npx tsx tests/pathfinding/benchmark/generate.ts --all [--force] + * + * Examples: + * npx tsx tests/pathfinding/benchmark/generate.ts iceland + * npx tsx tests/pathfinding/benchmark/generate.ts giantworldmap --force + * npx tsx tests/pathfinding/benchmark/generate.ts --all + */ + +import { existsSync, mkdirSync, readdirSync, writeFileSync } from "fs"; +import { dirname, join } from "path"; +import { fileURLToPath } from "url"; +import { setupFromPath } from "../utils"; + +const currentFile = fileURLToPath(import.meta.url); +const pathfindingDir = dirname(currentFile); +const projectRoot = join(pathfindingDir, "../../.."); +const mapsDirectory = join(projectRoot, "resources/maps"); +const scenariosDir = join(pathfindingDir, "scenarios", "synthetic"); + +const NUM_PORTS = 200; +const NUM_ROUTES = 1000; +const ROUTES_PER_PORT = 5; + +interface GenerationOptions { + force: boolean; + silent: boolean; +} + +async function generateScenarioForMap( + mapName: string, + options: GenerationOptions, +): Promise<"created" | "skipped" | "error"> { + const outputPath = join(scenariosDir, `${mapName}.ts`); + + // Check if file exists and --force not provided + if (existsSync(outputPath) && !options.force) { + if (!options.silent) { + console.log( + `⚠️ ${mapName}: File already exists (use --force to overwrite)`, + ); + } + + return "skipped"; + } + + try { + const game = await setupFromPath(mapsDirectory, mapName); + const map = game.map(); + + // Find all water shoreline tiles + const shorelinePorts: Array<[number, number]> = []; + + map.forEachTile((tile) => { + if (map.isOcean(tile) && map.isShoreline(tile)) { + shorelinePorts.push([map.x(tile), map.y(tile)]); + } + }); + + if (shorelinePorts.length < 10) { + console.log( + `❌ ${mapName}: Not enough water shoreline tiles (minimum 10 required)`, + ); + return "error"; + } + + // Select random ports + const numPortsToSelect = Math.min(NUM_PORTS, shorelinePorts.length); + const selectedPorts: Array<[number, number]> = []; + const shuffled = shorelinePorts.sort(() => Math.random() - 0.5); + for (let i = 0; i < numPortsToSelect; i++) { + selectedPorts.push(shuffled[i]); + } + + // Build ports array + const ports: Port[] = selectedPorts.map((coord, index) => ({ + name: `Port${String(index + 1).padStart(3, "0")}`, + coords: coord, + })); + + // Build routes array + const routes: Route[] = []; + + // Generate routes: each port connects to next N ports + for (let i = 0; i < selectedPorts.length; i++) { + for ( + let j = 1; + j <= ROUTES_PER_PORT && i + j < selectedPorts.length; + j++ + ) { + routes.push({ + from: `Port${String(i + 1).padStart(3, "0")}`, + to: `Port${String(i + j + 1).padStart(3, "0")}`, + }); + } + } + + // Add extra routes to reach target (or as many as possible) + const targetRoutes = Math.min(NUM_ROUTES, routes.length + 200); + const additionalRoutesNeeded = targetRoutes - routes.length; + if (additionalRoutesNeeded > 0) { + let added = 0; + for ( + let i = 0; + i < selectedPorts.length && added < additionalRoutesNeeded; + i++ + ) { + for ( + let j = ROUTES_PER_PORT + 1; + j <= ROUTES_PER_PORT + 3 && + i + j < selectedPorts.length && + added < additionalRoutesNeeded; + j++ + ) { + routes.push({ + from: `Port${String(i + 1).padStart(3, "0")}`, + to: `Port${String(i + j + 1).padStart(3, "0")}`, + }); + added++; + } + } + } + + // Generate content from template + const content = generateScenarioContent({ + mapName, + ports, + routes, + }); + + const routeCount = routes.length; + + // Ensure directory exists + mkdirSync(scenariosDir, { recursive: true }); + + // Write to file + writeFileSync(outputPath, content); + + console.log( + `✅ ${mapName} generated with ${numPortsToSelect} ports and ${routeCount} routes`, + ); + + return "created"; + } catch (error) { + console.error(`❌ ${mapName}:`, error); + return "error"; + } +} + +function printUsage() { + console.log(` +Usage: + npx tsx tests/pathfinding/benchmark/generate.ts [--force] + npx tsx tests/pathfinding/benchmark/generate.ts --all [--force] + +Arguments: + Name of the map to generate scenario for (e.g., iceland, giantworldmap) + --all Generate scenarios for all available maps + --force Overwrite existing scenario files + +Examples: + npx tsx tests/pathfinding/benchmark/generate.ts iceland + npx tsx tests/pathfinding/benchmark/generate.ts giantworldmap --force + npx tsx tests/pathfinding/benchmark/generate.ts --all + +Available maps: + Run 'ls resources/maps' to see all available maps +`); +} + +// Parse command-line arguments +async function main() { + const args = process.argv.slice(2); + + if (args.length === 0 || args.includes("--help") || args.includes("-h")) { + printUsage(); + process.exit(0); + } + + const options: GenerationOptions = { + force: args.includes("--force"), + silent: args.includes("--all"), + }; + + const nonFlagArgs = args.filter((arg) => !arg.startsWith("--")); + + if (args.includes("--all")) { + // Generate for all maps + const maps = readdirSync(mapsDirectory, { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => dirent.name) + .sort(); + + console.log(`Generating synthetic scenarios for ${maps.length} maps...`); + console.log(`Config: ${NUM_PORTS} ports, ${NUM_ROUTES} routes`); + console.log(`Force overwrite: ${options.force}`); + console.log(``); + + let createdCount = 0; + let skippedCount = 0; + let errorCount = 0; + + for (const mapName of maps) { + const result = await generateScenarioForMap(mapName, options); + + if (result === "created") { + createdCount++; + } else if (result === "skipped") { + skippedCount++; + } else if (result === "error") { + errorCount++; + } + } + + if (createdCount + errorCount > 0) { + console.log(``); + } + + console.log( + `Created: ${createdCount}, Skipped: ${skippedCount}, Errors: ${errorCount}`, + ); + } else if (nonFlagArgs.length === 1) { + // Generate for single map + const mapName = nonFlagArgs[0]; + const mapPath = join(mapsDirectory, mapName); + + if (!existsSync(mapPath)) { + console.error(`Map not found: ${mapName}`); + process.exit(1); + } + + console.log(`Generating synthetic scenario for ${mapName}...`); + console.log(`Config: ${NUM_PORTS} ports, ${NUM_ROUTES} routes`); + console.log(`Force overwrite: ${options.force}`); + console.log(``); + + const result = await generateScenarioForMap(mapName, options); + + if (result === "created") { + console.log(``); + console.log(`Scenario generated successfully!`); + console.log( + `You can now run: npx tsx tests/pathfinding/benchmark/run.ts --synthetic ${mapName}`, + ); + } else { + process.exit(1); + } + } else { + console.error(`Invalid arguments.`); + printUsage(); + process.exit(1); + } +} + +// Run main function +main().catch((error) => { + console.error(`Fatal error:`, error); + process.exit(1); +}); + +/** + * Template for generating synthetic benchmark scenarios + */ + +interface Port { + name: string; + coords: [number, number]; +} + +interface Route { + from: string; + to: string; +} + +interface TemplateParams { + mapName: string; + ports: Port[]; + routes: Route[]; +} + +function generateScenarioContent(params: TemplateParams): string { + const { mapName, ports, routes } = params; + + let content = ``; + + // Simplified format - just data, no setup function + content += `export const MAP_NAME = "${mapName}";\n\n`; + + // Generate PORTS object + content += `export const PORTS: { [k: string]: [number, number] } = {\n`; + ports.forEach((port) => { + content += ` ${port.name}: [${port.coords[0]}, ${port.coords[1]}],\n`; + }); + content += `};\n\n`; + + // Generate ROUTES array + content += `export const ROUTES: Array<[keyof typeof PORTS, keyof typeof PORTS]> = [\n`; + routes.forEach((route) => { + content += ` ["${route.from}", "${route.to}"],\n`; + }); + content += `];\n`; + + return content; +} diff --git a/tests/pathfinding/benchmark/run.ts b/tests/pathfinding/benchmark/run.ts new file mode 100644 index 000000000..ceaa47035 --- /dev/null +++ b/tests/pathfinding/benchmark/run.ts @@ -0,0 +1,287 @@ +#!/usr/bin/env node + +/** + * Benchmark pathfinding adapters on various scenarios + * + * Usage: + * npx tsx tests/pathfinding/benchmark/run.ts [ []] + * npx tsx tests/pathfinding/benchmark/run.ts --synthetic [] + * npx tsx tests/pathfinding/benchmark/run.ts --synthetic --all [] + * + * Examples: + * npx tsx tests/pathfinding/benchmark/run.ts + * npx tsx tests/pathfinding/benchmark/run.ts default legacy + * npx tsx tests/pathfinding/benchmark/run.ts --synthetic --all + * npx tsx tests/pathfinding/benchmark/run.ts --synthetic iceland legacy + */ + +import { readdirSync } from "fs"; +import { dirname, join } from "path"; +import { fileURLToPath } from "url"; +import { + type BenchmarkResult, + calculateStats, + getAdapter, + getScenario, + measureExecutionTime, + measurePathLength, + printHeader, + printRow, +} from "../utils"; + +const currentFile = fileURLToPath(import.meta.url); +const pathfindingDir = dirname(currentFile); +const syntheticScenariosDir = join(pathfindingDir, "scenarios", "synthetic"); + +interface RunOptions { + silent?: boolean; + iterations?: number; +} + +const DEFAULT_ADAPTER = "hpa"; +const DEFAULT_SCENARIO = "default"; +const DEFAULT_ITERATIONS = 10; + +async function runScenario( + adapterName: string, + scenarioName: string, + options: RunOptions = {}, +) { + const { game, routes, initTime } = await getScenario( + scenarioName, + adapterName, + ); + const adapter = getAdapter(game, adapterName); + const { silent = false } = options; + + if (!silent) { + console.log(`Date: ${new Date().toISOString()}`); + console.log(`Benchmarking: ${adapterName}`); + console.log(`Scenario: ${scenarioName}`); + console.log(`Routes: ${routes.length}`); + console.log(``); + } + + // ============================================================================= + + if (!silent) { + printHeader("METRIC 1: INITIALIZATION TIME"); + } + + const initializationTime = initTime; + + if (!silent) { + console.log(`Initialization time: ${initializationTime.toFixed(2)}ms`); + console.log(``); + } + + // ============================================================================= + + if (!silent) { + printHeader("METRIC 2: PATH DISTANCE"); + printRow(["Route", "Path Length"], [40, 12]); + } + + const results: BenchmarkResult[] = []; + + for (const route of routes) { + const pathLength = measurePathLength(adapter, route); + results.push({ route: route.name, pathLength, executionTime: null }); + if (!silent) { + printRow( + [route.name, pathLength !== null ? `${pathLength} tiles` : "FAILED"], + [40, 12], + ); + } + } + + const { totalDistance, successfulRoutes, totalRoutes } = + calculateStats(results); + + if (!silent) { + console.log(``); + console.log(`Total distance: ${totalDistance} tiles`); + console.log(`Routes completed: ${successfulRoutes} / ${totalRoutes}`); + console.log(``); + } + + // ============================================================================= + + if (!silent) { + printHeader("METRIC 3: PATHFINDING TIME"); + printRow(["Route", "Time"], [40, 12]); + } + + for (const route of routes) { + const result = results.find((r) => r.route === route.name); + + if (result && result.pathLength !== null) { + const execTime = measureExecutionTime( + adapter, + route, + options.iterations ?? DEFAULT_ITERATIONS, + ); + result.executionTime = execTime; + + if (!silent) { + printRow([route.name, `${execTime!.toFixed(2)}ms`], [40, 12]); + } + } else { + if (!silent) { + printRow([route.name, "FAILED"], [40, 12]); + } + } + } + + const stats = calculateStats(results); + + if (!silent) { + console.log(``); + console.log(`Total time: ${stats.totalTime.toFixed(2)}ms`); + console.log(`Average time: ${stats.avgTime.toFixed(2)}ms`); + console.log( + `Routes benchmarked: ${stats.timedRoutes} / ${stats.totalRoutes}`, + ); + console.log(``); + + // ============================================================================= + + printHeader("SUMMARY"); + + console.log(`Adapter: ${adapterName}`); + console.log(`Scenario: ${scenarioName}`); + console.log(``); + + if (stats.successfulRoutes < stats.totalRoutes) { + console.log( + `Warning: Only ${stats.successfulRoutes} out of ${stats.totalRoutes} routes were completed successfully!`, + ); + console.log(``); + } + + console.log("Scores:"); + console.log(` Initialization: ${initializationTime.toFixed(2)}ms`); + console.log(` Pathfinding: ${stats.totalTime.toFixed(2)}ms`); + console.log(` Distance: ${totalDistance} tiles`); + console.log(``); + } else { + // Silent mode - just print a summary line + const status = stats.successfulRoutes < stats.totalRoutes ? "⚠️ " : "✅"; + console.log( + `${status} ${scenarioName.padEnd(35)} | Init: ${initializationTime.toFixed(2).padStart(8)}ms | Path: ${stats.totalTime.toFixed(2).padStart(9)}ms | Dist: ${totalDistance.toString().padStart(7)} tiles | Routes: ${stats.successfulRoutes}/${stats.totalRoutes}`, + ); + } + + return { + initializationTime, + totalTime: stats.totalTime, + totalDistance: totalDistance, + }; +} + +function printUsage() { + console.log(` +Usage: + npx tsx tests/pathfinding/benchmark/run.ts [ []] + npx tsx tests/pathfinding/benchmark/run.ts --synthetic [] + npx tsx tests/pathfinding/benchmark/run.ts --synthetic --all [] + +Arguments: + Name of the scenario to benchmark (default: "default" -> giantworldmap with handpicked ports) + Pathfinding adapter: "hpa" (default), "hpa.cached", "legacy" + --silent Minimize output, only print summary lines + --synthetic Run synthetic scenarios + --all Run all synthetic scenarios (requires --synthetic) + +Examples: + npx tsx tests/pathfinding/benchmark/run.ts + npx tsx tests/pathfinding/benchmark/run.ts default legacy + npx tsx tests/pathfinding/benchmark/run.ts --synthetic --all + npx tsx tests/pathfinding/benchmark/run.ts --synthetic iceland legacy + +Available synthetic scenarios: + Run 'ls tests/pathfinding/benchmark/scenarios/synthetic' to see all available scenarios +`); +} + +async function main() { + const args = process.argv.slice(2); + + if (args.includes("--help") || args.includes("-h")) { + printUsage(); + process.exit(0); + } + + const isSynthetic = args.includes("--synthetic"); + const isAll = args.includes("--all"); + const isSilent = args.includes("--silent"); + const nonFlagArgs = args.filter((arg) => !arg.startsWith("--")); + + if (isSynthetic) { + if (isAll) { + // Run all synthetic scenarios + const adapterName = nonFlagArgs[0] || DEFAULT_ADAPTER; + + // Find all synthetic scenario files + const scenarioFiles = readdirSync(syntheticScenariosDir) + .filter((file) => file.endsWith(".ts")) + .map((file) => file.replace(".ts", "")) + .sort(); + + console.log( + `Running ${scenarioFiles.length} synthetic scenarios with ${adapterName} adapter...`, + ); + console.log(``); + + const results: { + initializationTime: number; + totalTime: number; + totalDistance: number; + }[] = []; + + for (let i = 0; i < scenarioFiles.length; i++) { + const mapName = scenarioFiles[i]; + const scenarioName = `synthetic/${mapName}`; + const result = await runScenario(adapterName, scenarioName, { + silent: true, + iterations: 1, + }); + results.push(result); + } + + console.log(``); + console.log(`Completed ${scenarioFiles.length} scenarios`); + console.log( + `Total Initialization Time: ${results.reduce((sum, r) => sum + r.initializationTime, 0).toFixed(2)}ms`, + ); + console.log( + `Total Pathfinding Time: ${results.reduce((sum, r) => sum + r.totalTime, 0).toFixed(2)}ms`, + ); + console.log( + `Total Distance: ${results.reduce((sum, r) => sum + r.totalDistance, 0)} tiles`, + ); + } else if (nonFlagArgs.length >= 1) { + // Run single synthetic scenario + const mapName = nonFlagArgs[0]; + const adapterName = nonFlagArgs[1] || DEFAULT_ADAPTER; + const scenarioName = `synthetic/${mapName}`; + + await runScenario(adapterName, scenarioName, { silent: isSilent }); + } else { + console.error("Error: --synthetic requires a map name or --all flag"); + printUsage(); + process.exit(1); + } + } else { + // Standard mode with positional arguments + const scenarioName = nonFlagArgs[0] || DEFAULT_SCENARIO; + const adapterName = nonFlagArgs[1] || DEFAULT_ADAPTER; + + await runScenario(adapterName, scenarioName, { silent: isSilent }); + } +} + +main().catch((error) => { + console.error("Fatal error:", error); + process.exit(1); +}); diff --git a/tests/pathfinding/benchmark/scenarios/default.ts b/tests/pathfinding/benchmark/scenarios/default.ts new file mode 100644 index 000000000..83985bc3a --- /dev/null +++ b/tests/pathfinding/benchmark/scenarios/default.ts @@ -0,0 +1,55 @@ +export const MAP_NAME = "giantworldmap"; + +export const PORTS: { [k: string]: [number, number] } = { + Miami: [1014, 694], + Boston: [1120, 498], + Houston: [844, 657], + Chicago: [928, 508], + Cleveland: [995, 514], + Barcelona: [1943, 518], + "Sao Paulo": [1396, 1288], + "San Francisco": [520, 547], + "Falkland Islands": [1259, 1616], + "San Salvador": [901, 842], + Luxor: [2302, 700], + Venice: [2068, 468], + "Kongo River": [2142, 965], + Shanghai: [3317, 639], + Tokyo: [3525, 583], + "Abu Zabi": [2554, 711], + Gdansk: [2143, 362], + Neapol: [2081, 516], + "San Felipe": [617, 637], + Anchorage: [217, 281], + Honolulu: [156, 768], + "Ghana River": [1877, 869], + "Guinea River": [1824, 868], + "Peru River": [1097, 1162], + "China Desert River": [2965, 599], + "Australia River": [3663, 1343], +}; + +export const ROUTES: Array<[keyof typeof PORTS, keyof typeof PORTS]> = [ + ["Miami", "Boston"], + ["Miami", "Houston"], + ["Miami", "Chicago"], + ["Miami", "Cleveland"], + ["Miami", "Barcelona"], + ["Miami", "Sao Paulo"], + ["Miami", "San Francisco"], + ["Miami", "Falkland Islands"], + ["Miami", "San Salvador"], + ["Luxor", "Venice"], + ["Luxor", "Kongo River"], + ["Shanghai", "Tokyo"], + ["Shanghai", "San Francisco"], + ["Abu Zabi", "Gdansk"], + ["Chicago", "Cleveland"], + ["Barcelona", "Neapol"], + ["San Francisco", "San Felipe"], + ["Anchorage", "Honolulu"], + ["Kongo River", "Ghana River"], + ["Kongo River", "Guinea River"], + ["Peru River", "China Desert River"], + ["China Desert River", "Australia River"], +]; diff --git a/tests/pathfinding/benchmark/scenarios/synthetic/giantworldmap.ts b/tests/pathfinding/benchmark/scenarios/synthetic/giantworldmap.ts new file mode 100644 index 000000000..ef4bcfda1 --- /dev/null +++ b/tests/pathfinding/benchmark/scenarios/synthetic/giantworldmap.ts @@ -0,0 +1,1207 @@ +export const MAP_NAME = "giantworldmap"; + +export const PORTS: { [k: string]: [number, number] } = { + Port001: [2224, 1019], + Port002: [1665, 145], + Port003: [3969, 186], + Port004: [1211, 215], + Port005: [735, 163], + Port006: [1346, 176], + Port007: [2561, 150], + Port008: [653, 173], + Port009: [2787, 144], + Port010: [1148, 181], + Port011: [396, 182], + Port012: [3613, 180], + Port013: [3931, 179], + Port014: [2192, 178], + Port015: [622, 173], + Port016: [597, 160], + Port017: [1663, 172], + Port018: [802, 162], + Port019: [3923, 179], + Port020: [1875, 405], + Port021: [2883, 159], + Port022: [3336, 336], + Port023: [944, 155], + Port024: [3864, 289], + Port025: [2303, 290], + Port026: [2266, 296], + Port027: [1678, 159], + Port028: [3259, 289], + Port029: [2141, 300], + Port030: [2544, 160], + Port031: [1132, 294], + Port032: [855, 152], + Port033: [3509, 159], + Port034: [2788, 160], + Port035: [1872, 312], + Port036: [2979, 310], + Port037: [2580, 169], + Port038: [2789, 145], + Port039: [3224, 297], + Port040: [2277, 296], + Port041: [1295, 160], + Port042: [2559, 169], + Port043: [1654, 147], + Port044: [3583, 148], + Port045: [2199, 172], + Port046: [2891, 182], + Port047: [115, 311], + Port048: [762, 173], + Port049: [381, 304], + Port050: [170, 314], + Port051: [1676, 159], + Port052: [3689, 297], + Port053: [3420, 311], + Port054: [2827, 294], + Port055: [280, 293], + Port056: [2127, 298], + Port057: [3453, 298], + Port058: [3144, 143], + Port059: [228, 296], + Port060: [3303, 291], + Port061: [1655, 148], + Port062: [1043, 145], + Port063: [3751, 169], + Port064: [475, 173], + Port065: [589, 143], + Port066: [2134, 302], + Port067: [2702, 160], + Port068: [2242, 289], + Port069: [444, 180], + Port070: [673, 145], + Port071: [383, 303], + Port072: [3401, 148], + Port073: [3912, 179], + Port074: [3414, 311], + Port075: [638, 170], + Port076: [2849, 305], + Port077: [2214, 293], + Port078: [3078, 422], + Port079: [2789, 158], + Port080: [2554, 169], + Port081: [2919, 142], + Port082: [3309, 142], + Port083: [1323, 173], + Port084: [1103, 456], + Port085: [1637, 170], + Port086: [2101, 411], + Port087: [2547, 168], + Port088: [483, 408], + Port089: [2532, 160], + Port090: [3225, 142], + Port091: [2714, 305], + Port092: [675, 143], + Port093: [1277, 404], + Port094: [1223, 411], + Port095: [2857, 306], + Port096: [3381, 160], + Port097: [533, 386], + Port098: [3543, 490], + Port099: [1669, 148], + Port100: [1024, 173], + Port101: [3384, 310], + Port102: [1934, 444], + Port103: [2117, 311], + Port104: [3290, 423], + Port105: [2073, 230], + Port106: [3353, 310], + Port107: [2144, 297], + Port108: [625, 169], + Port109: [2757, 145], + Port110: [111, 299], + Port111: [2235, 172], + Port112: [3162, 318], + Port113: [1990, 492], + Port114: [2285, 217], + Port115: [2791, 148], + Port116: [1055, 232], + Port117: [459, 220], + Port118: [2674, 234], + Port119: [371, 311], + Port120: [591, 320], + Port121: [2808, 160], + Port122: [2299, 229], + Port123: [3491, 416], + Port124: [783, 462], + Port125: [950, 218], + Port126: [2842, 151], + Port127: [51, 288], + Port128: [955, 230], + Port129: [2149, 509], + Port130: [933, 232], + Port131: [2556, 227], + Port132: [2709, 315], + Port133: [179, 235], + Port134: [1222, 464], + Port135: [1745, 218], + Port136: [766, 149], + Port137: [3149, 386], + Port138: [4091, 228], + Port139: [923, 173], + Port140: [53, 217], + Port141: [2435, 218], + Port142: [862, 159], + Port143: [1133, 299], + Port144: [252, 218], + Port145: [584, 421], + Port146: [52, 217], + Port147: [1845, 489], + Port148: [3763, 181], + Port149: [538, 423], + Port150: [1470, 241], + Port151: [891, 226], + Port152: [1975, 458], + Port153: [453, 218], + Port154: [1281, 418], + Port155: [4049, 221], + Port156: [3514, 158], + Port157: [3941, 241], + Port158: [1498, 229], + Port159: [590, 478], + Port160: [321, 182], + Port161: [2302, 284], + Port162: [2418, 296], + Port163: [3139, 384], + Port164: [1203, 315], + Port165: [2275, 404], + Port166: [100, 173], + Port167: [310, 180], + Port168: [1287, 396], + Port169: [2430, 266], + Port170: [183, 170], + Port171: [176, 235], + Port172: [325, 182], + Port173: [2984, 315], + Port174: [511, 248], + Port175: [2700, 215], + Port176: [2560, 222], + Port177: [3162, 298], + Port178: [1917, 463], + Port179: [1094, 458], + Port180: [2870, 314], + Port181: [2683, 221], + Port182: [1679, 172], + Port183: [3012, 247], + Port184: [1324, 214], + Port185: [2734, 220], + Port186: [80, 239], + Port187: [2579, 234], + Port188: [1297, 152], + Port189: [1206, 464], + Port190: [3426, 168], + Port191: [745, 282], + Port192: [2996, 329], + Port193: [2061, 247], + Port194: [3073, 426], + Port195: [3051, 246], + Port196: [3921, 179], + Port197: [503, 402], + Port198: [3473, 159], + Port199: [846, 296], + Port200: [2179, 180], +}; + +export const ROUTES: Array<[keyof typeof PORTS, keyof typeof PORTS]> = [ + ["Port001", "Port002"], + ["Port001", "Port003"], + ["Port001", "Port004"], + ["Port001", "Port005"], + ["Port001", "Port006"], + ["Port002", "Port003"], + ["Port002", "Port004"], + ["Port002", "Port005"], + ["Port002", "Port006"], + ["Port002", "Port007"], + ["Port003", "Port004"], + ["Port003", "Port005"], + ["Port003", "Port006"], + ["Port003", "Port007"], + ["Port003", "Port008"], + ["Port004", "Port005"], + ["Port004", "Port006"], + ["Port004", "Port007"], + ["Port004", "Port008"], + ["Port004", "Port009"], + ["Port005", "Port006"], + ["Port005", "Port007"], + ["Port005", "Port008"], + ["Port005", "Port009"], + ["Port005", "Port010"], + ["Port006", "Port007"], + ["Port006", "Port008"], + ["Port006", "Port009"], + ["Port006", "Port010"], + ["Port006", "Port011"], + ["Port007", "Port008"], + ["Port007", "Port009"], + ["Port007", "Port010"], + ["Port007", "Port011"], + ["Port007", "Port012"], + ["Port008", "Port009"], + ["Port008", "Port010"], + ["Port008", "Port011"], + ["Port008", "Port012"], + ["Port008", "Port013"], + ["Port009", "Port010"], + ["Port009", "Port011"], + ["Port009", "Port012"], + ["Port009", "Port013"], + ["Port009", "Port014"], + ["Port010", "Port011"], + ["Port010", "Port012"], + ["Port010", "Port013"], + ["Port010", "Port014"], + ["Port010", "Port015"], + ["Port011", "Port012"], + ["Port011", "Port013"], + ["Port011", "Port014"], + ["Port011", "Port015"], + ["Port011", "Port016"], + ["Port012", "Port013"], + ["Port012", "Port014"], + ["Port012", "Port015"], + ["Port012", "Port016"], + ["Port012", "Port017"], + ["Port013", "Port014"], + ["Port013", "Port015"], + ["Port013", "Port016"], + ["Port013", "Port017"], + ["Port013", "Port018"], + ["Port014", "Port015"], + ["Port014", "Port016"], + ["Port014", "Port017"], + ["Port014", "Port018"], + ["Port014", "Port019"], + ["Port015", "Port016"], + ["Port015", "Port017"], + ["Port015", "Port018"], + ["Port015", "Port019"], + ["Port015", "Port020"], + ["Port016", "Port017"], + ["Port016", "Port018"], + ["Port016", "Port019"], + ["Port016", "Port020"], + ["Port016", "Port021"], + ["Port017", "Port018"], + ["Port017", "Port019"], + ["Port017", "Port020"], + ["Port017", "Port021"], + ["Port017", "Port022"], + ["Port018", "Port019"], + ["Port018", "Port020"], + ["Port018", "Port021"], + ["Port018", "Port022"], + ["Port018", "Port023"], + ["Port019", "Port020"], + ["Port019", "Port021"], + ["Port019", "Port022"], + ["Port019", "Port023"], + ["Port019", "Port024"], + ["Port020", "Port021"], + ["Port020", "Port022"], + ["Port020", "Port023"], + ["Port020", "Port024"], + ["Port020", "Port025"], + ["Port021", "Port022"], + ["Port021", "Port023"], + ["Port021", "Port024"], + ["Port021", "Port025"], + ["Port021", "Port026"], + ["Port022", "Port023"], + ["Port022", "Port024"], + ["Port022", "Port025"], + ["Port022", "Port026"], + ["Port022", "Port027"], + ["Port023", "Port024"], + ["Port023", "Port025"], + ["Port023", "Port026"], + ["Port023", "Port027"], + ["Port023", "Port028"], + ["Port024", "Port025"], + ["Port024", "Port026"], + ["Port024", "Port027"], + ["Port024", "Port028"], + ["Port024", "Port029"], + ["Port025", "Port026"], + ["Port025", "Port027"], + ["Port025", "Port028"], + ["Port025", "Port029"], + ["Port025", "Port030"], + ["Port026", "Port027"], + ["Port026", "Port028"], + ["Port026", "Port029"], + ["Port026", "Port030"], + ["Port026", "Port031"], + ["Port027", "Port028"], + ["Port027", "Port029"], + ["Port027", "Port030"], + ["Port027", "Port031"], + ["Port027", "Port032"], + ["Port028", "Port029"], + ["Port028", "Port030"], + ["Port028", "Port031"], + ["Port028", "Port032"], + ["Port028", "Port033"], + ["Port029", "Port030"], + ["Port029", "Port031"], + ["Port029", "Port032"], + ["Port029", "Port033"], + ["Port029", "Port034"], + ["Port030", "Port031"], + ["Port030", "Port032"], + ["Port030", "Port033"], + ["Port030", "Port034"], + ["Port030", "Port035"], + ["Port031", "Port032"], + ["Port031", "Port033"], + ["Port031", "Port034"], + ["Port031", "Port035"], + ["Port031", "Port036"], + ["Port032", "Port033"], + ["Port032", "Port034"], + ["Port032", "Port035"], + ["Port032", "Port036"], + ["Port032", "Port037"], + ["Port033", "Port034"], + ["Port033", "Port035"], + ["Port033", "Port036"], + ["Port033", "Port037"], + ["Port033", "Port038"], + ["Port034", "Port035"], + ["Port034", "Port036"], + ["Port034", "Port037"], + ["Port034", "Port038"], + ["Port034", "Port039"], + ["Port035", "Port036"], + ["Port035", "Port037"], + ["Port035", "Port038"], + ["Port035", "Port039"], + ["Port035", "Port040"], + ["Port036", "Port037"], + ["Port036", "Port038"], + ["Port036", "Port039"], + ["Port036", "Port040"], + ["Port036", "Port041"], + ["Port037", "Port038"], + ["Port037", "Port039"], + ["Port037", "Port040"], + ["Port037", "Port041"], + ["Port037", "Port042"], + ["Port038", "Port039"], + ["Port038", "Port040"], + ["Port038", "Port041"], + ["Port038", "Port042"], + ["Port038", "Port043"], + ["Port039", "Port040"], + ["Port039", "Port041"], + ["Port039", "Port042"], + ["Port039", "Port043"], + ["Port039", "Port044"], + ["Port040", "Port041"], + ["Port040", "Port042"], + ["Port040", "Port043"], + ["Port040", "Port044"], + ["Port040", "Port045"], + ["Port041", "Port042"], + ["Port041", "Port043"], + ["Port041", "Port044"], + ["Port041", "Port045"], + ["Port041", "Port046"], + ["Port042", "Port043"], + ["Port042", "Port044"], + ["Port042", "Port045"], + ["Port042", "Port046"], + ["Port042", "Port047"], + ["Port043", "Port044"], + ["Port043", "Port045"], + ["Port043", "Port046"], + ["Port043", "Port047"], + ["Port043", "Port048"], + ["Port044", "Port045"], + ["Port044", "Port046"], + ["Port044", "Port047"], + ["Port044", "Port048"], + ["Port044", "Port049"], + ["Port045", "Port046"], + ["Port045", "Port047"], + ["Port045", "Port048"], + ["Port045", "Port049"], + ["Port045", "Port050"], + ["Port046", "Port047"], + ["Port046", "Port048"], + ["Port046", "Port049"], + ["Port046", "Port050"], + ["Port046", "Port051"], + ["Port047", "Port048"], + ["Port047", "Port049"], + ["Port047", "Port050"], + ["Port047", "Port051"], + ["Port047", "Port052"], + ["Port048", "Port049"], + ["Port048", "Port050"], + ["Port048", "Port051"], + ["Port048", "Port052"], + ["Port048", "Port053"], + ["Port049", "Port050"], + ["Port049", "Port051"], + ["Port049", "Port052"], + ["Port049", "Port053"], + ["Port049", "Port054"], + ["Port050", "Port051"], + ["Port050", "Port052"], + ["Port050", "Port053"], + ["Port050", "Port054"], + ["Port050", "Port055"], + ["Port051", "Port052"], + ["Port051", "Port053"], + ["Port051", "Port054"], + ["Port051", "Port055"], + ["Port051", "Port056"], + ["Port052", "Port053"], + ["Port052", "Port054"], + ["Port052", "Port055"], + ["Port052", "Port056"], + ["Port052", "Port057"], + ["Port053", "Port054"], + ["Port053", "Port055"], + ["Port053", "Port056"], + ["Port053", "Port057"], + ["Port053", "Port058"], + ["Port054", "Port055"], + ["Port054", "Port056"], + ["Port054", "Port057"], + ["Port054", "Port058"], + ["Port054", "Port059"], + ["Port055", "Port056"], + ["Port055", "Port057"], + ["Port055", "Port058"], + ["Port055", "Port059"], + ["Port055", "Port060"], + ["Port056", "Port057"], + ["Port056", "Port058"], + ["Port056", "Port059"], + ["Port056", "Port060"], + ["Port056", "Port061"], + ["Port057", "Port058"], + ["Port057", "Port059"], + ["Port057", "Port060"], + ["Port057", "Port061"], + ["Port057", "Port062"], + ["Port058", "Port059"], + ["Port058", "Port060"], + ["Port058", "Port061"], + ["Port058", "Port062"], + ["Port058", "Port063"], + ["Port059", "Port060"], + ["Port059", "Port061"], + ["Port059", "Port062"], + ["Port059", "Port063"], + ["Port059", "Port064"], + ["Port060", "Port061"], + ["Port060", "Port062"], + ["Port060", "Port063"], + ["Port060", "Port064"], + ["Port060", "Port065"], + ["Port061", "Port062"], + ["Port061", "Port063"], + ["Port061", "Port064"], + ["Port061", "Port065"], + ["Port061", "Port066"], + ["Port062", "Port063"], + ["Port062", "Port064"], + ["Port062", "Port065"], + ["Port062", "Port066"], + ["Port062", "Port067"], + ["Port063", "Port064"], + ["Port063", "Port065"], + ["Port063", "Port066"], + ["Port063", "Port067"], + ["Port063", "Port068"], + ["Port064", "Port065"], + ["Port064", "Port066"], + ["Port064", "Port067"], + ["Port064", "Port068"], + ["Port064", "Port069"], + ["Port065", "Port066"], + ["Port065", "Port067"], + ["Port065", "Port068"], + ["Port065", "Port069"], + ["Port065", "Port070"], + ["Port066", "Port067"], + ["Port066", "Port068"], + ["Port066", "Port069"], + ["Port066", "Port070"], + ["Port066", "Port071"], + ["Port067", "Port068"], + ["Port067", "Port069"], + ["Port067", "Port070"], + ["Port067", "Port071"], + ["Port067", "Port072"], + ["Port068", "Port069"], + ["Port068", "Port070"], + ["Port068", "Port071"], + ["Port068", "Port072"], + ["Port068", "Port073"], + ["Port069", "Port070"], + ["Port069", "Port071"], + ["Port069", "Port072"], + ["Port069", "Port073"], + ["Port069", "Port074"], + ["Port070", "Port071"], + ["Port070", "Port072"], + ["Port070", "Port073"], + ["Port070", "Port074"], + ["Port070", "Port075"], + ["Port071", "Port072"], + ["Port071", "Port073"], + ["Port071", "Port074"], + ["Port071", "Port075"], + ["Port071", "Port076"], + ["Port072", "Port073"], + ["Port072", "Port074"], + ["Port072", "Port075"], + ["Port072", "Port076"], + ["Port072", "Port077"], + ["Port073", "Port074"], + ["Port073", "Port075"], + ["Port073", "Port076"], + ["Port073", "Port077"], + ["Port073", "Port078"], + ["Port074", "Port075"], + ["Port074", "Port076"], + ["Port074", "Port077"], + ["Port074", "Port078"], + ["Port074", "Port079"], + ["Port075", "Port076"], + ["Port075", "Port077"], + ["Port075", "Port078"], + ["Port075", "Port079"], + ["Port075", "Port080"], + ["Port076", "Port077"], + ["Port076", "Port078"], + ["Port076", "Port079"], + ["Port076", "Port080"], + ["Port076", "Port081"], + ["Port077", "Port078"], + ["Port077", "Port079"], + ["Port077", "Port080"], + ["Port077", "Port081"], + ["Port077", "Port082"], + ["Port078", "Port079"], + ["Port078", "Port080"], + ["Port078", "Port081"], + ["Port078", "Port082"], + ["Port078", "Port083"], + ["Port079", "Port080"], + ["Port079", "Port081"], + ["Port079", "Port082"], + ["Port079", "Port083"], + ["Port079", "Port084"], + ["Port080", "Port081"], + ["Port080", "Port082"], + ["Port080", "Port083"], + ["Port080", "Port084"], + ["Port080", "Port085"], + ["Port081", "Port082"], + ["Port081", "Port083"], + ["Port081", "Port084"], + ["Port081", "Port085"], + ["Port081", "Port086"], + ["Port082", "Port083"], + ["Port082", "Port084"], + ["Port082", "Port085"], + ["Port082", "Port086"], + ["Port082", "Port087"], + ["Port083", "Port084"], + ["Port083", "Port085"], + ["Port083", "Port086"], + ["Port083", "Port087"], + ["Port083", "Port088"], + ["Port084", "Port085"], + ["Port084", "Port086"], + ["Port084", "Port087"], + ["Port084", "Port088"], + ["Port084", "Port089"], + ["Port085", "Port086"], + ["Port085", "Port087"], + ["Port085", "Port088"], + ["Port085", "Port089"], + ["Port085", "Port090"], + ["Port086", "Port087"], + ["Port086", "Port088"], + ["Port086", "Port089"], + ["Port086", "Port090"], + ["Port086", "Port091"], + ["Port087", "Port088"], + ["Port087", "Port089"], + ["Port087", "Port090"], + ["Port087", "Port091"], + ["Port087", "Port092"], + ["Port088", "Port089"], + ["Port088", "Port090"], + ["Port088", "Port091"], + ["Port088", "Port092"], + ["Port088", "Port093"], + ["Port089", "Port090"], + ["Port089", "Port091"], + ["Port089", "Port092"], + ["Port089", "Port093"], + ["Port089", "Port094"], + ["Port090", "Port091"], + ["Port090", "Port092"], + ["Port090", "Port093"], + ["Port090", "Port094"], + ["Port090", "Port095"], + ["Port091", "Port092"], + ["Port091", "Port093"], + ["Port091", "Port094"], + ["Port091", "Port095"], + ["Port091", "Port096"], + ["Port092", "Port093"], + ["Port092", "Port094"], + ["Port092", "Port095"], + ["Port092", "Port096"], + ["Port092", "Port097"], + ["Port093", "Port094"], + ["Port093", "Port095"], + ["Port093", "Port096"], + ["Port093", "Port097"], + ["Port093", "Port098"], + ["Port094", "Port095"], + ["Port094", "Port096"], + ["Port094", "Port097"], + ["Port094", "Port098"], + ["Port094", "Port099"], + ["Port095", "Port096"], + ["Port095", "Port097"], + ["Port095", "Port098"], + ["Port095", "Port099"], + ["Port095", "Port100"], + ["Port096", "Port097"], + ["Port096", "Port098"], + ["Port096", "Port099"], + ["Port096", "Port100"], + ["Port096", "Port101"], + ["Port097", "Port098"], + ["Port097", "Port099"], + ["Port097", "Port100"], + ["Port097", "Port101"], + ["Port097", "Port102"], + ["Port098", "Port099"], + ["Port098", "Port100"], + ["Port098", "Port101"], + ["Port098", "Port102"], + ["Port098", "Port103"], + ["Port099", "Port100"], + ["Port099", "Port101"], + ["Port099", "Port102"], + ["Port099", "Port103"], + ["Port099", "Port104"], + ["Port100", "Port101"], + ["Port100", "Port102"], + ["Port100", "Port103"], + ["Port100", "Port104"], + ["Port100", "Port105"], + ["Port101", "Port102"], + ["Port101", "Port103"], + ["Port101", "Port104"], + ["Port101", "Port105"], + ["Port101", "Port106"], + ["Port102", "Port103"], + ["Port102", "Port104"], + ["Port102", "Port105"], + ["Port102", "Port106"], + ["Port102", "Port107"], + ["Port103", "Port104"], + ["Port103", "Port105"], + ["Port103", "Port106"], + ["Port103", "Port107"], + ["Port103", "Port108"], + ["Port104", "Port105"], + ["Port104", "Port106"], + ["Port104", "Port107"], + ["Port104", "Port108"], + ["Port104", "Port109"], + ["Port105", "Port106"], + ["Port105", "Port107"], + ["Port105", "Port108"], + ["Port105", "Port109"], + ["Port105", "Port110"], + ["Port106", "Port107"], + ["Port106", "Port108"], + ["Port106", "Port109"], + ["Port106", "Port110"], + ["Port106", "Port111"], + ["Port107", "Port108"], + ["Port107", "Port109"], + ["Port107", "Port110"], + ["Port107", "Port111"], + ["Port107", "Port112"], + ["Port108", "Port109"], + ["Port108", "Port110"], + ["Port108", "Port111"], + ["Port108", "Port112"], + ["Port108", "Port113"], + ["Port109", "Port110"], + ["Port109", "Port111"], + ["Port109", "Port112"], + ["Port109", "Port113"], + ["Port109", "Port114"], + ["Port110", "Port111"], + ["Port110", "Port112"], + ["Port110", "Port113"], + ["Port110", "Port114"], + ["Port110", "Port115"], + ["Port111", "Port112"], + ["Port111", "Port113"], + ["Port111", "Port114"], + ["Port111", "Port115"], + ["Port111", "Port116"], + ["Port112", "Port113"], + ["Port112", "Port114"], + ["Port112", "Port115"], + ["Port112", "Port116"], + ["Port112", "Port117"], + ["Port113", "Port114"], + ["Port113", "Port115"], + ["Port113", "Port116"], + ["Port113", "Port117"], + ["Port113", "Port118"], + ["Port114", "Port115"], + ["Port114", "Port116"], + ["Port114", "Port117"], + ["Port114", "Port118"], + ["Port114", "Port119"], + ["Port115", "Port116"], + ["Port115", "Port117"], + ["Port115", "Port118"], + ["Port115", "Port119"], + ["Port115", "Port120"], + ["Port116", "Port117"], + ["Port116", "Port118"], + ["Port116", "Port119"], + ["Port116", "Port120"], + ["Port116", "Port121"], + ["Port117", "Port118"], + ["Port117", "Port119"], + ["Port117", "Port120"], + ["Port117", "Port121"], + ["Port117", "Port122"], + ["Port118", "Port119"], + ["Port118", "Port120"], + ["Port118", "Port121"], + ["Port118", "Port122"], + ["Port118", "Port123"], + ["Port119", "Port120"], + ["Port119", "Port121"], + ["Port119", "Port122"], + ["Port119", "Port123"], + ["Port119", "Port124"], + ["Port120", "Port121"], + ["Port120", "Port122"], + ["Port120", "Port123"], + ["Port120", "Port124"], + ["Port120", "Port125"], + ["Port121", "Port122"], + ["Port121", "Port123"], + ["Port121", "Port124"], + ["Port121", "Port125"], + ["Port121", "Port126"], + ["Port122", "Port123"], + ["Port122", "Port124"], + ["Port122", "Port125"], + ["Port122", "Port126"], + ["Port122", "Port127"], + ["Port123", "Port124"], + ["Port123", "Port125"], + ["Port123", "Port126"], + ["Port123", "Port127"], + ["Port123", "Port128"], + ["Port124", "Port125"], + ["Port124", "Port126"], + ["Port124", "Port127"], + ["Port124", "Port128"], + ["Port124", "Port129"], + ["Port125", "Port126"], + ["Port125", "Port127"], + ["Port125", "Port128"], + ["Port125", "Port129"], + ["Port125", "Port130"], + ["Port126", "Port127"], + ["Port126", "Port128"], + ["Port126", "Port129"], + ["Port126", "Port130"], + ["Port126", "Port131"], + ["Port127", "Port128"], + ["Port127", "Port129"], + ["Port127", "Port130"], + ["Port127", "Port131"], + ["Port127", "Port132"], + ["Port128", "Port129"], + ["Port128", "Port130"], + ["Port128", "Port131"], + ["Port128", "Port132"], + ["Port128", "Port133"], + ["Port129", "Port130"], + ["Port129", "Port131"], + ["Port129", "Port132"], + ["Port129", "Port133"], + ["Port129", "Port134"], + ["Port130", "Port131"], + ["Port130", "Port132"], + ["Port130", "Port133"], + ["Port130", "Port134"], + ["Port130", "Port135"], + ["Port131", "Port132"], + ["Port131", "Port133"], + ["Port131", "Port134"], + ["Port131", "Port135"], + ["Port131", "Port136"], + ["Port132", "Port133"], + ["Port132", "Port134"], + ["Port132", "Port135"], + ["Port132", "Port136"], + ["Port132", "Port137"], + ["Port133", "Port134"], + ["Port133", "Port135"], + ["Port133", "Port136"], + ["Port133", "Port137"], + ["Port133", "Port138"], + ["Port134", "Port135"], + ["Port134", "Port136"], + ["Port134", "Port137"], + ["Port134", "Port138"], + ["Port134", "Port139"], + ["Port135", "Port136"], + ["Port135", "Port137"], + ["Port135", "Port138"], + ["Port135", "Port139"], + ["Port135", "Port140"], + ["Port136", "Port137"], + ["Port136", "Port138"], + ["Port136", "Port139"], + ["Port136", "Port140"], + ["Port136", "Port141"], + ["Port137", "Port138"], + ["Port137", "Port139"], + ["Port137", "Port140"], + ["Port137", "Port141"], + ["Port137", "Port142"], + ["Port138", "Port139"], + ["Port138", "Port140"], + ["Port138", "Port141"], + ["Port138", "Port142"], + ["Port138", "Port143"], + ["Port139", "Port140"], + ["Port139", "Port141"], + ["Port139", "Port142"], + ["Port139", "Port143"], + ["Port139", "Port144"], + ["Port140", "Port141"], + ["Port140", "Port142"], + ["Port140", "Port143"], + ["Port140", "Port144"], + ["Port140", "Port145"], + ["Port141", "Port142"], + ["Port141", "Port143"], + ["Port141", "Port144"], + ["Port141", "Port145"], + ["Port141", "Port146"], + ["Port142", "Port143"], + ["Port142", "Port144"], + ["Port142", "Port145"], + ["Port142", "Port146"], + ["Port142", "Port147"], + ["Port143", "Port144"], + ["Port143", "Port145"], + ["Port143", "Port146"], + ["Port143", "Port147"], + ["Port143", "Port148"], + ["Port144", "Port145"], + ["Port144", "Port146"], + ["Port144", "Port147"], + ["Port144", "Port148"], + ["Port144", "Port149"], + ["Port145", "Port146"], + ["Port145", "Port147"], + ["Port145", "Port148"], + ["Port145", "Port149"], + ["Port145", "Port150"], + ["Port146", "Port147"], + ["Port146", "Port148"], + ["Port146", "Port149"], + ["Port146", "Port150"], + ["Port146", "Port151"], + ["Port147", "Port148"], + ["Port147", "Port149"], + ["Port147", "Port150"], + ["Port147", "Port151"], + ["Port147", "Port152"], + ["Port148", "Port149"], + ["Port148", "Port150"], + ["Port148", "Port151"], + ["Port148", "Port152"], + ["Port148", "Port153"], + ["Port149", "Port150"], + ["Port149", "Port151"], + ["Port149", "Port152"], + ["Port149", "Port153"], + ["Port149", "Port154"], + ["Port150", "Port151"], + ["Port150", "Port152"], + ["Port150", "Port153"], + ["Port150", "Port154"], + ["Port150", "Port155"], + ["Port151", "Port152"], + ["Port151", "Port153"], + ["Port151", "Port154"], + ["Port151", "Port155"], + ["Port151", "Port156"], + ["Port152", "Port153"], + ["Port152", "Port154"], + ["Port152", "Port155"], + ["Port152", "Port156"], + ["Port152", "Port157"], + ["Port153", "Port154"], + ["Port153", "Port155"], + ["Port153", "Port156"], + ["Port153", "Port157"], + ["Port153", "Port158"], + ["Port154", "Port155"], + ["Port154", "Port156"], + ["Port154", "Port157"], + ["Port154", "Port158"], + ["Port154", "Port159"], + ["Port155", "Port156"], + ["Port155", "Port157"], + ["Port155", "Port158"], + ["Port155", "Port159"], + ["Port155", "Port160"], + ["Port156", "Port157"], + ["Port156", "Port158"], + ["Port156", "Port159"], + ["Port156", "Port160"], + ["Port156", "Port161"], + ["Port157", "Port158"], + ["Port157", "Port159"], + ["Port157", "Port160"], + ["Port157", "Port161"], + ["Port157", "Port162"], + ["Port158", "Port159"], + ["Port158", "Port160"], + ["Port158", "Port161"], + ["Port158", "Port162"], + ["Port158", "Port163"], + ["Port159", "Port160"], + ["Port159", "Port161"], + ["Port159", "Port162"], + ["Port159", "Port163"], + ["Port159", "Port164"], + ["Port160", "Port161"], + ["Port160", "Port162"], + ["Port160", "Port163"], + ["Port160", "Port164"], + ["Port160", "Port165"], + ["Port161", "Port162"], + ["Port161", "Port163"], + ["Port161", "Port164"], + ["Port161", "Port165"], + ["Port161", "Port166"], + ["Port162", "Port163"], + ["Port162", "Port164"], + ["Port162", "Port165"], + ["Port162", "Port166"], + ["Port162", "Port167"], + ["Port163", "Port164"], + ["Port163", "Port165"], + ["Port163", "Port166"], + ["Port163", "Port167"], + ["Port163", "Port168"], + ["Port164", "Port165"], + ["Port164", "Port166"], + ["Port164", "Port167"], + ["Port164", "Port168"], + ["Port164", "Port169"], + ["Port165", "Port166"], + ["Port165", "Port167"], + ["Port165", "Port168"], + ["Port165", "Port169"], + ["Port165", "Port170"], + ["Port166", "Port167"], + ["Port166", "Port168"], + ["Port166", "Port169"], + ["Port166", "Port170"], + ["Port166", "Port171"], + ["Port167", "Port168"], + ["Port167", "Port169"], + ["Port167", "Port170"], + ["Port167", "Port171"], + ["Port167", "Port172"], + ["Port168", "Port169"], + ["Port168", "Port170"], + ["Port168", "Port171"], + ["Port168", "Port172"], + ["Port168", "Port173"], + ["Port169", "Port170"], + ["Port169", "Port171"], + ["Port169", "Port172"], + ["Port169", "Port173"], + ["Port169", "Port174"], + ["Port170", "Port171"], + ["Port170", "Port172"], + ["Port170", "Port173"], + ["Port170", "Port174"], + ["Port170", "Port175"], + ["Port171", "Port172"], + ["Port171", "Port173"], + ["Port171", "Port174"], + ["Port171", "Port175"], + ["Port171", "Port176"], + ["Port172", "Port173"], + ["Port172", "Port174"], + ["Port172", "Port175"], + ["Port172", "Port176"], + ["Port172", "Port177"], + ["Port173", "Port174"], + ["Port173", "Port175"], + ["Port173", "Port176"], + ["Port173", "Port177"], + ["Port173", "Port178"], + ["Port174", "Port175"], + ["Port174", "Port176"], + ["Port174", "Port177"], + ["Port174", "Port178"], + ["Port174", "Port179"], + ["Port175", "Port176"], + ["Port175", "Port177"], + ["Port175", "Port178"], + ["Port175", "Port179"], + ["Port175", "Port180"], + ["Port176", "Port177"], + ["Port176", "Port178"], + ["Port176", "Port179"], + ["Port176", "Port180"], + ["Port176", "Port181"], + ["Port177", "Port178"], + ["Port177", "Port179"], + ["Port177", "Port180"], + ["Port177", "Port181"], + ["Port177", "Port182"], + ["Port178", "Port179"], + ["Port178", "Port180"], + ["Port178", "Port181"], + ["Port178", "Port182"], + ["Port178", "Port183"], + ["Port179", "Port180"], + ["Port179", "Port181"], + ["Port179", "Port182"], + ["Port179", "Port183"], + ["Port179", "Port184"], + ["Port180", "Port181"], + ["Port180", "Port182"], + ["Port180", "Port183"], + ["Port180", "Port184"], + ["Port180", "Port185"], + ["Port181", "Port182"], + ["Port181", "Port183"], + ["Port181", "Port184"], + ["Port181", "Port185"], + ["Port181", "Port186"], + ["Port182", "Port183"], + ["Port182", "Port184"], + ["Port182", "Port185"], + ["Port182", "Port186"], + ["Port182", "Port187"], + ["Port183", "Port184"], + ["Port183", "Port185"], + ["Port183", "Port186"], + ["Port183", "Port187"], + ["Port183", "Port188"], + ["Port184", "Port185"], + ["Port184", "Port186"], + ["Port184", "Port187"], + ["Port184", "Port188"], + ["Port184", "Port189"], + ["Port185", "Port186"], + ["Port185", "Port187"], + ["Port185", "Port188"], + ["Port185", "Port189"], + ["Port185", "Port190"], + ["Port186", "Port187"], + ["Port186", "Port188"], + ["Port186", "Port189"], + ["Port186", "Port190"], + ["Port186", "Port191"], + ["Port187", "Port188"], + ["Port187", "Port189"], + ["Port187", "Port190"], + ["Port187", "Port191"], + ["Port187", "Port192"], + ["Port188", "Port189"], + ["Port188", "Port190"], + ["Port188", "Port191"], + ["Port188", "Port192"], + ["Port188", "Port193"], + ["Port189", "Port190"], + ["Port189", "Port191"], + ["Port189", "Port192"], + ["Port189", "Port193"], + ["Port189", "Port194"], + ["Port190", "Port191"], + ["Port190", "Port192"], + ["Port190", "Port193"], + ["Port190", "Port194"], + ["Port190", "Port195"], + ["Port191", "Port192"], + ["Port191", "Port193"], + ["Port191", "Port194"], + ["Port191", "Port195"], + ["Port191", "Port196"], + ["Port192", "Port193"], + ["Port192", "Port194"], + ["Port192", "Port195"], + ["Port192", "Port196"], + ["Port192", "Port197"], + ["Port193", "Port194"], + ["Port193", "Port195"], + ["Port193", "Port196"], + ["Port193", "Port197"], + ["Port193", "Port198"], + ["Port194", "Port195"], + ["Port194", "Port196"], + ["Port194", "Port197"], + ["Port194", "Port198"], + ["Port194", "Port199"], + ["Port195", "Port196"], + ["Port195", "Port197"], + ["Port195", "Port198"], + ["Port195", "Port199"], + ["Port195", "Port200"], + ["Port196", "Port197"], + ["Port196", "Port198"], + ["Port196", "Port199"], + ["Port196", "Port200"], + ["Port197", "Port198"], + ["Port197", "Port199"], + ["Port197", "Port200"], + ["Port198", "Port199"], + ["Port198", "Port200"], + ["Port199", "Port200"], + ["Port001", "Port007"], + ["Port001", "Port008"], + ["Port001", "Port009"], + ["Port002", "Port008"], + ["Port002", "Port009"], + ["Port002", "Port010"], + ["Port003", "Port009"], + ["Port003", "Port010"], + ["Port003", "Port011"], + ["Port004", "Port010"], + ["Port004", "Port011"], + ["Port004", "Port012"], + ["Port005", "Port011"], + ["Port005", "Port012"], + ["Port005", "Port013"], +]; diff --git a/tests/pathfinding/playground/README.md b/tests/pathfinding/playground/README.md new file mode 100644 index 000000000..7555fd003 --- /dev/null +++ b/tests/pathfinding/playground/README.md @@ -0,0 +1,25 @@ +# Pathfinding Playground + +Interactive web-based visualization tool for exploring and comparing pathfinding algorithms. + +## Usage + +Start the server from the project root: + +```bash +# With path caching (default) +npx tsx tests/pathfinding/playground/server.ts + +# Without path caching +npx tsx tests/pathfinding/playground/server.ts --no-cache +``` + +Then open http://localhost:5555 in your browser. + +## Options + +- `--no-cache` - Disable path caching in NavMesh to measure uncached performance + +## Clanker Disclosure + +The source code of both the UI and the backend is mostly generated by a robot and therefore probably unmaintainable by humans. Since this is meant to be one-off playground project the author has not put additional thought into the inner workings. The UI however is very highly opinionated, if you believe a clanker could do this first pass, you live in the (possibly not far off) future. diff --git a/tests/pathfinding/playground/api/maps.ts b/tests/pathfinding/playground/api/maps.ts new file mode 100644 index 000000000..7d1776931 --- /dev/null +++ b/tests/pathfinding/playground/api/maps.ts @@ -0,0 +1,224 @@ +import { readdirSync, readFileSync } from "fs"; +import { dirname, join } from "path"; +import { fileURLToPath } from "url"; +import { Game } from "../../../../src/core/game/Game.js"; +import { TileRef } from "../../../../src/core/game/GameMap.js"; +import { NavMesh } from "../../../../src/core/pathfinding/navmesh/NavMesh.js"; +import { setupFromPath } from "../../utils.js"; + +export interface MapInfo { + name: string; + displayName: string; +} + +export interface MapCache { + game: Game; + navMesh: NavMesh; +} + +const cache = new Map(); + +/** + * Global configuration for map loading + */ +let config = { + cachePaths: true, +}; + +/** + * Set configuration options + */ +export function setConfig(options: { cachePaths?: boolean }) { + config = { ...config, ...options }; +} + +/** + * Get the resources/maps directory path + */ +function getMapsDirectory(): string { + return join( + dirname(fileURLToPath(import.meta.url)), + "../../../../resources/maps", + ); +} + +/** + * Format map name to title case with proper spacing + * Handles: underscores, camelCase, existing spaces, and parentheses + */ +function formatMapName(name: string): string { + return ( + name + // Replace underscores with spaces + .replace(/_/g, " ") + // Add space before capital letters (for camelCase) + .replace(/([a-z])([A-Z])/g, "$1 $2") + // Convert to lowercase first + .toLowerCase() + // Capitalize first letter of string + .replace(/^\w/, (char) => char.toUpperCase()) + // Capitalize after spaces and opening parentheses + .replace(/(\s+|[(])\w/g, (match) => match.toUpperCase()) + ); +} + +/** + * Get list of available maps by reading the resources/maps directory + */ +export function listMaps(): MapInfo[] { + const mapsDir = getMapsDirectory(); + const maps: MapInfo[] = []; + + try { + const entries = readdirSync(mapsDir, { withFileTypes: true }); + + for (const entry of entries) { + if (entry.isDirectory()) { + const name = entry.name; + let displayName = formatMapName(name); + + // Try to read displayName from manifest.json + try { + const manifestPath = join(mapsDir, name, "manifest.json"); + const manifestData = JSON.parse(readFileSync(manifestPath, "utf-8")); + if (manifestData.name) { + displayName = formatMapName(manifestData.name); + } + } catch (e) { + // If manifest doesn't exist or doesn't have name, use formatted folder name + console.warn( + `Could not read manifest for ${name}:`, + e instanceof Error ? e.message : e, + ); + } + + maps.push({ name, displayName }); + } + } + } catch (e) { + console.error("Failed to read maps directory:", e); + } + + return maps.sort((a, b) => a.displayName.localeCompare(b.displayName)); +} + +/** + * Load a map from cache or disk + */ +export async function loadMap(mapName: string): Promise { + // Check cache first + if (cache.has(mapName)) { + return cache.get(mapName)!; + } + + const mapsDir = getMapsDirectory(); + + // Use the existing setupFromPath utility to load the map + const game = await setupFromPath(mapsDir, mapName); + + // Initialize NavMesh + const navMesh = new NavMesh(game, { cachePaths: config.cachePaths }); + navMesh.initialize(); + + const cacheEntry: MapCache = { game, navMesh }; + + // Store in cache + cache.set(mapName, cacheEntry); + + return cacheEntry; +} + +/** + * Get map metadata for client + */ +export async function getMapMetadata(mapName: string) { + const { game, navMesh } = await loadMap(mapName); + + // Extract map data + const mapData: number[] = []; + for (let y = 0; y < game.height(); y++) { + for (let x = 0; x < game.width(); x++) { + const tile = game.ref(x, y); + mapData.push(game.isWater(tile) ? 1 : 0); + } + } + + // Extract static graph data from NavMesh + const miniMap = game.miniMap(); + const navMeshGraph = (navMesh as any).graph; + + // Convert gateways from Map to array + const gatewaysArray = Array.from(navMeshGraph.gateways.values()); + const allGateways = gatewaysArray.map((gw: any) => ({ + id: gw.id, + x: miniMap.x(gw.tile), + y: miniMap.y(gw.tile), + })); + + // Create a lookup map from gateway ID to gateway for edge conversion + const gatewayById = new Map(gatewaysArray.map((gw: any) => [gw.id, gw])); + + // Convert edges from Map to flat array + // The edges Map has gateway IDs as keys, and arrays of edges as values + const allEdges: any[] = []; + for (const edgeArray of navMeshGraph.edges.values()) { + allEdges.push(...edgeArray); + } + + // Deduplicate edges (they're bidirectional, so each edge appears twice) + const seenEdges = new Set(); + const edges = allEdges + .filter((edge: any) => { + const edgeKey = + edge.from < edge.to + ? `${edge.from}-${edge.to}` + : `${edge.to}-${edge.from}`; + if (seenEdges.has(edgeKey)) return false; + seenEdges.add(edgeKey); + return true; + }) + .map((edge: any) => { + const fromGateway = gatewayById.get(edge.from); + const toGateway = gatewayById.get(edge.to); + + return { + fromId: edge.from, + toId: edge.to, + from: fromGateway + ? [miniMap.x(fromGateway.tile) * 2, miniMap.y(fromGateway.tile) * 2] + : [0, 0], + to: toGateway + ? [miniMap.x(toGateway.tile) * 2, miniMap.y(toGateway.tile) * 2] + : [0, 0], + cost: edge.cost, + path: edge.path + ? edge.path.map((tile: TileRef) => [game.x(tile), game.y(tile)]) + : null, + }; + }); + + console.log( + `Map ${mapName}: ${allGateways.length} gateways, ${edges.length} edges`, + ); + + const sectorSize = navMeshGraph.sectorSize; + + return { + name: mapName, + width: game.width(), + height: game.height(), + mapData, + graphDebug: { + allGateways, + edges, + sectorSize, + }, + }; +} + +/** + * Clear map cache + */ +export function clearCache() { + cache.clear(); +} diff --git a/tests/pathfinding/playground/api/pathfinding.ts b/tests/pathfinding/playground/api/pathfinding.ts new file mode 100644 index 000000000..102e83310 --- /dev/null +++ b/tests/pathfinding/playground/api/pathfinding.ts @@ -0,0 +1,157 @@ +import { TileRef } from "../../../../src/core/game/GameMap.js"; +import { MiniAStarAdapter } from "../../../../src/core/pathfinding/adapters/MiniAStarAdapter.js"; +import { loadMap } from "./maps.js"; + +interface PathfindingOptions { + includePfMini?: boolean; + includeNavMesh?: boolean; +} + +interface NavMeshResult { + path: Array<[number, number]> | null; + initialPath: Array<[number, number]> | null; + gateways: Array<[number, number]> | null; + timings: any; + length: number; + time: number; +} + +interface PfMiniResult { + path: Array<[number, number]> | null; + length: number; + time: number; +} + +// Cache pathfinding adapters per map +const pfMiniCache = new Map(); + +/** + * Get or create MiniAStar adapter for a map + */ +function getPfMiniAdapter(mapName: string, game: any): MiniAStarAdapter { + if (!pfMiniCache.has(mapName)) { + const adapter = new MiniAStarAdapter(game, { waterPath: true }); + pfMiniCache.set(mapName, adapter); + } + return pfMiniCache.get(mapName)!; +} + +/** + * Convert TileRef array to coordinate array + */ +function pathToCoords( + path: TileRef[] | null, + game: any, +): Array<[number, number]> | null { + if (!path) return null; + return path.map((tile) => [game.x(tile), game.y(tile)]); +} + +/** + * Compute pathfinding between two points + */ +export async function computePath( + mapName: string, + from: [number, number], + to: [number, number], + options: PathfindingOptions = {}, +): Promise { + const { game, navMesh: navMeshAdapter } = await loadMap(mapName); + + // Convert coordinates to TileRefs + const fromRef = game.ref(from[0], from[1]); + const toRef = game.ref(to[0], to[1]); + + // Validate that both points are water tiles + if (!game.isWater(fromRef)) { + throw new Error(`Start point (${from[0]}, ${from[1]}) is not water`); + } + if (!game.isWater(toRef)) { + throw new Error(`End point (${to[0]}, ${to[1]}) is not water`); + } + + // Compute NavMesh path + const navMeshPath = navMeshAdapter.findPath(fromRef, toRef, true); + const path = pathToCoords(navMeshPath, game); + + const miniMap = game.miniMap(); + + // Extract debug info + let gateways: Array<[number, number]> | null = null; + let initialPath: Array<[number, number]> | null = null; + let timings: any = {}; + + if (navMeshAdapter.debugInfo) { + // Convert gatewayPath (TileRefs on miniMap) to full map coordinates + if (navMeshAdapter.debugInfo.gatewayPath) { + gateways = navMeshAdapter.debugInfo.gatewayPath.map((tile: TileRef) => { + const x = miniMap.x(tile) * 2; + const y = miniMap.y(tile) * 2; + return [x, y] as [number, number]; + }); + } + + // Convert initial path + if (navMeshAdapter.debugInfo.initialPath) { + initialPath = navMeshAdapter.debugInfo.initialPath.map( + (tile: TileRef) => [game.x(tile), game.y(tile)] as [number, number], + ); + } + + timings = navMeshAdapter.debugInfo.timings || {}; + } + + return { + path, + initialPath, + gateways, + timings, + length: path ? path.length : 0, + time: timings.total ?? 0, + }; +} + +/** + * Compute only PathFinder.Mini path + */ +export async function computePfMiniPath( + mapName: string, + from: [number, number], + to: [number, number], +): Promise { + const { game } = await loadMap(mapName); + + // Convert coordinates to TileRefs + const fromRef = game.ref(from[0], from[1]); + const toRef = game.ref(to[0], to[1]); + + // Validate that both points are water tiles + if (!game.isWater(fromRef)) { + throw new Error(`Start point (${from[0]}, ${from[1]}) is not water`); + } + if (!game.isWater(toRef)) { + throw new Error(`End point (${to[0]}, ${to[1]}) is not water`); + } + + // Compute PathFinder.Mini path + const pfMiniAdapter = getPfMiniAdapter(mapName, game); + const pfMiniStart = performance.now(); + const pfMiniPath = pfMiniAdapter.findPath(fromRef, toRef); + const pfMiniEnd = performance.now(); + + const path = pathToCoords(pfMiniPath, game); + const time = pfMiniEnd - pfMiniStart; + + return { + path, + length: path ? path.length : 0, + time, + }; +} + +/** + * Clear pathfinding adapter caches + */ +export function clearAdapterCaches() { + pfMiniCache.clear(); +} diff --git a/tests/pathfinding/playground/public/client.js b/tests/pathfinding/playground/public/client.js new file mode 100644 index 000000000..48a222786 --- /dev/null +++ b/tests/pathfinding/playground/public/client.js @@ -0,0 +1,1569 @@ +// Application State +const state = { + currentMap: null, + mapData: null, + mapWidth: 0, + mapHeight: 0, + startPoint: null, + endPoint: null, + navMeshPath: null, + navMeshResult: null, // Store full NavMesh result including timing + pfMiniPath: null, + pfMiniResult: null, // Store full PF.Mini result including timing + graphDebug: null, // Static graph data (gateways, edges, sectorSize) - loaded once per map + debugInfo: null, // Per-path debug data (timings, gatewayWaypoints, initialPath) + isMapLoading: false, // Loading state for map switching + isNavMeshLoading: false, // Separate loading state for NavMesh + isPfMiniLoading: false, // Separate loading state for PF.Mini + showPfMini: false, + activeRefreshButton: null, // Track which refresh button is spinning +}; + +// Canvas state +let zoomLevel = 1.0; +let panX = 0; +let panY = 0; +let isDragging = false; +let dragStartX = 0; +let dragStartY = 0; +let dragStartPanX = 0; +let dragStartPanY = 0; + +let mapCanvas, overlayCanvas, interactiveCanvas; +let mapCtx, overlayCtx, interactiveCtx; +let mapRendered = false; +let hoveredGateway = null; +let hoveredPoint = null; // 'start', 'end', or null +let draggingPoint = null; // 'start', 'end', or null +let draggingPointPosition = null; // [x, y] canvas position while dragging +let lastPathRecalcTime = 0; +let renderRequested = false; + +// Save current state to URL query string +function updateURLState() { + const params = new URLSearchParams(); + + if (state.currentMap) { + params.set("map", state.currentMap); + } + if (state.startPoint) { + params.set("start", `${state.startPoint[0]},${state.startPoint[1]}`); + } + if (state.endPoint) { + params.set("end", `${state.endPoint[0]},${state.endPoint[1]}`); + } + + const newURL = `${window.location.pathname}?${params.toString()}`; + window.history.replaceState({}, "", newURL); +} + +// Restore state from URL query string +function restoreFromURL() { + const params = new URLSearchParams(window.location.search); + + const mapName = params.get("map"); + const startStr = params.get("start"); + const endStr = params.get("end"); + + const result = { + map: mapName, + start: null, + end: null, + }; + + if (startStr) { + const [x, y] = startStr.split(",").map(Number); + if (!isNaN(x) && !isNaN(y)) { + result.start = [x, y]; + } + } + + if (endStr) { + const [x, y] = endStr.split(",").map(Number); + if (!isNaN(x) && !isNaN(y)) { + result.end = [x, y]; + } + } + + return result; +} + +// Initialize on DOM load +window.addEventListener("DOMContentLoaded", () => { + initializeCanvases(); + initializeControls(); + initializeDragControls(); + initializeTimingsPanel(); + loadMaps(); +}); + +// Initialize canvas elements +function initializeCanvases() { + mapCanvas = document.getElementById("mapCanvas"); + mapCtx = mapCanvas.getContext("2d"); + + overlayCanvas = document.getElementById("overlayCanvas"); + overlayCtx = overlayCanvas.getContext("2d"); + + // Create interactive canvas OUTSIDE the CSS transform wrapper + // This canvas is viewport-sized and renders paths/points at screen coordinates + const canvasContainer = document.querySelector(".canvas-container"); + interactiveCanvas = document.createElement("canvas"); + interactiveCanvas.id = "interactiveCanvas"; + interactiveCanvas.style.position = "absolute"; + interactiveCanvas.style.top = "0"; + interactiveCanvas.style.left = "0"; + interactiveCanvas.style.width = "100%"; + interactiveCanvas.style.height = "100%"; + interactiveCanvas.style.zIndex = "3"; + interactiveCanvas.style.pointerEvents = "none"; + canvasContainer.appendChild(interactiveCanvas); + interactiveCtx = interactiveCanvas.getContext("2d"); + + // Size interactive canvas to viewport + const resizeInteractiveCanvas = () => { + const rect = canvasContainer.getBoundingClientRect(); + interactiveCanvas.width = rect.width; + interactiveCanvas.height = rect.height; + }; + resizeInteractiveCanvas(); + window.addEventListener("resize", resizeInteractiveCanvas); +} + +// Initialize control event listeners +function initializeControls() { + // Map selector (top panel) + document.getElementById("scenarioSelect").addEventListener("change", (e) => { + switchMap(e.target.value); + }); + + // Map selector (welcome screen) + document + .getElementById("welcomeMapSelect") + .addEventListener("change", (e) => { + const mapName = e.target.value; + if (mapName) { + switchMap(mapName); + } + }); + + // PF.Mini request button + document.getElementById("requestPfMini").addEventListener("click", () => { + if ( + state.startPoint && + state.endPoint && + !state.pfMiniPath && + !state.isPfMiniLoading + ) { + state.showPfMini = true; + requestPfMiniOnly(state.startPoint, state.endPoint); + } + }); + + // Refresh NavMesh button + document.getElementById("refreshNavMesh").addEventListener("click", (e) => { + if (state.startPoint && state.endPoint) { + const btn = e.currentTarget; + btn.classList.add("spinning"); + state.activeRefreshButton = btn; + requestPathfinding(state.startPoint, state.endPoint); + } + }); + + // Refresh PF.Mini button + document.getElementById("refreshPfMini").addEventListener("click", (e) => { + if (state.startPoint && state.endPoint && state.pfMiniPath) { + const btn = e.currentTarget; + btn.classList.add("spinning"); + state.activeRefreshButton = btn; + requestPfMiniOnly(state.startPoint, state.endPoint); + } + }); + + // Visualization toggles - all buttons + [ + "showInitialPath", + "showUsedGateways", + "showColoredMap", + "showGateways", + "showSectorGrid", + "showEdges", + ].forEach((id) => { + const button = document.getElementById(id); + button.addEventListener("click", () => { + const isActive = button.dataset.active === "true"; + button.dataset.active = !isActive; + // Map coloring affects map canvas + if (id === "showColoredMap") { + renderMapBackground(2); + } + // Static overlays (sectors, edges, all gateways) go on overlay canvas + if (["showGateways", "showSectorGrid", "showEdges"].includes(id)) { + renderOverlay(2); + } + // Dynamic elements (paths, highlighted gateways) go on interactive canvas + renderInteractive(); + }); + }); + + // Zoom control + document.getElementById("zoom").addEventListener("input", (e) => { + zoomLevel = parseFloat(e.target.value); + document.getElementById("zoomValue").textContent = + zoomLevel.toFixed(1) + "x"; + updateTransform(); + }); + + // Clear points button + document.getElementById("clearPoints").addEventListener("click", () => { + clearPoints(); + }); +} + +// Helper function to check if mouse is over a start/end point +function getPointAtPosition(canvasX, canvasY) { + const scale = zoomLevel; + const zoomFactor = 3 / zoomLevel; + const hitRadius = Math.max(4, scale * 3 * zoomFactor) + 3; // Add 3px tolerance + + // Check end point first (render on top) + if (state.endPoint) { + const dx = canvasX - (state.endPoint[0] + 0.5); + const dy = canvasY - (state.endPoint[1] + 0.5); + const distance = Math.sqrt(dx * dx + dy * dy); + if (distance <= hitRadius / scale) { + return "end"; + } + } + + // Check start point + if (state.startPoint) { + const dx = canvasX - (state.startPoint[0] + 0.5); + const dy = canvasY - (state.startPoint[1] + 0.5); + const distance = Math.sqrt(dx * dx + dy * dy); + if (distance <= hitRadius / scale) { + return "start"; + } + } + + return null; +} + +// Throttled path recalculation (max once per 16ms ~60fps) +function schedulePathRecalc() { + const now = Date.now(); + const timeSinceLastCall = now - lastPathRecalcTime; + + if (timeSinceLastCall >= 16) { + // Enough time has passed, request immediately + lastPathRecalcTime = now; + if (state.startPoint && state.endPoint) { + requestPathfinding(state.startPoint, state.endPoint); + } + } + // If not enough time has passed, skip this call (throttle) +} + +// Initialize drag and click controls +function initializeDragControls() { + const wrapper = document.getElementById("canvasWrapper"); + const tooltip = document.getElementById("tooltip"); + + wrapper.addEventListener("mousedown", (e) => { + const rect = wrapper.getBoundingClientRect(); + const canvasX = (e.clientX - rect.left - panX) / zoomLevel; + const canvasY = (e.clientY - rect.top - panY) / zoomLevel; + + // Check if clicking on a point + const pointAtMouse = getPointAtPosition(canvasX, canvasY); + + if (pointAtMouse) { + // Start dragging the point + draggingPoint = pointAtMouse; + wrapper.style.cursor = "move"; + + // Invalidate PF.Mini path since we're changing the route + state.pfMiniPath = null; + state.pfMiniResult = null; + updatePfMiniButton(); + } else { + // Start panning the map + isDragging = true; + wrapper.style.cursor = "grabbing"; + } + + dragStartX = e.clientX; + dragStartY = e.clientY; + dragStartPanX = panX; + dragStartPanY = panY; + }); + + wrapper.addEventListener("mousemove", (e) => { + const rect = wrapper.getBoundingClientRect(); + const canvasX = (e.clientX - rect.left - panX) / zoomLevel; + const canvasY = (e.clientY - rect.top - panY) / zoomLevel; + + if (draggingPoint) { + // Dragging a start/end point - snap to water tile + const tileX = Math.floor(canvasX); + const tileY = Math.floor(canvasY); + + // Validate tile is within bounds and is water + if ( + tileX >= 0 && + tileX < state.mapWidth && + tileY >= 0 && + tileY < state.mapHeight + ) { + const tileIndex = tileY * state.mapWidth + tileX; + const isWater = state.mapData[tileIndex] === 1; + + if (isWater) { + // Snap to water tile center + draggingPointPosition = [tileX, tileY]; + + // Update the actual point position and trigger throttled path recalculation + if (draggingPoint === "start") { + state.startPoint = [tileX, tileY]; + } else { + state.endPoint = [tileX, tileY]; + } + + // Trigger throttled path recalculation (16ms) + if (state.startPoint && state.endPoint) { + schedulePathRecalc(); + } + } + // If not water, keep previous valid position (don't update) + } + + renderInteractive(); + } else if (isDragging) { + // Panning the map + const dx = e.clientX - dragStartX; + const dy = e.clientY - dragStartY; + panX = dragStartPanX + dx; + panY = dragStartPanY + dy; + updateTransform(); // Updates interactive layer at screen coordinates + } else { + // Check for point hover + const pointAtMouse = getPointAtPosition(canvasX, canvasY); + if (pointAtMouse !== hoveredPoint) { + hoveredPoint = pointAtMouse; + renderInteractive(); // Fast - only redraws points + // Update cursor + wrapper.style.cursor = hoveredPoint ? "move" : "grab"; + } + + // Check for gateway hover (only if gateway visualization is enabled) + const showGateways = + document.getElementById("showGateways").dataset.active === "true"; + const showUsedGateways = + document.getElementById("showUsedGateways").dataset.active === "true"; + + if ( + (showGateways || showUsedGateways) && + state.graphDebug && + state.graphDebug.allGateways + ) { + // Filter gateways based on what's visible + let gatewaysToCheck = state.graphDebug.allGateways; + if ( + showUsedGateways && + !showGateways && + state.debugInfo && + state.debugInfo.gatewayWaypoints + ) { + // Only show tooltips for used gateways + // gatewayWaypoints are coordinates [x, y] matching the map format + const usedGatewayCoords = new Set( + state.debugInfo.gatewayWaypoints.map(([x, y]) => `${x},${y}`), + ); + gatewaysToCheck = state.graphDebug.allGateways.filter((gw) => + usedGatewayCoords.has(`${gw.x * 2},${gw.y * 2}`), + ); + } + + const foundGateway = findGatewayAtPosition( + canvasX, + canvasY, + gatewaysToCheck, + ); + + if (foundGateway !== hoveredGateway) { + hoveredGateway = foundGateway; + if (hoveredGateway) { + showGatewayTooltip(hoveredGateway, e.clientX, e.clientY); + } else { + tooltip.classList.remove("visible"); + } + renderInteractive(); + } else if (hoveredGateway) { + tooltip.style.left = e.clientX + 15 + "px"; + tooltip.style.top = e.clientY + 15 + "px"; + } + } else { + // No gateway visualization enabled, clear any existing tooltip + if (hoveredGateway) { + hoveredGateway = null; + tooltip.classList.remove("visible"); + renderInteractive(); + } + } + } + }); + + wrapper.addEventListener("mouseup", (e) => { + // Only treat as click if mouse didn't move much + const dx = Math.abs(e.clientX - dragStartX); + const dy = Math.abs(e.clientY - dragStartY); + + if (draggingPoint) { + // Finished dragging a point + // Request final path update to ensure we have the path for the final position + // (in case throttling skipped the last update during fast dragging) + if (state.startPoint && state.endPoint) { + requestPathfinding(state.startPoint, state.endPoint); + } + draggingPoint = null; + draggingPointPosition = null; + renderInteractive(); + updateURLState(); + } else if (isDragging && dx < 5 && dy < 5) { + // Was panning but didn't move much - treat as click + handleMapClick(e); + } + + isDragging = false; + + // Reset cursor based on current hover state + const rect = wrapper.getBoundingClientRect(); + const canvasX = (e.clientX - rect.left - panX) / zoomLevel; + const canvasY = (e.clientY - rect.top - panY) / zoomLevel; + const pointAtMouse = getPointAtPosition(canvasX, canvasY); + wrapper.style.cursor = pointAtMouse ? "move" : "grab"; + }); + + wrapper.addEventListener("mouseleave", () => { + isDragging = false; + draggingPoint = null; + draggingPointPosition = null; + tooltip.classList.remove("visible"); + wrapper.style.cursor = "grab"; + + const needsRender = hoveredGateway || hoveredPoint; + hoveredGateway = null; + hoveredPoint = null; + + if (needsRender) { + renderInteractive(); + } + }); + + wrapper.addEventListener("wheel", (e) => { + e.preventDefault(); + + const rect = wrapper.getBoundingClientRect(); + const mouseX = e.clientX - rect.left; + const mouseY = e.clientY - rect.top; + + const oldZoom = zoomLevel; + const zoomDelta = e.deltaY > 0 ? 0.9 : 1.1; + zoomLevel = Math.max(0.1, Math.min(5, zoomLevel * zoomDelta)); + + panX = mouseX - (mouseX - panX) * (zoomLevel / oldZoom); + panY = mouseY - (mouseY - panY) * (zoomLevel / oldZoom); + + document.getElementById("zoom").value = zoomLevel; + document.getElementById("zoomValue").textContent = zoomLevel.toFixed(1); + + updateTransform(); + renderInteractive(); + }); +} + +// Initialize timings panel to default state +function initializeTimingsPanel() { + // Set initial state to match "no path" state + updateTimingsPanel({ navMesh: null, pfMini: null }); + updatePfMiniButton(); +} + +// Handle map clicks for point selection +function handleMapClick(e) { + if ( + !state.currentMap || + state.isMapLoading || + state.isNavMeshLoading || + state.isPfMiniLoading + ) + return; + + const wrapper = document.getElementById("canvasWrapper"); + const rect = wrapper.getBoundingClientRect(); + + // Convert screen coordinates to tile coordinates + const canvasX = (e.clientX - rect.left - panX) / zoomLevel; + const canvasY = (e.clientY - rect.top - panY) / zoomLevel; + const tileX = Math.floor(canvasX); + const tileY = Math.floor(canvasY); + + // Validate coordinates + if ( + tileX < 0 || + tileX >= state.mapWidth || + tileY < 0 || + tileY >= state.mapHeight + ) { + return; + } + + // Check if tile is water + const index = tileY * state.mapWidth + tileX; + const isWater = state.mapData[index] === 1; + + if (!isWater) { + showError("Selected point must be on water"); + return; + } + + // Point selection state machine + if (!state.startPoint) { + // Set start point + state.startPoint = [tileX, tileY]; + updatePointDisplay(); + renderInteractive(); + updateURLState(); + } else if (!state.endPoint) { + // Set end point and trigger pathfinding + state.endPoint = [tileX, tileY]; + updatePointDisplay(); + renderInteractive(); + updateURLState(); + requestPathfinding(state.startPoint, state.endPoint); + } else { + // Reset and set new start point + clearPoints(); + state.startPoint = [tileX, tileY]; + updatePointDisplay(); + renderInteractive(); + updateURLState(); + } +} + +// Clear selected points +function clearPoints() { + state.startPoint = null; + state.endPoint = null; + state.navMeshPath = null; + state.navMeshResult = null; + state.pfMiniPath = null; + state.pfMiniResult = null; + state.debugInfo = null; + state.showPfMini = false; + updatePointDisplay(); + hidePathInfo(); + updatePfMiniButton(); + updateURLState(); // Remove points from URL + renderInteractive(); +} + +// Update transform for pan/zoom +function updateTransform() { + const transform = `translate(${panX}px, ${panY}px) scale(${zoomLevel})`; + mapCanvas.style.transform = transform; + overlayCanvas.style.transform = transform; + // Interactive canvas is outside the transform - update it separately + renderInteractive(); +} + +// Load available maps +async function loadMaps() { + setStatus("Loading maps...", true); + + try { + const response = await fetch("/api/maps"); + if (!response.ok) throw new Error("Failed to load maps"); + + const data = await response.json(); + + // Featured maps to show in grid (in order) + const featuredMapNames = [ + "giantworldmap", + "northamerica", + "southamerica", + "europe", + "asia", + "straitofgibraltar", + "manicouagan", + "mars", + ]; + + // Get featured maps in the specified order + const gridMaps = featuredMapNames + .map((name) => data.maps.find((m) => m.name === name)) + .filter((map) => map !== undefined); + + // Populate map grid with featured maps - update placeholders + gridMaps.forEach((map, index) => { + const card = document.querySelector(`[data-map-index="${index}"]`); + if (!card) return; + + // Update click handler + card.onclick = () => switchMap(map.name); + + // Update image + const img = card.querySelector("img"); + if (img) { + img.src = `/api/maps/${encodeURIComponent(map.name)}/thumbnail`; + img.alt = map.displayName; + } + + // Update name + const nameEl = card.querySelector(".map-card-name"); + if (nameEl) { + nameEl.textContent = map.displayName; + nameEl.style.opacity = "1"; + } + }); + + // Populate both selectors (all maps) + const topSelect = document.getElementById("scenarioSelect"); + const welcomeSelect = document.getElementById("welcomeMapSelect"); + + topSelect.innerHTML = ''; + welcomeSelect.innerHTML = ''; + + data.maps.forEach((map) => { + // Top panel selector + const topOption = document.createElement("option"); + topOption.value = map.name; + topOption.textContent = map.displayName; + topSelect.appendChild(topOption); + + // Welcome screen selector + const welcomeOption = document.createElement("option"); + welcomeOption.value = map.name; + welcomeOption.textContent = map.displayName; + welcomeSelect.appendChild(welcomeOption); + }); + + setStatus("Select a map to begin"); + + // Restore state from URL if present + const urlState = restoreFromURL(); + if (urlState.map) { + // Load the map from URL + await switchMap(urlState.map, true); // Restore points from URL + + // Points will be restored in switchMap after the map loads + } + } catch (error) { + showError(`Failed to load maps: ${error.message}`); + } +} + +// Switch to a different map +async function switchMap(mapName, restorePointsFromURL = false) { + if (!mapName) return; + + setStatus("Loading map...", true); + state.isMapLoading = true; + + try { + const response = await fetch(`/api/maps/${encodeURIComponent(mapName)}`); + if (!response.ok) throw new Error("Failed to load map"); + + const data = await response.json(); + + // Update state + state.currentMap = mapName; + state.mapWidth = data.width; + state.mapHeight = data.height; + state.mapData = data.mapData; + state.graphDebug = data.graphDebug; // Store static graph debug data + + // Clear paths (but don't update URL yet if we're restoring from URL) + state.startPoint = null; + state.endPoint = null; + state.navMeshPath = null; + state.navMeshResult = null; + state.pfMiniPath = null; + state.pfMiniResult = null; + state.debugInfo = null; + state.showPfMini = false; + updatePointDisplay(); + hidePathInfo(); + updatePfMiniButton(); + + // Size canvases + mapCanvas.width = state.mapWidth * 2; + mapCanvas.height = state.mapHeight * 2; + mapCanvas.style.width = `${state.mapWidth}px`; + mapCanvas.style.height = `${state.mapHeight}px`; + + overlayCanvas.width = state.mapWidth * 2; + overlayCanvas.height = state.mapHeight * 2; + overlayCanvas.style.width = `${state.mapWidth}px`; + overlayCanvas.style.height = `${state.mapHeight}px`; + + // Render map and overlays + renderMapBackground(2); + renderOverlay(2); + renderInteractive(); + + // Reset view + zoomLevel = 1.0; + panX = 0; + panY = 0; + document.getElementById("zoom").value = 1.0; + document.getElementById("zoomValue").textContent = "1.0"; + updateTransform(); + + // Hide welcome screen + hideWelcomeScreen(); + + // Sync both selectors + document.getElementById("scenarioSelect").value = mapName; + document.getElementById("welcomeMapSelect").value = mapName; + + setStatus("Click on map to set start point"); + mapRendered = true; + + // Restore start/end points from URL if requested (initial page load) + if (restorePointsFromURL) { + const urlState = restoreFromURL(); + if (urlState.start) { + const [x, y] = urlState.start; + if (x >= 0 && x < state.mapWidth && y >= 0 && y < state.mapHeight) { + const tileIndex = y * state.mapWidth + x; + const isWater = state.mapData[tileIndex] === 1; + if (isWater) { + state.startPoint = [x, y]; + } + } + } + if (urlState.end) { + const [x, y] = urlState.end; + if (x >= 0 && x < state.mapWidth && y >= 0 && y < state.mapHeight) { + const tileIndex = y * state.mapWidth + x; + const isWater = state.mapData[tileIndex] === 1; + if (isWater) { + state.endPoint = [x, y]; + } + } + } + + // If both points are set, request pathfinding + if (state.startPoint && state.endPoint) { + renderInteractive(); + requestPathfinding(state.startPoint, state.endPoint); + } + } else { + // User manually switched maps - update URL to clear points + updateURLState(); + } + } catch (error) { + showError(`Failed to load map: ${error.message}`); + } finally { + state.isMapLoading = false; + } +} + +// Show/hide welcome screen +function showWelcomeScreen() { + document.getElementById("welcomeScreen").classList.remove("hidden"); +} + +function hideWelcomeScreen() { + document.getElementById("welcomeScreen").classList.add("hidden"); +} + +// Request pathfinding computation (NavMesh only) +async function requestPathfinding(from, to) { + setStatus("Computing path...", true); + state.isNavMeshLoading = true; + + try { + const response = await fetch("/api/pathfind", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + map: state.currentMap, + from, + to, + }), + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.message || "Pathfinding failed"); + } + + const result = await response.json(); + + // Update state + state.navMeshPath = result.path; + state.navMeshResult = result; // Store full result for later use + // Don't reset pfMiniPath - preserve it across NavMesh refreshes + state.debugInfo = { + initialPath: result.initialPath, + gatewayWaypoints: result.gateways, + timings: result.timings, + }; + + // Update UI - preserve existing PF.Mini if it exists + updatePathInfo({ navMesh: result, pfMini: state.pfMiniResult }); + renderInteractive(); + + setStatus("Path computed successfully"); + } catch (error) { + showError(`Pathfinding failed: ${error.message}`); + } finally { + state.isNavMeshLoading = false; + // Stop refresh button spinning + if (state.activeRefreshButton) { + state.activeRefreshButton.classList.remove("spinning"); + state.activeRefreshButton = null; + } + } +} + +// Request PF.Mini computation only (without re-computing NavMesh) +async function requestPfMiniOnly(from, to) { + setStatus("Computing PF.Mini path...", true); + state.isPfMiniLoading = true; + updatePfMiniButton(); // Update button to show loading state + + try { + const response = await fetch("/api/pathfind-pfmini", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + map: state.currentMap, + from, + to, + }), + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.message || "Pathfinding failed"); + } + + const result = await response.json(); + + // Update only PF.Mini path (preserve existing NavMesh path and debug info) + state.pfMiniPath = result.path; + state.pfMiniResult = result; // Store full result + + // Update UI (preserve existing NavMesh result) + updatePathInfo({ navMesh: state.navMeshResult, pfMini: result }); + renderInteractive(); + + setStatus("PF.Mini path computed successfully"); + } catch (error) { + showError(`PF.Mini pathfinding failed: ${error.message}`); + } finally { + state.isPfMiniLoading = false; + // Stop refresh button spinning + if (state.activeRefreshButton) { + state.activeRefreshButton.classList.remove("spinning"); + state.activeRefreshButton = null; + } + // Update button state + updatePfMiniButton(); + } +} + +// Update point display +function updatePointDisplay() { + updatePfMiniButton(); +} + +// Update PF.Mini button state +function updatePfMiniButton() { + const button = document.getElementById("requestPfMini"); + const requestSection = document.getElementById("pfMiniRequestSection"); + + if (state.pfMiniPath) { + // Hide button when PF.Mini is already computed + requestSection.style.display = "none"; + } else if (state.isPfMiniLoading && !state.activeRefreshButton) { + // Show loading spinner when computing PF.Mini (not a refresh) + requestSection.style.display = "block"; + button.disabled = true; + button.innerHTML = 'Computing... '; + } else if (state.startPoint && state.endPoint && state.navMeshPath) { + // Show and enable button when points are set and NavMesh path exists + requestSection.style.display = "block"; + button.disabled = false; + button.textContent = "Request PathFinder.Mini"; + } else { + // Show but disable button when points aren't set + requestSection.style.display = "block"; + button.disabled = true; + button.textContent = "Request PathFinder.Mini"; + } +} + +// Update path info in UI +function updatePathInfo(result) { + // Update PF.Mini legend visibility + if (result.pfMini) { + document.getElementById("pfMiniLegend").style.display = "flex"; + } else { + document.getElementById("pfMiniLegend").style.display = "none"; + } + + // Update timings panel + updateTimingsPanel(result); + + // Update PF.Mini button + updatePfMiniButton(); +} + +// Update the dedicated timings panel +function updateTimingsPanel(result) { + const navMesh = result.navMesh; + + // Show NavMesh time and path length (or 0.00 in light gray if no data) + const navMeshTimeEl = document.getElementById("navMeshTime"); + if (navMesh && navMesh.time > 0) { + navMeshTimeEl.textContent = `${navMesh.time.toFixed(2)}ms`; + navMeshTimeEl.classList.remove("faded"); + } else { + navMeshTimeEl.textContent = "0.00ms"; + navMeshTimeEl.classList.add("faded"); + } + + const navMeshTilesEl = document.getElementById("navMeshTiles"); + if (navMesh && navMesh.length > 0) { + navMeshTilesEl.textContent = `- ${navMesh.length} tiles`; + } else { + navMeshTilesEl.textContent = ""; + } + + // Show timing breakdown - always visible with gray dashes when no data + const timings = navMesh && navMesh.timings ? navMesh.timings : {}; + + // Early Exit + const earlyExitEl = document.getElementById("timingEarlyExit"); + const earlyExitValueEl = document.getElementById("timingEarlyExitValue"); + earlyExitEl.style.display = "flex"; + if (timings.earlyExitLocalPath !== undefined) { + earlyExitValueEl.textContent = `${timings.earlyExitLocalPath.toFixed(2)}ms`; + earlyExitValueEl.style.color = "#f5f5f5"; + } else { + earlyExitValueEl.textContent = "—"; + earlyExitValueEl.style.color = "#666"; + } + + // Find Gateways + const findGatewaysEl = document.getElementById("timingFindGateways"); + const findGatewaysValueEl = document.getElementById( + "timingFindGatewaysValue", + ); + findGatewaysEl.style.display = "flex"; + if (timings.findGateways !== undefined) { + findGatewaysValueEl.textContent = `${timings.findGateways.toFixed(2)}ms`; + findGatewaysValueEl.style.color = "#f5f5f5"; + } else { + findGatewaysValueEl.textContent = "—"; + findGatewaysValueEl.style.color = "#666"; + } + + // Gateway Path + const gatewayPathEl = document.getElementById("timingGatewayPath"); + const gatewayPathValueEl = document.getElementById("timingGatewayPathValue"); + gatewayPathEl.style.display = "flex"; + if (timings.findGatewayPath !== undefined) { + gatewayPathValueEl.textContent = `${timings.findGatewayPath.toFixed(2)}ms`; + gatewayPathValueEl.style.color = "#f5f5f5"; + } else { + gatewayPathValueEl.textContent = "—"; + gatewayPathValueEl.style.color = "#666"; + } + + // Initial Path + const initialPathEl = document.getElementById("timingInitialPath"); + const initialPathValueEl = document.getElementById("timingInitialPathValue"); + initialPathEl.style.display = "flex"; + if (timings.buildInitialPath !== undefined) { + initialPathValueEl.textContent = `${timings.buildInitialPath.toFixed(2)}ms`; + initialPathValueEl.style.color = "#f5f5f5"; + } else { + initialPathValueEl.textContent = "—"; + initialPathValueEl.style.color = "#666"; + } + + // Smooth Path + const smoothPathEl = document.getElementById("timingSmoothPath"); + const smoothPathValueEl = document.getElementById("timingSmoothPathValue"); + smoothPathEl.style.display = "flex"; + if (timings.buildSmoothPath !== undefined) { + smoothPathValueEl.textContent = `${timings.buildSmoothPath.toFixed(2)}ms`; + smoothPathValueEl.style.color = "#f5f5f5"; + } else { + smoothPathValueEl.textContent = "—"; + smoothPathValueEl.style.color = "#666"; + } + + // Show PF.Mini time and speedup if available + if (result.pfMini && result.pfMini.time > 0) { + const pfMiniTimeEl = document.getElementById("pfMiniTime"); + pfMiniTimeEl.textContent = `${result.pfMini.time.toFixed(2)}ms`; + pfMiniTimeEl.classList.remove("faded"); + + document.getElementById("pfMiniTiles").textContent = + `- ${result.pfMini.length} tiles`; + document.getElementById("pfMiniTimingSection").style.display = "block"; + + // Calculate and show speedup + if (navMesh && navMesh.time > 0) { + const speedup = result.pfMini.time / navMesh.time; + document.getElementById("speedupValue").textContent = + `${speedup.toFixed(1)}x`; + document.getElementById("speedupSection").style.display = "block"; + } else { + document.getElementById("speedupSection").style.display = "none"; + } + } else if (result.pfMini) { + // PF.Mini exists but time is 0 + const pfMiniTimeEl = document.getElementById("pfMiniTime"); + pfMiniTimeEl.textContent = "—"; + pfMiniTimeEl.classList.add("faded"); + document.getElementById("pfMiniTiles").textContent = ""; + document.getElementById("pfMiniTimingSection").style.display = "block"; + document.getElementById("speedupSection").style.display = "none"; + } else { + document.getElementById("pfMiniTimingSection").style.display = "none"; + document.getElementById("speedupSection").style.display = "none"; + } +} + +// Reset path info to show dashes +function hidePathInfo() { + // Don't hide the panel, just reset to show dashes + updateTimingsPanel({ navMesh: null, pfMini: null }); +} + +// Set status message +function setStatus(message, loading = false) { + const statusEl = document.getElementById("status"); + statusEl.textContent = message; + statusEl.className = loading ? "loading" : ""; +} + +// Show error message +function showError(message) { + const errorEl = document.getElementById("error"); + errorEl.textContent = message; + errorEl.classList.add("visible"); + setTimeout(() => { + errorEl.classList.remove("visible"); + }, 5000); + setStatus(message, false); +} + +// Render map background +function renderMapBackground(scale) { + mapCanvas.width = state.mapWidth * scale; + mapCanvas.height = state.mapHeight * scale; + mapCanvas.style.width = `${state.mapWidth}px`; + mapCanvas.style.height = `${state.mapHeight}px`; + + // Use ImageData for much faster rendering + const imageData = mapCtx.createImageData( + state.mapWidth * scale, + state.mapHeight * scale, + ); + const data = imageData.data; + + // Check if colored map is enabled + const showColored = + document.getElementById("showColoredMap").dataset.active === "true"; + + let waterR, waterG, waterB, landR, landG, landB; + + if (showColored) { + // Colored: Water = #2a5c8a (darker blue), Land = #a1bb75 + waterR = 42; + waterG = 92; + waterB = 138; + landR = 161; + landG = 187; + landB = 117; + } else { + // Grayscale: Water = #3c3c3c (darker gray), Land = #777777 (slightly darker) + waterR = 60; + waterG = 60; + waterB = 60; + landR = 119; + landG = 119; + landB = 119; + } + + for (let y = 0; y < state.mapHeight; y++) { + for (let x = 0; x < state.mapWidth; x++) { + const mapIndex = y * state.mapWidth + x; + const isWater = state.mapData[mapIndex] === 1; + + const r = isWater ? waterR : landR; + const g = isWater ? waterG : landG; + const b = isWater ? waterB : landB; + + // Fill all pixels for this tile (scale x scale block) + for (let dy = 0; dy < scale; dy++) { + for (let dx = 0; dx < scale; dx++) { + const px = x * scale + dx; + const py = y * scale + dy; + const pixelIndex = (py * state.mapWidth * scale + px) * 4; + + data[pixelIndex] = r; + data[pixelIndex + 1] = g; + data[pixelIndex + 2] = b; + data[pixelIndex + 3] = 255; // Alpha + } + } + } + } + + mapCtx.putImageData(imageData, 0, 0); +} + +// Render static debug overlays (sectors, edges, all gateways) at map scale +function renderOverlay(scale) { + overlayCtx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height); + + if (!state.mapData || !state.graphDebug) return; + + const showSectorGrid = + document.getElementById("showSectorGrid").dataset.active === "true"; + const showEdges = + document.getElementById("showEdges").dataset.active === "true"; + const showGateways = + document.getElementById("showGateways").dataset.active === "true"; + + // Draw sector grid (sectorSize is in mini map coords, scale 2x for real map) + if (showSectorGrid && state.graphDebug.sectorSize) { + const sectorSize = state.graphDebug.sectorSize * 2; + overlayCtx.strokeStyle = "#777777"; + overlayCtx.lineWidth = scale * 0.5; + overlayCtx.globalAlpha = 0.7; + overlayCtx.setLineDash([5 * scale, 5 * scale]); + + // Vertical lines + for (let x = 0; x <= state.mapWidth; x += sectorSize) { + overlayCtx.beginPath(); + overlayCtx.moveTo(x * scale, 0); + overlayCtx.lineTo(x * scale, state.mapHeight * scale); + overlayCtx.stroke(); + } + + // Horizontal lines + for (let y = 0; y <= state.mapHeight; y += sectorSize) { + overlayCtx.beginPath(); + overlayCtx.moveTo(0, y * scale); + overlayCtx.lineTo(state.mapWidth * scale, y * scale); + overlayCtx.stroke(); + } + + overlayCtx.setLineDash([]); + overlayCtx.globalAlpha = 1.0; + } + + // Draw edges + if (showEdges && state.graphDebug.edges) { + overlayCtx.strokeStyle = "#00ff88"; + overlayCtx.lineWidth = scale * 0.5; + overlayCtx.globalAlpha = 0.4; + + for (const edge of state.graphDebug.edges) { + overlayCtx.beginPath(); + overlayCtx.moveTo( + (edge.from[0] + 0.5) * scale, + (edge.from[1] + 0.5) * scale, + ); + overlayCtx.lineTo((edge.to[0] + 0.5) * scale, (edge.to[1] + 0.5) * scale); + overlayCtx.stroke(); + } + + overlayCtx.globalAlpha = 1.0; + } + + // Draw all gateways + if (showGateways && state.graphDebug.allGateways) { + overlayCtx.fillStyle = "#aaaaaa"; + const gatewayRadius = scale * 1.5; + + for (const gw of state.graphDebug.allGateways) { + overlayCtx.beginPath(); + overlayCtx.arc( + (gw.x * 2 + 0.5) * scale, + (gw.y * 2 + 0.5) * scale, + gatewayRadius, + 0, + Math.PI * 2, + ); + overlayCtx.fill(); + } + } +} + +// Convert map coordinates to screen coordinates +function mapToScreen(mapX, mapY) { + return { + x: mapX * zoomLevel + panX, + y: mapY * zoomLevel + panY, + }; +} + +// Render truly interactive/dynamic overlay (paths, points, highlights) at screen coordinates +function renderInteractive() { + // Clear viewport-sized canvas (super fast!) + interactiveCtx.clearRect( + 0, + 0, + interactiveCanvas.width, + interactiveCanvas.height, + ); + + if (!state.mapData) return; + + const markerSize = Math.max(4, 3 * zoomLevel); + + // Check what to show + const showUsedGateways = + document.getElementById("showUsedGateways").dataset.active === "true"; + const showInitialPath = + document.getElementById("showInitialPath").dataset.active === "true"; + const showEdges = + document.getElementById("showEdges").dataset.active === "true"; + const showGateways = + document.getElementById("showGateways").dataset.active === "true"; + + // Draw highlighted edges for hovered gateway only + if ( + hoveredGateway && + showEdges && + state.graphDebug && + state.graphDebug.edges + ) { + const connectedEdges = state.graphDebug.edges.filter( + (e) => e.fromId === hoveredGateway.id || e.toId === hoveredGateway.id, + ); + + interactiveCtx.strokeStyle = "#00ffaa"; + interactiveCtx.lineWidth = Math.max(1, zoomLevel * 0.8); + interactiveCtx.globalAlpha = 1.0; + + for (const edge of connectedEdges) { + const from = mapToScreen(edge.from[0], edge.from[1]); + const to = mapToScreen(edge.to[0], edge.to[1]); + interactiveCtx.beginPath(); + interactiveCtx.moveTo(from.x, from.y); + interactiveCtx.lineTo(to.x, to.y); + interactiveCtx.stroke(); + } + + interactiveCtx.globalAlpha = 1.0; + } + + // Draw highlighted gateways (hovered + connected) only + if ( + hoveredGateway && + showGateways && + state.graphDebug && + state.graphDebug.allGateways + ) { + // Get connected gateways + let connectedGatewayIds = new Set(); + if (state.graphDebug.edges) { + const connectedEdges = state.graphDebug.edges.filter( + (e) => e.fromId === hoveredGateway.id || e.toId === hoveredGateway.id, + ); + connectedEdges.forEach((edge) => { + if (edge.fromId !== hoveredGateway.id) + connectedGatewayIds.add(edge.fromId); + if (edge.toId !== hoveredGateway.id) connectedGatewayIds.add(edge.toId); + }); + } + + // Draw connected gateways + for (const gwId of connectedGatewayIds) { + const gw = state.graphDebug.allGateways.find((g) => g.id === gwId); + if (gw) { + const screen = mapToScreen(gw.x * 2, gw.y * 2); + interactiveCtx.fillStyle = "#00ff88"; + interactiveCtx.strokeStyle = "#ffffff"; + interactiveCtx.lineWidth = Math.max(1, zoomLevel * 0.3); + interactiveCtx.beginPath(); + interactiveCtx.arc( + screen.x, + screen.y, + Math.max(3, zoomLevel * 2), + 0, + Math.PI * 2, + ); + interactiveCtx.fill(); + interactiveCtx.stroke(); + } + } + + // Draw hovered gateway on top + const screen = mapToScreen(hoveredGateway.x * 2, hoveredGateway.y * 2); + interactiveCtx.fillStyle = "#ffff00"; + interactiveCtx.strokeStyle = "#ffffff"; + interactiveCtx.lineWidth = Math.max(1, zoomLevel * 0.5); + interactiveCtx.beginPath(); + interactiveCtx.arc( + screen.x, + screen.y, + Math.max(4, zoomLevel * 2.5), + 0, + Math.PI * 2, + ); + interactiveCtx.fill(); + interactiveCtx.stroke(); + } + + // Draw initial path (unsmoothed) + if ( + showInitialPath && + state.debugInfo && + state.debugInfo.initialPath && + state.debugInfo.initialPath.length > 0 + ) { + interactiveCtx.strokeStyle = "#ff00ff"; + interactiveCtx.lineWidth = Math.max(1, zoomLevel); + interactiveCtx.lineCap = "round"; + interactiveCtx.lineJoin = "round"; + interactiveCtx.beginPath(); + + for (let i = 0; i < state.debugInfo.initialPath.length; i++) { + const [x, y] = state.debugInfo.initialPath[i]; + const screen = mapToScreen(x + 0.5, y + 0.5); + if (i === 0) { + interactiveCtx.moveTo(screen.x, screen.y); + } else { + interactiveCtx.lineTo(screen.x, screen.y); + } + } + interactiveCtx.stroke(); + } + + // Draw NavMesh path + if (state.navMeshPath && state.navMeshPath.length > 0) { + interactiveCtx.strokeStyle = "#00ffff"; + interactiveCtx.lineWidth = Math.max(1, zoomLevel); + interactiveCtx.lineCap = "round"; + interactiveCtx.lineJoin = "round"; + interactiveCtx.beginPath(); + + for (let i = 0; i < state.navMeshPath.length; i++) { + const [x, y] = state.navMeshPath[i]; + const screen = mapToScreen(x + 0.5, y + 0.5); + if (i === 0) { + interactiveCtx.moveTo(screen.x, screen.y); + } else { + interactiveCtx.lineTo(screen.x, screen.y); + } + } + interactiveCtx.stroke(); + } + + // Draw PF.Mini path + if (state.pfMiniPath && state.pfMiniPath.length > 0) { + interactiveCtx.strokeStyle = "#ffaa00"; + interactiveCtx.lineWidth = Math.max(1, zoomLevel); + interactiveCtx.lineCap = "round"; + interactiveCtx.lineJoin = "round"; + interactiveCtx.beginPath(); + + for (let i = 0; i < state.pfMiniPath.length; i++) { + const [x, y] = state.pfMiniPath[i]; + const screen = mapToScreen(x + 0.5, y + 0.5); + if (i === 0) { + interactiveCtx.moveTo(screen.x, screen.y); + } else { + interactiveCtx.lineTo(screen.x, screen.y); + } + } + interactiveCtx.stroke(); + } + + // Draw used gateways (highlighted) + if (showUsedGateways && state.debugInfo && state.debugInfo.gatewayWaypoints) { + interactiveCtx.fillStyle = "#ffff00"; + const usedGatewayRadius = Math.max(3, zoomLevel * 2.5); + + for (const [x, y] of state.debugInfo.gatewayWaypoints) { + // Gateways are coordinates [x, y] in the same format as path + const screen = mapToScreen(x + 0.5, y + 0.5); + interactiveCtx.beginPath(); + interactiveCtx.arc(screen.x, screen.y, usedGatewayRadius, 0, Math.PI * 2); + interactiveCtx.fill(); + } + } + + // Start point + if (state.startPoint) { + let mapX, mapY; + if (draggingPoint === "start" && draggingPointPosition) { + // Dragging - snap to tile center + mapX = draggingPointPosition[0] + 0.5; + mapY = draggingPointPosition[1] + 0.5; + } else { + mapX = state.startPoint[0] + 0.5; + mapY = state.startPoint[1] + 0.5; + } + + const screen = mapToScreen(mapX, mapY); + + // Highlight ring if hovered + if (hoveredPoint === "start") { + interactiveCtx.strokeStyle = "#ff4444"; + interactiveCtx.lineWidth = Math.max(2, zoomLevel * 0.5); + interactiveCtx.globalAlpha = 0.5; + interactiveCtx.beginPath(); + interactiveCtx.arc(screen.x, screen.y, markerSize + 3, 0, Math.PI * 2); + interactiveCtx.stroke(); + interactiveCtx.globalAlpha = 1.0; + } + + // Draw point + interactiveCtx.fillStyle = "#ff4444"; + interactiveCtx.beginPath(); + interactiveCtx.arc(screen.x, screen.y, markerSize, 0, Math.PI * 2); + interactiveCtx.fill(); + } + + // End point + if (state.endPoint) { + let mapX, mapY; + if (draggingPoint === "end" && draggingPointPosition) { + // Dragging - snap to tile center + mapX = draggingPointPosition[0] + 0.5; + mapY = draggingPointPosition[1] + 0.5; + } else { + mapX = state.endPoint[0] + 0.5; + mapY = state.endPoint[1] + 0.5; + } + + const screen = mapToScreen(mapX, mapY); + + // Highlight ring if hovered + if (hoveredPoint === "end") { + interactiveCtx.strokeStyle = "#44ff44"; + interactiveCtx.lineWidth = Math.max(2, zoomLevel * 0.5); + interactiveCtx.globalAlpha = 0.5; + interactiveCtx.beginPath(); + interactiveCtx.arc(screen.x, screen.y, markerSize + 3, 0, Math.PI * 2); + interactiveCtx.stroke(); + interactiveCtx.globalAlpha = 1.0; + } + + // Draw point + interactiveCtx.fillStyle = "#44ff44"; + interactiveCtx.beginPath(); + interactiveCtx.arc(screen.x, screen.y, markerSize, 0, Math.PI * 2); + interactiveCtx.fill(); + } +} + +function findGatewayAtPosition(canvasX, canvasY, gatewaysToCheck = null) { + const gateways = + gatewaysToCheck || (state.graphDebug && state.graphDebug.allGateways); + if (!gateways) { + return null; + } + + const threshold = 10; + + for (const gw of gateways) { + const gwX = gw.x * 2; + const gwY = gw.y * 2; + const dx = Math.abs(canvasX - gwX); + const dy = Math.abs(canvasY - gwY); + + if (dx < threshold && dy < threshold) { + return gw; + } + } + + return null; +} + +// Show gateway tooltip +function showGatewayTooltip(gateway, mouseX, mouseY) { + const tooltip = document.getElementById("tooltip"); + + const connectedEdges = state.graphDebug.edges.filter( + (e) => e.fromId === gateway.id || e.toId === gateway.id, + ); + + const selfLoops = connectedEdges.filter((e) => e.fromId === e.toId); + + let html = `Gateway ${gateway.id}
`; + html += `Position: (${gateway.x * 2}, ${gateway.y * 2})
`; + html += `Edges: ${connectedEdges.length}`; + + if (selfLoops.length > 0) { + html += ` (${selfLoops.length} self-loop!)`; + } + + if (connectedEdges.length > 0) { + html += '

- -
- -
- - - @@ -256,13 +223,9 @@

Pathfinding Playground

> End Point -
- NavMesh + HPA*
@@ -273,7 +236,7 @@

Pathfinding Playground

class="legend-color" style="background: #ffff00; height: 8px" >
- Used Gateways + Used Nodes
Pathfinding Playground border-radius: 50%; " >
- Gateways + Nodes
{ * map: string, * from: [x, y], * to: [x, y], - * includePfMini?: boolean + * adapters?: string[] // Optional: which comparison adapters to run + * } + * + * Response: + * { + * primary: { path, length, time, debug: { nodePath, initialPath, timings } }, + * comparisons: [{ adapter, path, length, time }, ...] * } */ app.post("/api/pathfind", async (req: Request, res: Response) => { try { - const { map, from, to, includePfMini } = req.body; + const { map, from, to, adapters } = req.body; // Validate request if (!map || !from || !to) { @@ -144,7 +146,7 @@ app.post("/api/pathfind", async (req: Request, res: Response) => { map, from as [number, number], to as [number, number], - { includePfMini: !!includePfMini }, + { adapters }, ); res.json(result); @@ -165,66 +167,6 @@ app.post("/api/pathfind", async (req: Request, res: Response) => { } }); -/** - * POST /api/pathfind-pfmini - * Compute only PathFinder.Mini path - * - * Request body: - * { - * map: string, - * from: [x, y], - * to: [x, y] - * } - */ -app.post("/api/pathfind-pfmini", async (req: Request, res: Response) => { - try { - const { map, from, to } = req.body; - - // Validate request - if (!map || !from || !to) { - return res.status(400).json({ - error: "Invalid request", - message: "Missing required fields: map, from, to", - }); - } - - if ( - !Array.isArray(from) || - from.length !== 2 || - !Array.isArray(to) || - to.length !== 2 - ) { - return res.status(400).json({ - error: "Invalid coordinates", - message: "from and to must be [x, y] coordinate arrays", - }); - } - - // Compute PF.Mini path only - const result = await computePfMiniPath( - map, - from as [number, number], - to as [number, number], - ); - - res.json(result); - } catch (error) { - console.error("Error computing PF.Mini path:", error); - - if (error instanceof Error && error.message.includes("is not water")) { - res.status(400).json({ - error: "Invalid coordinates", - message: error.message, - }); - } else { - res.status(500).json({ - error: "Failed to compute PF.Mini path", - message: error instanceof Error ? error.message : String(error), - }); - } - } -}); - /** * POST /api/cache/clear * Clear all caches (useful for development) diff --git a/tests/pathfinding/utils.ts b/tests/pathfinding/utils.ts index 6e3a12ceb..e2d39b3e5 100644 --- a/tests/pathfinding/utils.ts +++ b/tests/pathfinding/utils.ts @@ -13,10 +13,19 @@ import { createGame } from "../../src/core/game/GameImpl"; import { TileRef } from "../../src/core/game/GameMap"; import { genTerrainFromBin } from "../../src/core/game/TerrainMapLoader"; import { UserSettings } from "../../src/core/game/UserSettings"; -import { NavMesh } from "../../src/core/pathfinding/navmesh/NavMesh"; -import { PathFinder, PathFinders } from "../../src/core/pathfinding/PathFinder"; +import { AStarWater } from "../../src/core/pathfinding/algorithms/AStar.Water"; +import { AStarWaterHierarchical } from "../../src/core/pathfinding/algorithms/AStar.WaterHierarchical"; +import { PathFinding } from "../../src/core/pathfinding/PathFinder"; +import { PathFinderBuilder } from "../../src/core/pathfinding/PathFinderBuilder"; +import { StepperConfig } from "../../src/core/pathfinding/PathFinderStepper"; +import { MiniMapTransformer } from "../../src/core/pathfinding/transformers/MiniMapTransformer"; +import { + PathStatus, + SteppingPathFinder, +} from "../../src/core/pathfinding/types"; import { GameConfig, PeaceTimerDuration } from "../../src/core/Schemas"; import { TestConfig } from "../util/TestConfig"; + export type BenchmarkRoute = { name: string; from: TileRef; @@ -38,25 +47,58 @@ export type BenchmarkSummary = { avgTime: number; }; -export function getAdapter(game: Game, name: string): PathFinder { +function tileStepperConfig(game: Game): StepperConfig { + return { + equals: (a, b) => a === b, + distance: (a, b) => game.manhattanDist(a, b), + preCheck: (from, to) => + typeof from !== "number" || + typeof to !== "number" || + !game.isValidRef(from) || + !game.isValidRef(to) + ? { status: PathStatus.NOT_FOUND } + : null, + }; +} + +export function getAdapter( + game: Game, + name: string, +): SteppingPathFinder { switch (name) { - case "legacy": - return PathFinders.WaterLegacy(game, { - iterations: 500_000, - maxTries: 50, - }); + case "a.baseline": { + return PathFinderBuilder.create(new AStarWater(game.miniMap())) + .wrap((pf) => new MiniMapTransformer(pf, game, game.miniMap())) + .buildWithStepper(tileStepperConfig(game)); + } + case "a.generic": { + // Same as baseline - uses AStarWater on minimap + return PathFinderBuilder.create(new AStarWater(game.miniMap())) + .wrap((pf) => new MiniMapTransformer(pf, game, game.miniMap())) + .buildWithStepper(tileStepperConfig(game)); + } + case "a.full": { + return PathFinderBuilder.create( + new AStarWater(game.map()), + ).buildWithStepper(tileStepperConfig(game)); + } case "hpa": { - // Recreate NavMesh without cache, this approach was chosen + // Recreate AStarWaterHierarchical without cache, this approach was chosen // over adding cache toggles to the existing game instance // to avoid adding side effect from benchmark to the game - const navMesh = new NavMesh(game, { cachePaths: false }); - navMesh.initialize(); - (game as any)._navMesh = navMesh; + const graph = game.miniWaterGraph(); + if (!graph) { + throw new Error("miniWaterGraph not available"); + } + const hpa = new AStarWaterHierarchical(game.miniMap(), graph, { + cachePaths: false, + }); + (game as any)._miniWaterHPA = hpa; - return PathFinders.Water(game); + return PathFinding.Water(game); } case "hpa.cached": - return PathFinders.Water(game); + return PathFinding.Water(game); default: throw new Error(`Unknown pathfinding adapter: ${name}`); } @@ -98,7 +140,7 @@ export async function getScenario( } export function measurePathLength( - adapter: PathFinder, + adapter: SteppingPathFinder, route: BenchmarkRoute, ): number | null { const path = adapter.findPath(route.from, route.to); @@ -113,7 +155,7 @@ export function measureTime(fn: () => T): { result: T; time: number } { } export function measureExecutionTime( - adapter: PathFinder, + adapter: SteppingPathFinder, route: BenchmarkRoute, executions: number = 1, ): number | null { diff --git a/tests/perf/AstarPerf.ts b/tests/perf/AstarPerf.ts deleted file mode 100644 index 6e5931672..000000000 --- a/tests/perf/AstarPerf.ts +++ /dev/null @@ -1,29 +0,0 @@ -import Benchmark from "benchmark"; -import { MiniPathFinder } from "../../src/core/pathfinding/PathFinding"; -import { setup } from "../util/Setup"; - -const game = await setup("giantworldmap", {}, []); - -new Benchmark.Suite() - .add("top-left-to-bottom-right", () => { - new MiniPathFinder(game, 10_000_000_000, true, 1).nextTile( - game.ref(0, 0), - game.ref(4077, 1929), - ); - }) - .add("hawaii to svalbard", () => { - new MiniPathFinder(game, 10_000_000_000, true, 1).nextTile( - game.ref(186, 800), - game.ref(2205, 52), - ); - }) - .add("black sea to california", () => { - new MiniPathFinder(game, 10_000_000_000, true, 1).nextTile( - game.ref(2349, 455), - game.ref(511, 536), - ); - }) - .on("cycle", (event: any) => { - console.log(String(event.target)); - }) - .run({ async: true }); From fb78aade97656a3a485bb51d2fc01152cbeb53f7 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 04:34:05 +0100 Subject: [PATCH 23/34] Pathfinding Refinement (#2878) This PR introduces final change to the pathfinding - path refinement. It optimizes Line of Sight refinement by searching with for the best tile with a binary search instead of linearly. And then spends the recovered budget on better refinement of the first and last 50 tiles of the journey - the place where user is most likely to look at. Additionally this PR re-introduces magnitude check and makes the ships prefer sailing close to the coast, but not too close. - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced | Before | After | | :--- | :--- | | image | image | | image | image | There is actually a severe performance impact of these changes. The path initial path takes almost 2x as long to generate - this is because pre processing can only do so much if the initial path is ugly. Luckily in real gameplay we only need to do this calculation once per edge, so the actual observed performance impact should be much smaller. Cache FTW. | | No Cache | Cache | | :--- | :--- | :--- | | Before | 277.04ms | 208.58ms | | After | 498.34ms | 264.27ms | Small utility, it allows any code to be easily instrumented for performance. The idea is the same as with [OTEL Spans](https://opentelemetry.io/docs/concepts/signals/traces/). Produce a span, create sub-spans, measure whatever you need. Works only when `globalThis.__DEBUG_SPAN_ENABLED__ === true`, otherwise no-op. Cool stuff, try it out: ```ts // Convenient wrapper, small performance impact return DebugSpan.wrap('add', () => a + b) // Synchronous API, basically free DebugSpan.start('work') work() DebugSpan.end() // Create sub spans DebugSpan.wrap('complex', () => { const aPlusB = DebugSpan.wrap('add', () => a + b) DebugSpan.set('additionResult', () => aPlusB) // Store data return aPlusB * c }) // Access spans, data and timing const span = DebugSpan.getLast() const compelxSpan = DebugSpan.getLast('complex') console.log(complexSpan.duration, complexSpan.data['additionResult']) ``` These are virtually free and can be enabled on-demand **in production** and available in the devtools. Under the hood devtools integration is just a wrapper around [Performance API](https://developer.mozilla.org/en-US/docs/Web/API/Performance_API). For clarity data keys not prefixed by `$` are omitted from the integration. Every key prefixed with `$` must be fully JSON serializable. image --- src/core/pathfinding/PathFinder.ts | 4 +- src/core/pathfinding/PathFinderBuilder.ts | 10 +- .../pathfinding/algorithms/AStar.Water.ts | 106 ++++-- ...AStar.Bounded.ts => AStar.WaterBounded.ts} | 96 +++-- .../algorithms/AStar.WaterHierarchical.ts | 229 +++--------- .../pathfinding/algorithms/AbstractGraph.ts | 138 +------ .../algorithms/ConnectedComponents.ts | 3 + .../smoothing/BresenhamPathSmoother.ts | 168 --------- .../pathfinding/smoothing/PathSmoother.ts | 7 - .../smoothing/SmoothingTransformer.ts | 18 - .../transformers/SmoothingWaterTransformer.ts | 341 ++++++++++++++++++ src/core/utilities/DebugSpan.ts | 159 ++++++++ tests/pathfinding/playground/api/maps.ts | 176 +++++---- .../pathfinding/playground/api/pathfinding.ts | 107 +++--- tests/pathfinding/playground/public/client.js | 65 ++-- .../pathfinding/playground/public/index.html | 4 + .../pathfinding/playground/public/styles.css | 4 + tests/pathfinding/playground/server.ts | 14 - tests/pathfinding/utils.ts | 28 +- tests/util/Setup.ts | 67 +++- 20 files changed, 1019 insertions(+), 725 deletions(-) rename src/core/pathfinding/algorithms/{AStar.Bounded.ts => AStar.WaterBounded.ts} (68%) delete mode 100644 src/core/pathfinding/smoothing/BresenhamPathSmoother.ts delete mode 100644 src/core/pathfinding/smoothing/PathSmoother.ts delete mode 100644 src/core/pathfinding/smoothing/SmoothingTransformer.ts create mode 100644 src/core/pathfinding/transformers/SmoothingWaterTransformer.ts create mode 100644 src/core/utilities/DebugSpan.ts diff --git a/src/core/pathfinding/PathFinder.ts b/src/core/pathfinding/PathFinder.ts index 04a4b60a9..2c3497817 100644 --- a/src/core/pathfinding/PathFinder.ts +++ b/src/core/pathfinding/PathFinder.ts @@ -8,10 +8,10 @@ import { } from "./PathFinder.Parabola"; import { PathFinderBuilder } from "./PathFinderBuilder"; import { StepperConfig } from "./PathFinderStepper"; -import { BresenhamSmoothingTransformer } from "./smoothing/BresenhamPathSmoother"; import { ComponentCheckTransformer } from "./transformers/ComponentCheckTransformer"; import { MiniMapTransformer } from "./transformers/MiniMapTransformer"; import { ShoreCoercingTransformer } from "./transformers/ShoreCoercingTransformer"; +import { SmoothingWaterTransformer } from "./transformers/SmoothingWaterTransformer"; import { PathStatus, SteppingPathFinder } from "./types"; /** @@ -43,7 +43,7 @@ export class PathFinding { return PathFinderBuilder.create(pf) .wrap((pf) => new ComponentCheckTransformer(pf, componentCheckFn)) - .wrap((pf) => new BresenhamSmoothingTransformer(pf, miniMap)) + .wrap((pf) => new SmoothingWaterTransformer(pf, miniMap)) .wrap((pf) => new ShoreCoercingTransformer(pf, miniMap)) .wrap((pf) => new MiniMapTransformer(pf, game.map(), miniMap)) .buildWithStepper(tileStepperConfig(game)); diff --git a/src/core/pathfinding/PathFinderBuilder.ts b/src/core/pathfinding/PathFinderBuilder.ts index 51d7b6460..d4eff7633 100644 --- a/src/core/pathfinding/PathFinderBuilder.ts +++ b/src/core/pathfinding/PathFinderBuilder.ts @@ -1,3 +1,4 @@ +import { DebugSpan } from "../utilities/DebugSpan"; import { PathFinderStepper, StepperConfig } from "./PathFinderStepper"; import { PathFinder, SteppingPathFinder } from "./types"; @@ -27,10 +28,17 @@ export class PathFinderBuilder { } build(): PathFinder { - return this.wrappers.reduce( + const pathFinder = this.wrappers.reduce( (pf, wrapper) => wrapper(pf), this.core as PathFinder, ); + + const _findPath = pathFinder.findPath; + pathFinder.findPath = function (from: T | T[], to: T): T[] | null { + return DebugSpan.wrap("findPath", () => _findPath.call(this, from, to)); + }; + + return pathFinder; } /** diff --git a/src/core/pathfinding/algorithms/AStar.Water.ts b/src/core/pathfinding/algorithms/AStar.Water.ts index 920f1a475..6452114a5 100644 --- a/src/core/pathfinding/algorithms/AStar.Water.ts +++ b/src/core/pathfinding/algorithms/AStar.Water.ts @@ -3,6 +3,16 @@ import { PathFinder } from "../types"; import { BucketQueue, PriorityQueue } from "./PriorityQueue"; const LAND_BIT = 7; // Bit 7 in terrain indicates land +const MAGNITUDE_MASK = 0x1f; +const COST_SCALE = 100; +const BASE_COST = 1 * COST_SCALE; + +// Prefer magnitude 3-10 (3-10 tiles from shore) +function getMagnitudePenalty(magnitude: number): number { + if (magnitude < 3) return 10 * COST_SCALE; // too close to shore + if (magnitude <= 10) return 0; // sweet spot + return 1 * COST_SCALE; // deep water, slight penalty +} export interface AStarWaterConfig { heuristicWeight?: number; @@ -27,7 +37,7 @@ export class AStarWater implements PathFinder { this.terrain = (map as any).terrain as Uint8Array; this.width = map.width(); this.numNodes = map.width() * map.height(); - this.heuristicWeight = config?.heuristicWeight ?? 15; + this.heuristicWeight = config?.heuristicWeight ?? 5; this.maxIterations = config?.maxIterations ?? 1_000_000; this.closedStamp = new Uint32Array(this.numNodes); @@ -35,7 +45,10 @@ export class AStarWater implements PathFinder { this.gScore = new Uint32Array(this.numNodes); this.cameFrom = new Int32Array(this.numNodes); - const maxF = this.heuristicWeight * (map.width() + map.height()); + // Account for scaled costs + tie-breaker headroom + const maxDim = map.width() + map.height(); + const maxF = + (this.heuristicWeight + 1) * BASE_COST * maxDim + COST_SCALE * maxDim; this.queue = new BucketQueue(maxF); } @@ -64,13 +77,32 @@ export class AStarWater implements PathFinder { queue.clear(); const starts = Array.isArray(start) ? start : [start]; + + // For cross-product tie-breaker (prefer diagonal paths) + const s0 = starts[0]; + const startX = s0 % width; + const startY = (s0 / width) | 0; + const dxGoal = goalX - startX; + const dyGoal = goalY - startY; + // Normalization factor to keep tie-breaker small (< COST_SCALE) + const crossNorm = Math.max(1, Math.abs(dxGoal) + Math.abs(dyGoal)); + + // Cross-product tie-breaker: measures deviation from start-goal line + const crossTieBreaker = (nx: number, ny: number): number => { + const dxN = nx - goalX; + const dyN = ny - goalY; + const cross = Math.abs(dxGoal * dyN - dyGoal * dxN); + return Math.floor((cross * (COST_SCALE - 1)) / crossNorm / crossNorm); + }; + for (const s of starts) { gScore[s] = 0; gScoreStamp[s] = stamp; cameFrom[s] = -1; const sx = s % width; const sy = (s / width) | 0; - const h = weight * (Math.abs(sx - goalX) + Math.abs(sy - goalY)); + const h = + weight * BASE_COST * (Math.abs(sx - goalX) + Math.abs(sy - goalY)); queue.push(s, h); } @@ -91,15 +123,19 @@ export class AStarWater implements PathFinder { } const currentG = gScore[current]; - const tentativeG = currentG + 1; const currentX = current % width; + const currentY = (current / width) | 0; if (current >= width) { const neighbor = current - width; + const neighborTerrain = terrain[neighbor]; if ( closedStamp[neighbor] !== stamp && - (neighbor === goal || (terrain[neighbor] & landMask) === 0) + (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const magnitude = neighborTerrain & MAGNITUDE_MASK; + const cost = BASE_COST + getMagnitudePenalty(magnitude); + const tentativeG = currentG + cost; if ( gScoreStamp[neighbor] !== stamp || tentativeG < gScore[neighbor] @@ -107,11 +143,12 @@ export class AStarWater implements PathFinder { cameFrom[neighbor] = current; gScore[neighbor] = tentativeG; gScoreStamp[neighbor] = stamp; - const nx = neighbor % width; - const ny = (neighbor / width) | 0; - const f = - tentativeG + - weight * (Math.abs(nx - goalX) + Math.abs(ny - goalY)); + const ny = currentY - 1; + const h = + weight * + BASE_COST * + (Math.abs(currentX - goalX) + Math.abs(ny - goalY)); + const f = tentativeG + h + crossTieBreaker(currentX, ny); queue.push(neighbor, f); } } @@ -119,10 +156,14 @@ export class AStarWater implements PathFinder { if (current < numNodes - width) { const neighbor = current + width; + const neighborTerrain = terrain[neighbor]; if ( closedStamp[neighbor] !== stamp && - (neighbor === goal || (terrain[neighbor] & landMask) === 0) + (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const magnitude = neighborTerrain & MAGNITUDE_MASK; + const cost = BASE_COST + getMagnitudePenalty(magnitude); + const tentativeG = currentG + cost; if ( gScoreStamp[neighbor] !== stamp || tentativeG < gScore[neighbor] @@ -130,11 +171,12 @@ export class AStarWater implements PathFinder { cameFrom[neighbor] = current; gScore[neighbor] = tentativeG; gScoreStamp[neighbor] = stamp; - const nx = neighbor % width; - const ny = (neighbor / width) | 0; - const f = - tentativeG + - weight * (Math.abs(nx - goalX) + Math.abs(ny - goalY)); + const ny = currentY + 1; + const h = + weight * + BASE_COST * + (Math.abs(currentX - goalX) + Math.abs(ny - goalY)); + const f = tentativeG + h + crossTieBreaker(currentX, ny); queue.push(neighbor, f); } } @@ -142,10 +184,14 @@ export class AStarWater implements PathFinder { if (currentX !== 0) { const neighbor = current - 1; + const neighborTerrain = terrain[neighbor]; if ( closedStamp[neighbor] !== stamp && - (neighbor === goal || (terrain[neighbor] & landMask) === 0) + (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const magnitude = neighborTerrain & MAGNITUDE_MASK; + const cost = BASE_COST + getMagnitudePenalty(magnitude); + const tentativeG = currentG + cost; if ( gScoreStamp[neighbor] !== stamp || tentativeG < gScore[neighbor] @@ -153,10 +199,12 @@ export class AStarWater implements PathFinder { cameFrom[neighbor] = current; gScore[neighbor] = tentativeG; gScoreStamp[neighbor] = stamp; - const ny = (neighbor / width) | 0; - const f = - tentativeG + - weight * (Math.abs(currentX - 1 - goalX) + Math.abs(ny - goalY)); + const nx = currentX - 1; + const h = + weight * + BASE_COST * + (Math.abs(nx - goalX) + Math.abs(currentY - goalY)); + const f = tentativeG + h + crossTieBreaker(nx, currentY); queue.push(neighbor, f); } } @@ -164,10 +212,14 @@ export class AStarWater implements PathFinder { if (currentX !== width - 1) { const neighbor = current + 1; + const neighborTerrain = terrain[neighbor]; if ( closedStamp[neighbor] !== stamp && - (neighbor === goal || (terrain[neighbor] & landMask) === 0) + (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const magnitude = neighborTerrain & MAGNITUDE_MASK; + const cost = BASE_COST + getMagnitudePenalty(magnitude); + const tentativeG = currentG + cost; if ( gScoreStamp[neighbor] !== stamp || tentativeG < gScore[neighbor] @@ -175,10 +227,12 @@ export class AStarWater implements PathFinder { cameFrom[neighbor] = current; gScore[neighbor] = tentativeG; gScoreStamp[neighbor] = stamp; - const ny = (neighbor / width) | 0; - const f = - tentativeG + - weight * (Math.abs(currentX + 1 - goalX) + Math.abs(ny - goalY)); + const nx = currentX + 1; + const h = + weight * + BASE_COST * + (Math.abs(nx - goalX) + Math.abs(currentY - goalY)); + const f = tentativeG + h + crossTieBreaker(nx, currentY); queue.push(neighbor, f); } } diff --git a/src/core/pathfinding/algorithms/AStar.Bounded.ts b/src/core/pathfinding/algorithms/AStar.WaterBounded.ts similarity index 68% rename from src/core/pathfinding/algorithms/AStar.Bounded.ts rename to src/core/pathfinding/algorithms/AStar.WaterBounded.ts index 923f06083..aa8bdd693 100644 --- a/src/core/pathfinding/algorithms/AStar.Bounded.ts +++ b/src/core/pathfinding/algorithms/AStar.WaterBounded.ts @@ -3,6 +3,16 @@ import { PathFinder } from "../types"; import { BucketQueue } from "./PriorityQueue"; const LAND_BIT = 7; +const MAGNITUDE_MASK = 0x1f; +const COST_SCALE = 100; +const BASE_COST = 1 * COST_SCALE; + +// Prefer magnitude 3-10 (3-10 tiles from shore) +function getMagnitudePenalty(magnitude: number): number { + if (magnitude < 3) return 3 * COST_SCALE; // too close to shore + if (magnitude <= 10) return 0; // sweet spot + return 1 * COST_SCALE; // deep water, slight penalty +} export interface BoundedAStarConfig { heuristicWeight?: number; @@ -16,7 +26,7 @@ export interface SearchBounds { maxY: number; } -export class AStarBounded implements PathFinder { +export class AStarWaterBounded implements PathFinder { private stamp = 1; private readonly closedStamp: Uint32Array; @@ -36,7 +46,7 @@ export class AStarBounded implements PathFinder { ) { this.terrain = (map as any).terrain as Uint8Array; this.mapWidth = map.width(); - this.heuristicWeight = config?.heuristicWeight ?? 1; + this.heuristicWeight = config?.heuristicWeight ?? 3; this.maxIterations = config?.maxIterations ?? 100_000; this.closedStamp = new Uint32Array(maxSearchArea); @@ -45,7 +55,9 @@ export class AStarBounded implements PathFinder { this.cameFrom = new Int32Array(maxSearchArea); const maxDim = Math.ceil(Math.sqrt(maxSearchArea)); - const maxF = this.heuristicWeight * maxDim * 2; + // Account for scaled costs + tie-breaker headroom + const maxF = + (this.heuristicWeight + 1) * BASE_COST * maxDim * 2 + COST_SCALE * maxDim; this.queue = new BucketQueue(maxF); } @@ -133,6 +145,24 @@ export class AStarBounded implements PathFinder { queue.clear(); const starts = Array.isArray(start) ? start : [start]; + + // For cross-product tie-breaker (prefer diagonal paths) + const s0 = starts[0]; + const startX = s0 % mapWidth; + const startY = (s0 / mapWidth) | 0; + const dxGoal = goalX - startX; + const dyGoal = goalY - startY; + // Normalization factor to keep tie-breaker small (< COST_SCALE) + const crossNorm = Math.max(1, Math.abs(dxGoal) + Math.abs(dyGoal)); + + // Cross-product tie-breaker: measures deviation from start-goal line + const crossTieBreaker = (nx: number, ny: number): number => { + const dxN = nx - goalX; + const dyN = ny - goalY; + const cross = Math.abs(dxGoal * dyN - dyGoal * dxN); + return Math.floor((cross * (COST_SCALE - 1)) / crossNorm / crossNorm); + }; + for (const s of starts) { const startLocal = toLocal(s, true); if (startLocal < 0 || startLocal >= numLocalNodes) { @@ -143,7 +173,8 @@ export class AStarBounded implements PathFinder { cameFrom[startLocal] = -1; const sx = s % mapWidth; const sy = (s / mapWidth) | 0; - const h = weight * (Math.abs(sx - goalX) + Math.abs(sy - goalY)); + const h = + weight * BASE_COST * (Math.abs(sx - goalX) + Math.abs(sy - goalY)); queue.push(startLocal, h); } @@ -164,7 +195,6 @@ export class AStarBounded implements PathFinder { } const currentG = gScore[currentLocal]; - const tentativeG = currentG + 1; // Convert to global coords for neighbor calculation const current = toGlobal(currentLocal); @@ -174,10 +204,14 @@ export class AStarBounded implements PathFinder { if (currentY > minY) { const neighbor = current - mapWidth; const neighborLocal = currentLocal - boundsWidth; + const neighborTerrain = terrain[neighbor]; if ( closedStamp[neighborLocal] !== stamp && - (neighbor === goal || (terrain[neighbor] & landMask) === 0) + (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const magnitude = neighborTerrain & MAGNITUDE_MASK; + const cost = BASE_COST + getMagnitudePenalty(magnitude); + const tentativeG = currentG + cost; if ( gScoreStamp[neighborLocal] !== stamp || tentativeG < gScore[neighborLocal] @@ -185,10 +219,12 @@ export class AStarBounded implements PathFinder { cameFrom[neighborLocal] = currentLocal; gScore[neighborLocal] = tentativeG; gScoreStamp[neighborLocal] = stamp; - const f = - tentativeG + + const ny = currentY - 1; + const h = weight * - (Math.abs(currentX - goalX) + Math.abs(currentY - 1 - goalY)); + BASE_COST * + (Math.abs(currentX - goalX) + Math.abs(ny - goalY)); + const f = tentativeG + h + crossTieBreaker(currentX, ny); queue.push(neighborLocal, f); } } @@ -197,10 +233,14 @@ export class AStarBounded implements PathFinder { if (currentY < maxY) { const neighbor = current + mapWidth; const neighborLocal = currentLocal + boundsWidth; + const neighborTerrain = terrain[neighbor]; if ( closedStamp[neighborLocal] !== stamp && - (neighbor === goal || (terrain[neighbor] & landMask) === 0) + (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const magnitude = neighborTerrain & MAGNITUDE_MASK; + const cost = BASE_COST + getMagnitudePenalty(magnitude); + const tentativeG = currentG + cost; if ( gScoreStamp[neighborLocal] !== stamp || tentativeG < gScore[neighborLocal] @@ -208,10 +248,12 @@ export class AStarBounded implements PathFinder { cameFrom[neighborLocal] = currentLocal; gScore[neighborLocal] = tentativeG; gScoreStamp[neighborLocal] = stamp; - const f = - tentativeG + + const ny = currentY + 1; + const h = weight * - (Math.abs(currentX - goalX) + Math.abs(currentY + 1 - goalY)); + BASE_COST * + (Math.abs(currentX - goalX) + Math.abs(ny - goalY)); + const f = tentativeG + h + crossTieBreaker(currentX, ny); queue.push(neighborLocal, f); } } @@ -220,10 +262,14 @@ export class AStarBounded implements PathFinder { if (currentX > minX) { const neighbor = current - 1; const neighborLocal = currentLocal - 1; + const neighborTerrain = terrain[neighbor]; if ( closedStamp[neighborLocal] !== stamp && - (neighbor === goal || (terrain[neighbor] & landMask) === 0) + (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const magnitude = neighborTerrain & MAGNITUDE_MASK; + const cost = BASE_COST + getMagnitudePenalty(magnitude); + const tentativeG = currentG + cost; if ( gScoreStamp[neighborLocal] !== stamp || tentativeG < gScore[neighborLocal] @@ -231,10 +277,12 @@ export class AStarBounded implements PathFinder { cameFrom[neighborLocal] = currentLocal; gScore[neighborLocal] = tentativeG; gScoreStamp[neighborLocal] = stamp; - const f = - tentativeG + + const nx = currentX - 1; + const h = weight * - (Math.abs(currentX - 1 - goalX) + Math.abs(currentY - goalY)); + BASE_COST * + (Math.abs(nx - goalX) + Math.abs(currentY - goalY)); + const f = tentativeG + h + crossTieBreaker(nx, currentY); queue.push(neighborLocal, f); } } @@ -243,10 +291,14 @@ export class AStarBounded implements PathFinder { if (currentX < maxX) { const neighbor = current + 1; const neighborLocal = currentLocal + 1; + const neighborTerrain = terrain[neighbor]; if ( closedStamp[neighborLocal] !== stamp && - (neighbor === goal || (terrain[neighbor] & landMask) === 0) + (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const magnitude = neighborTerrain & MAGNITUDE_MASK; + const cost = BASE_COST + getMagnitudePenalty(magnitude); + const tentativeG = currentG + cost; if ( gScoreStamp[neighborLocal] !== stamp || tentativeG < gScore[neighborLocal] @@ -254,10 +306,12 @@ export class AStarBounded implements PathFinder { cameFrom[neighborLocal] = currentLocal; gScore[neighborLocal] = tentativeG; gScoreStamp[neighborLocal] = stamp; - const f = - tentativeG + + const nx = currentX + 1; + const h = weight * - (Math.abs(currentX + 1 - goalX) + Math.abs(currentY - goalY)); + BASE_COST * + (Math.abs(nx - goalX) + Math.abs(currentY - goalY)); + const f = tentativeG + h + crossTieBreaker(nx, currentY); queue.push(neighborLocal, f); } } diff --git a/src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts b/src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts index 019893d6a..ce8ceb2a7 100644 --- a/src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts +++ b/src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts @@ -1,39 +1,19 @@ import { GameMap, TileRef } from "../../game/GameMap"; +import { DebugSpan } from "../../utilities/DebugSpan"; import { PathFinder } from "../types"; import { AbstractGraphAStar } from "./AStar.AbstractGraph"; -import { AStarBounded } from "./AStar.Bounded"; +import { AStarWaterBounded } from "./AStar.WaterBounded"; import { AbstractGraph, AbstractNode } from "./AbstractGraph"; import { BFSGrid } from "./BFS.Grid"; import { LAND_MARKER } from "./ConnectedComponents"; -type PathDebugInfo = { - nodePath: TileRef[] | null; - initialPath: TileRef[] | null; - graph: { - clusterSize: number; - nodes: Array<{ id: number; tile: TileRef }>; - edges: Array<{ - id: number; - nodeA: number; - nodeB: number; - from: TileRef; - to: TileRef; - cost: number; - }>; - }; - timings: { [key: string]: number }; -}; - export class AStarWaterHierarchical implements PathFinder { private tileBFS: BFSGrid; private abstractAStar: AbstractGraphAStar; - private localAStar: AStarBounded; - private localAStarMultiCluster: AStarBounded; + private localAStar: AStarWaterBounded; + private localAStarMultiCluster: AStarWaterBounded; private sourceResolver: SourceResolver; - public debugInfo: PathDebugInfo | null = null; - public debugMode: boolean = false; - constructor( private map: GameMap, private graph: AbstractGraph, @@ -51,23 +31,31 @@ export class AStarWaterHierarchical implements PathFinder { // BoundedAStar for cluster-bounded local pathfinding const maxLocalNodes = clusterSize * clusterSize; - this.localAStar = new AStarBounded(map, maxLocalNodes); + this.localAStar = new AStarWaterBounded(map, maxLocalNodes); // BoundedAStar for multi-cluster (3x3) local pathfinding const multiClusterSize = clusterSize * 3; const maxMultiClusterNodes = multiClusterSize * multiClusterSize; - this.localAStarMultiCluster = new AStarBounded(map, maxMultiClusterNodes); + this.localAStarMultiCluster = new AStarWaterBounded( + map, + maxMultiClusterNodes, + ); // SourceResolver for multi-source search this.sourceResolver = new SourceResolver(this.map, this.graph); } findPath(from: number | number[], to: number): number[] | null { - if (Array.isArray(from)) { - return this.findPathMultiSource(from as TileRef[], to as TileRef); - } + return DebugSpan.wrap("AStar.WaterHierarchical:findPath", () => { + DebugSpan.set("$to", () => to); + DebugSpan.set("$from", () => from); + + if (Array.isArray(from)) { + return this.findPathMultiSource(from as TileRef[], to as TileRef); + } - return this.findPathSingle(from as TileRef, to as TileRef, this.debugMode); + return this.findPathSingle(from as TileRef, to as TileRef); + }); } private findPathMultiSource( @@ -94,192 +82,66 @@ export class AStarWaterHierarchical implements PathFinder { return this.findPathSingle(winningSource, target); } - findPathSingle( - from: TileRef, - to: TileRef, - debug: boolean = false, - ): TileRef[] | null { - if (debug) { - const allEdges: Array<{ - id: number; - nodeA: number; - nodeB: number; - from: TileRef; - to: TileRef; - cost: number; - }> = []; - - for (let edgeId = 0; edgeId < this.graph.edgeCount; edgeId++) { - const edge = this.graph.getEdge(edgeId); - if (!edge) continue; - - const nodeA = this.graph.getNode(edge.nodeA); - const nodeB = this.graph.getNode(edge.nodeB); - if (!nodeA || !nodeB) continue; - - allEdges.push({ - id: edge.id, - nodeA: edge.nodeA, - nodeB: edge.nodeB, - from: nodeA.tile, - to: nodeB.tile, - cost: edge.cost, - }); - } - - this.debugInfo = { - nodePath: null, - initialPath: null, - graph: { - clusterSize: this.graph.clusterSize, - nodes: this.graph - .getAllNodes() - .map((node) => ({ id: node.id, tile: node.tile })), - edges: allEdges, - }, - timings: { - total: 0, - }, - }; - } - + findPathSingle(from: TileRef, to: TileRef): TileRef[] | null { const dist = this.map.manhattanDist(from, to); // Early exit for very short distances if (dist <= this.graph.clusterSize) { - performance.mark("hpa:findPath:earlyExitLocalPath:start"); + DebugSpan.start("earlyExit"); const startX = this.map.x(from); const startY = this.map.y(from); const clusterX = Math.floor(startX / this.graph.clusterSize); const clusterY = Math.floor(startY / this.graph.clusterSize); const localPath = this.findLocalPath(from, to, clusterX, clusterY, true); - performance.mark("hpa:findPath:earlyExitLocalPath:end"); - const measure = performance.measure( - "hpa:findPath:earlyExitLocalPath", - "hpa:findPath:earlyExitLocalPath:start", - "hpa:findPath:earlyExitLocalPath:end", - ); - - if (debug) { - this.debugInfo!.timings.earlyExitLocalPath = measure.duration; - this.debugInfo!.timings.total += measure.duration; - } + DebugSpan.end(); if (localPath) { - if (debug) { - console.log( - `[DEBUG] Direct local path found for dist=${dist}, length=${localPath.length}`, - ); - } return localPath; } - - if (debug) { - console.log( - `[DEBUG] Direct path failed for dist=${dist}, falling back to abstract graph`, - ); - } } - performance.mark("hpa:findPath:findNodes:start"); + DebugSpan.start("nodeLookup"); const startNode = this.findNearestNode(from); const endNode = this.findNearestNode(to); - performance.mark("hpa:findPath:findNodes:end"); - const findNodesMeasure = performance.measure( - "hpa:findPath:findNodes", - "hpa:findPath:findNodes:start", - "hpa:findPath:findNodes:end", - ); - - if (debug) { - this.debugInfo!.timings.findNodes = findNodesMeasure.duration; - this.debugInfo!.timings.total += findNodesMeasure.duration; - } + DebugSpan.end(); if (!startNode) { - if (debug) { - console.log( - `[DEBUG] Cannot find start node for (${this.map.x(from)}, ${this.map.y(from)})`, - ); - } return null; } if (!endNode) { - if (debug) { - console.log( - `[DEBUG] Cannot find end node for (${this.map.x(to)}, ${this.map.y(to)})`, - ); - } return null; } if (startNode.id === endNode.id) { - if (debug) { - console.log( - `[DEBUG] Start and end nodes are the same (ID=${startNode.id}), finding local path with multi-cluster search`, - ); - } - - performance.mark("hpa:findPath:sameNodeLocalPath:start"); + DebugSpan.start("sameNodeLocalPath"); const clusterX = Math.floor(startNode.x / this.graph.clusterSize); const clusterY = Math.floor(startNode.y / this.graph.clusterSize); const path = this.findLocalPath(from, to, clusterX, clusterY, true); - performance.mark("hpa:findPath:sameNodeLocalPath:end"); - const sameNodeMeasure = performance.measure( - "hpa:findPath:sameNodeLocalPath", - "hpa:findPath:sameNodeLocalPath:start", - "hpa:findPath:sameNodeLocalPath:end", - ); - - if (debug) { - this.debugInfo!.timings.sameNodeLocalPath = sameNodeMeasure.duration; - this.debugInfo!.timings.total += sameNodeMeasure.duration; - } - + DebugSpan.end(); return path; } - performance.mark("hpa:findPath:findAbstractPath:start"); + DebugSpan.start("abstractPath"); const nodePath = this.findAbstractPath(startNode.id, endNode.id); - performance.mark("hpa:findPath:findAbstractPath:end"); - const findAbstractPathMeasure = performance.measure( - "hpa:findPath:findAbstractPath", - "hpa:findPath:findAbstractPath:start", - "hpa:findPath:findAbstractPath:end", - ); - - if (debug) { - this.debugInfo!.timings.findAbstractPath = - findAbstractPathMeasure.duration; - this.debugInfo!.timings.total += findAbstractPathMeasure.duration; - - this.debugInfo!.nodePath = nodePath - ? nodePath - .map((nodeId) => { - const node = this.graph.getNode(nodeId); - return node ? node.tile : -1; - }) - .filter((tile) => tile !== -1) - : null; - } + DebugSpan.end(); if (!nodePath) { - if (debug) { - console.log( - `[DEBUG] No abstract path between nodes ${startNode.id} and ${endNode.id}`, - ); - } return null; } - if (debug) { - console.log(`[DEBUG] Abstract path found: ${nodePath.length} waypoints`); - } + DebugSpan.set("nodePath", () => + nodePath + .map((nodeId) => { + const node = this.graph.getNode(nodeId); + return node ? node.tile : -1; + }) + .filter((tile) => tile !== -1), + ); const initialPath: TileRef[] = []; - performance.mark("hpa:findPath:buildInitialPath:start"); + DebugSpan.start("initialPath"); // 1. Find path from start to first node const firstNode = this.graph.getNode(nodePath[0])!; @@ -324,6 +186,10 @@ export class AStarWaterHierarchical implements PathFinder { if (cachedPath && cachedPath.length > 0) { // Path is cached for this exact direction, use as-is initialPath.push(...cachedPath.slice(1)); + DebugSpan.set( + "$cachedSegmentsUsed", + (prev) => ((prev as number) ?? 0) + 1, + ); continue; } } @@ -368,20 +234,7 @@ export class AStarWaterHierarchical implements PathFinder { initialPath.push(...endSegment.slice(1)); - performance.mark("hpa:findPath:buildInitialPath:end"); - const buildInitialPathMeasure = performance.measure( - "hpa:findPath:buildInitialPath", - "hpa:findPath:buildInitialPath:start", - "hpa:findPath:buildInitialPath:end", - ); - - if (debug) { - this.debugInfo!.timings.buildInitialPath = - buildInitialPathMeasure.duration; - this.debugInfo!.timings.total += buildInitialPathMeasure.duration; - this.debugInfo!.initialPath = initialPath; - console.log(`[DEBUG] Initial path: ${initialPath.length} tiles`); - } + DebugSpan.set("initialPath", () => initialPath); // Smoothing moved to SmoothingTransformer - return raw path return initialPath; diff --git a/src/core/pathfinding/algorithms/AbstractGraph.ts b/src/core/pathfinding/algorithms/AbstractGraph.ts index d7be8faeb..f22b30c65 100644 --- a/src/core/pathfinding/algorithms/AbstractGraph.ts +++ b/src/core/pathfinding/algorithms/AbstractGraph.ts @@ -1,4 +1,5 @@ import { GameMap, TileRef } from "../../game/GameMap"; +import { DebugSpan } from "../../utilities/DebugSpan"; import { BFSGrid } from "./BFS.Grid"; import { ConnectedComponents } from "./ConnectedComponents"; @@ -25,16 +26,6 @@ export interface Cluster { nodeIds: number[]; } -export type BuildDebugInfo = { - clusters: number | null; - nodes: number | null; - edges: number | null; - actualBFSCalls: number | null; - potentialBFSCalls: number | null; - skippedByComponentFilter: number | null; - timings: { [key: string]: number }; -}; - export class AbstractGraph { // Nodes (array indexed by id) private readonly _nodes: AbstractNode[] = []; @@ -97,6 +88,10 @@ export class AbstractGraph { return edge.nodeA === nodeId ? edge.nodeB : edge.nodeA; } + getAllEdges(): readonly AbstractEdge[] { + return this._edges; + } + get edgeCount(): number { return this._edges.length; } @@ -217,8 +212,6 @@ export class AbstractGraphBuilder { private nextEdgeId = 0; private edgeBetween = new Map>(); - public debugInfo: BuildDebugInfo | null = null; - constructor( private readonly map: GameMap, private readonly clusterSize: number = AbstractGraphBuilder.CLUSTER_SIZE, @@ -231,8 +224,8 @@ export class AbstractGraphBuilder { this.waterComponents = new ConnectedComponents(map); } - build(debug: boolean = false): AbstractGraph { - performance.mark("abstractgraph:build:start"); + build(): AbstractGraph { + DebugSpan.start("AbstractGraphBuilder:build"); this.graph = new AbstractGraph( this.clusterSize, @@ -240,37 +233,8 @@ export class AbstractGraphBuilder { this.clustersY, ); - if (debug) { - console.log( - `[DEBUG] Building abstract graph with cluster size ${this.clusterSize} (${this.clustersX}x${this.clustersY} clusters)`, - ); - - this.debugInfo = { - clusters: null, - nodes: null, - edges: null, - actualBFSCalls: null, - potentialBFSCalls: null, - skippedByComponentFilter: null, - timings: {}, - }; - } - // Initialize water components - performance.mark("abstractgraph:build:water-component:start"); this.waterComponents.initialize(); - performance.mark("abstractgraph:build:water-component:end"); - const wcMeasure = performance.measure( - "abstractgraph:build:water-component", - "abstractgraph:build:water-component:start", - "abstractgraph:build:water-component:end", - ); - - if (debug) { - console.log( - `[DEBUG] Water Component Identification: ${wcMeasure.duration.toFixed(2)}ms`, - ); - } // Pre-create all clusters for (let cy = 0; cy < this.clustersY; cy++) { @@ -281,98 +245,30 @@ export class AbstractGraphBuilder { } // Find nodes (gateways) at cluster boundaries - performance.mark("abstractgraph:build:nodes:start"); + DebugSpan.start("nodes"); for (let cy = 0; cy < this.clustersY; cy++) { for (let cx = 0; cx < this.clustersX; cx++) { this.processCluster(cx, cy); } } - performance.mark("abstractgraph:build:nodes:end"); - const nodesMeasure = performance.measure( - "abstractgraph:build:nodes", - "abstractgraph:build:nodes:start", - "abstractgraph:build:nodes:end", - ); - - if (debug) { - console.log( - `[DEBUG] Node identification: ${nodesMeasure.duration.toFixed(2)}ms`, - ); - this.debugInfo!.potentialBFSCalls = 0; - this.debugInfo!.skippedByComponentFilter = 0; - } + DebugSpan.end(); // Build edges between nodes in same cluster - performance.mark("abstractgraph:build:edges:start"); + DebugSpan.start("edges"); for (let cy = 0; cy < this.clustersY; cy++) { for (let cx = 0; cx < this.clustersX; cx++) { const cluster = this.graph.getCluster(cx, cy); if (!cluster || cluster.nodeIds.length === 0) continue; - - if (debug) { - const n = cluster.nodeIds.length; - this.debugInfo!.potentialBFSCalls! += (n * (n - 1)) / 2; - - // Count skipped by component filter - for (let i = 0; i < n; i++) { - for (let j = i + 1; j < n; j++) { - const nodeI = this.graph.getNode(cluster.nodeIds[i])!; - const nodeJ = this.graph.getNode(cluster.nodeIds[j])!; - if (nodeI.componentId !== nodeJ.componentId) { - this.debugInfo!.skippedByComponentFilter!++; - } - } - } - } - this.buildClusterConnections(cx, cy); } } - performance.mark("abstractgraph:build:edges:end"); - const edgesMeasure = performance.measure( - "abstractgraph:build:edges", - "abstractgraph:build:edges:start", - "abstractgraph:build:edges:end", - ); + DebugSpan.end(); - if (debug) { - this.debugInfo!.actualBFSCalls = - this.debugInfo!.potentialBFSCalls! - - this.debugInfo!.skippedByComponentFilter!; - - console.log( - `[DEBUG] Edge identification: ${edgesMeasure.duration.toFixed(2)}ms`, - ); - console.log( - `[DEBUG] Potential BFS calls: ${this.debugInfo!.potentialBFSCalls}`, - ); - console.log( - `[DEBUG] Skipped by component filter: ${this.debugInfo!.skippedByComponentFilter} (${((this.debugInfo!.skippedByComponentFilter! / this.debugInfo!.potentialBFSCalls!) * 100).toFixed(1)}%)`, - ); - console.log( - `[DEBUG] Actual BFS calls: ${this.debugInfo!.actualBFSCalls}`, - ); - } - - performance.mark("abstractgraph:build:end"); - const totalMeasure = performance.measure( - "abstractgraph:build:total", - "abstractgraph:build:start", - "abstractgraph:build:end", - ); - - if (debug) { - console.log( - `[DEBUG] Abstract graph built in ${totalMeasure.duration.toFixed(2)}ms`, - ); - console.log(`[DEBUG] Nodes: ${this.graph.nodeCount}`); - console.log(`[DEBUG] Edges: ${this.graph.edgeCount}`); - console.log(`[DEBUG] Clusters: ${this.clustersX * this.clustersY}`); - - this.debugInfo!.clusters = this.clustersX * this.clustersY; - this.debugInfo!.nodes = this.graph.nodeCount; - this.debugInfo!.edges = this.graph.edgeCount; - } + DebugSpan.set("nodes", () => this.graph.getAllNodes()); + DebugSpan.set("edges", () => this.graph.getAllEdges()); + DebugSpan.set("nodesCount", () => this.graph.nodeCount); + DebugSpan.set("edgesCount", () => this.graph.edgeCount); + DebugSpan.set("clustersCount", () => this.clustersX * this.clustersY); // Initialize path cache after all edges are built this.graph._initPathCache(); @@ -380,6 +276,8 @@ export class AbstractGraphBuilder { // Store water components for componentId lookups this.graph.setWaterComponents(this.waterComponents); + DebugSpan.end(); // AbstractGraphBuilder:build + return this.graph; } diff --git a/src/core/pathfinding/algorithms/ConnectedComponents.ts b/src/core/pathfinding/algorithms/ConnectedComponents.ts index 93813b341..0d379d3c1 100644 --- a/src/core/pathfinding/algorithms/ConnectedComponents.ts +++ b/src/core/pathfinding/algorithms/ConnectedComponents.ts @@ -1,6 +1,7 @@ // Connected Component Labeling using flood-fill import { GameMap, TileRef } from "../../game/GameMap"; +import { DebugSpan } from "../../utilities/DebugSpan"; export const LAND_MARKER = 0xff; // Must fit in Uint8Array @@ -28,6 +29,7 @@ export class ConnectedComponents { } initialize(): void { + DebugSpan.start("ConnectedComponents:initialize"); let ids: Uint8Array | Uint16Array = this.createPrefilledIds(); let nextId = 0; @@ -52,6 +54,7 @@ export class ConnectedComponents { } this.componentIds = ids; + DebugSpan.end(); } /** diff --git a/src/core/pathfinding/smoothing/BresenhamPathSmoother.ts b/src/core/pathfinding/smoothing/BresenhamPathSmoother.ts deleted file mode 100644 index d4cafdba9..000000000 --- a/src/core/pathfinding/smoothing/BresenhamPathSmoother.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { GameMap, TileRef } from "../../game/GameMap"; -import { PathFinder } from "../types"; -import { PathSmoother } from "./PathSmoother"; - -/** - * Path smoother using Bresenham line-of-sight algorithm. - * Greedily skips waypoints when direct traversal is possible. - */ -export class BresenhamPathSmoother implements PathSmoother { - constructor( - private map: GameMap, - private isTraversable: (tile: TileRef) => boolean, - ) {} - - smooth(path: TileRef[]): TileRef[] { - if (path.length <= 2) { - return path; - } - - const smoothed: TileRef[] = []; - let current = 0; - - while (current < path.length - 1) { - let farthest = current + 1; - let bestTrace: TileRef[] | null = null; - - for ( - let i = current + 2; - i < path.length; - i += Math.max(1, Math.floor(path.length / 20)) - ) { - const trace = this.tracePath(path[current], path[i]); - - if (trace !== null) { - farthest = i; - bestTrace = trace; - } else { - break; - } - } - - if ( - farthest < path.length - 1 && - (path.length - 1 - current) % 10 !== 0 - ) { - const trace = this.tracePath(path[current], path[path.length - 1]); - if (trace !== null) { - farthest = path.length - 1; - bestTrace = trace; - } - } - - if (bestTrace !== null && farthest > current + 1) { - smoothed.push(...bestTrace.slice(0, -1)); - } else { - smoothed.push(path[current]); - } - - current = farthest; - } - - smoothed.push(path[path.length - 1]); - - return smoothed; - } - - private tracePath(from: TileRef, to: TileRef): TileRef[] | null { - const x0 = this.map.x(from); - const y0 = this.map.y(from); - const x1 = this.map.x(to); - const y1 = this.map.y(to); - - const tiles: TileRef[] = []; - - const dx = Math.abs(x1 - x0); - const dy = Math.abs(y1 - y0); - const sx = x0 < x1 ? 1 : -1; - const sy = y0 < y1 ? 1 : -1; - let err = dx - dy; - - let x = x0; - let y = y0; - - const maxTiles = 100000; - let iterations = 0; - - while (true) { - if (iterations++ > maxTiles) { - return null; - } - const tile = this.map.ref(x, y); - if (!this.isTraversable(tile)) { - return null; - } - - tiles.push(tile); - - if (x === x1 && y === y1) { - break; - } - - const e2 = 2 * err; - const shouldMoveX = e2 > -dy; - const shouldMoveY = e2 < dx; - - if (shouldMoveX && shouldMoveY) { - x += sx; - err -= dy; - - const intermediateTile = this.map.ref(x, y); - if (!this.isTraversable(intermediateTile)) { - x -= sx; - err += dy; - - y += sy; - err += dx; - - const altTile = this.map.ref(x, y); - if (!this.isTraversable(altTile)) { - return null; - } - tiles.push(altTile); - - x += sx; - err -= dy; - } else { - tiles.push(intermediateTile); - - y += sy; - err += dx; - } - } else { - if (shouldMoveX) { - x += sx; - err -= dy; - } - - if (shouldMoveY) { - y += sy; - err += dx; - } - } - } - - return tiles; - } -} - -/** - * Ready-to-use transformer that applies Bresenham smoothing. - * Defaults to water traversability. - */ -export class BresenhamSmoothingTransformer implements PathFinder { - private smoother: BresenhamPathSmoother; - - constructor( - private inner: PathFinder, - map: GameMap, - isTraversable: (tile: TileRef) => boolean = (t) => map.isWater(t), - ) { - this.smoother = new BresenhamPathSmoother(map, isTraversable); - } - - findPath(from: TileRef | TileRef[], to: TileRef): TileRef[] | null { - const path = this.inner.findPath(from, to); - return path ? this.smoother.smooth(path) : null; - } -} diff --git a/src/core/pathfinding/smoothing/PathSmoother.ts b/src/core/pathfinding/smoothing/PathSmoother.ts deleted file mode 100644 index fc4188afc..000000000 --- a/src/core/pathfinding/smoothing/PathSmoother.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * PathSmoother - interface for path smoothing algorithms. - * Takes a path and returns a smoothed version. - */ -export interface PathSmoother { - smooth(path: T[]): T[]; -} diff --git a/src/core/pathfinding/smoothing/SmoothingTransformer.ts b/src/core/pathfinding/smoothing/SmoothingTransformer.ts deleted file mode 100644 index ed1c60bff..000000000 --- a/src/core/pathfinding/smoothing/SmoothingTransformer.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { PathFinder } from "../types"; -import { PathSmoother } from "./PathSmoother"; - -/** - * Transformer that applies path smoothing to any PathFinder. - * Wraps an inner PathFinder and smooths its output. - */ -export class SmoothingTransformer implements PathFinder { - constructor( - private inner: PathFinder, - private smoother: PathSmoother, - ) {} - - findPath(from: T | T[], to: T): T[] | null { - const path = this.inner.findPath(from, to); - return path ? this.smoother.smooth(path) : null; - } -} diff --git a/src/core/pathfinding/transformers/SmoothingWaterTransformer.ts b/src/core/pathfinding/transformers/SmoothingWaterTransformer.ts new file mode 100644 index 000000000..63b30c97f --- /dev/null +++ b/src/core/pathfinding/transformers/SmoothingWaterTransformer.ts @@ -0,0 +1,341 @@ +import { GameMap, TileRef } from "../../game/GameMap"; +import { DebugSpan } from "../../utilities/DebugSpan"; +import { + AStarWaterBounded, + SearchBounds, +} from "../algorithms/AStar.WaterBounded"; +import { PathFinder } from "../types"; + +const ENDPOINT_REFINEMENT_TILES = 50; +const LOCAL_ASTAR_MAX_AREA = 100 * 100; +const LOS_MIN_MAGNITUDE = 3; +const MAGNITUDE_MASK = 0x1f; + +/** + * Water path smoother transformer with two passes: + * 1. Binary search LOS smoothing (avoids shallow water) + * 2. Local A* refinement on endpoints (first/last N tiles) + */ +export class SmoothingWaterTransformer implements PathFinder { + private readonly mapWidth: number; + private readonly localAStar: AStarWaterBounded; + private readonly terrain: Uint8Array; + private readonly isTraversable: (tile: TileRef) => boolean; + + constructor( + private inner: PathFinder, + private map: GameMap, + isTraversable: (tile: TileRef) => boolean = (t) => map.isWater(t), + ) { + this.mapWidth = map.width(); + this.localAStar = new AStarWaterBounded(map, LOCAL_ASTAR_MAX_AREA); + this.terrain = (map as any).terrain as Uint8Array; + this.isTraversable = isTraversable; + } + + findPath(from: TileRef | TileRef[], to: TileRef): TileRef[] | null { + const path = this.inner.findPath(from, to); + + return DebugSpan.wrap("smoothingTransformer", () => + path ? this.smooth(path) : null, + ); + } + + private smooth(path: TileRef[]): TileRef[] { + if (path.length <= 2) { + return path; + } + + // Pass 1: LOS smoothing with binary search + let smoothed = DebugSpan.wrap("smoother:los", () => this.losSmooth(path)); + + // Pass 2: Local A* refinement on endpoints + smoothed = DebugSpan.wrap("smoother:refine", () => + this.refineEndpoints(smoothed), + ); + + return smoothed; + } + + private losSmooth(path: TileRef[]): TileRef[] { + const result: TileRef[] = [path[0]]; + let current = 0; + + while (current < path.length - 1) { + // Binary search for farthest visible waypoint + let lo = current + 1; + let hi = path.length - 1; + let farthest = lo; + + while (lo <= hi) { + const mid = (lo + hi) >>> 1; + if (this.canSee(path[current], path[mid])) { + farthest = mid; + lo = mid + 1; + } else { + hi = mid - 1; + } + } + + // Trace the path to farthest visible point + if (farthest > current + 1) { + const trace = this.tracePath(path[current], path[farthest]); + if (trace) { + // Add all intermediate tiles except the last (will be added in next iteration or at end) + for (let i = 1; i < trace.length - 1; i++) { + result.push(trace[i]); + } + } + } + + current = farthest; + if (current < path.length - 1) { + result.push(path[current]); + } + } + + result.push(path[path.length - 1]); + return result; + } + + private refineEndpoints(path: TileRef[]): TileRef[] { + if (path.length <= 2) { + return path; + } + + const refineDist = ENDPOINT_REFINEMENT_TILES; + let result = path; + + // Find the index where cumulative distance reaches refineDist from start + const startEndIdx = this.findTileAtDistance(path, 0, refineDist, true); + + // Refine start segment if it's more than 2 tiles and not already optimal + if (startEndIdx > 1) { + const startSegment = this.refineSegment(path[0], path[startEndIdx]); + + if (startSegment && startSegment.length > 0) { + result = [...startSegment.slice(0, -1), ...result.slice(startEndIdx)]; + } + } + + // Find the index where cumulative distance reaches refineDist from end + const endStartIdx = this.findTileAtDistance( + result, + result.length - 1, + refineDist, + false, + ); + + // Refine end segment if it's more than 2 tiles and not already optimal + // Search in reverse (from destination backwards) so path approaches target naturally + if (endStartIdx < result.length - 2) { + const endSegment = this.refineSegment( + result[result.length - 1], + result[endStartIdx], + ); + + if (endSegment && endSegment.length > 0) { + endSegment.reverse(); + result = [...result.slice(0, endStartIdx), ...endSegment]; + } + } + + return result; + } + + private findTileAtDistance( + path: TileRef[], + startIdx: number, + distance: number, + forward: boolean, + ): number { + let cumDist = 0; + let idx = startIdx; + + if (forward) { + while (idx < path.length - 1 && cumDist < distance) { + cumDist += this.manhattanDist(path[idx], path[idx + 1]); + idx++; + } + } else { + while (idx > 0 && cumDist < distance) { + cumDist += this.manhattanDist(path[idx], path[idx - 1]); + idx--; + } + } + + return idx; + } + + private refineSegment(from: TileRef, to: TileRef): TileRef[] | null { + const x0 = this.map.x(from); + const y0 = this.map.y(from); + const x1 = this.map.x(to); + const y1 = this.map.y(to); + + // Calculate bounds with padding + const padding = 10; + const bounds: SearchBounds = { + minX: Math.max(0, Math.min(x0, x1) - padding), + maxX: Math.min(this.map.width() - 1, Math.max(x0, x1) + padding), + minY: Math.max(0, Math.min(y0, y1) - padding), + maxY: Math.min(this.map.height() - 1, Math.max(y0, y1) + padding), + }; + + return this.localAStar.searchBounded(from, to, bounds); + } + + private canSee(from: TileRef, to: TileRef): boolean { + const x0 = from % this.mapWidth; + const y0 = (from / this.mapWidth) | 0; + const x1 = to % this.mapWidth; + const y1 = (to / this.mapWidth) | 0; + + const dx = Math.abs(x1 - x0); + const dy = Math.abs(y1 - y0); + const sx = x0 < x1 ? 1 : -1; + const sy = y0 < y1 ? 1 : -1; + let err = dx - dy; + + let x = x0; + let y = y0; + + const maxTiles = 100000; + let iterations = 0; + + while (true) { + if (iterations++ > maxTiles) return false; + + const tile = (y * this.mapWidth + x) as TileRef; + if (!this.isTraversable(tile)) return false; + + // Check magnitude - avoid shallow water + const magnitude = this.terrain[tile] & MAGNITUDE_MASK; + if (magnitude < LOS_MIN_MAGNITUDE) return false; + + if (x === x1 && y === y1) return true; + + const e2 = 2 * err; + const shouldMoveX = e2 > -dy; + const shouldMoveY = e2 < dx; + + if (shouldMoveX && shouldMoveY) { + // Diagonal move - check intermediate tile + x += sx; + err -= dy; + + const intermediateTile = (y * this.mapWidth + x) as TileRef; + const intMag = this.terrain[intermediateTile] & MAGNITUDE_MASK; + if ( + !this.isTraversable(intermediateTile) || + intMag < LOS_MIN_MAGNITUDE + ) { + // Try alternative path + x -= sx; + err += dy; + y += sy; + err += dx; + + const altTile = (y * this.mapWidth + x) as TileRef; + const altMag = this.terrain[altTile] & MAGNITUDE_MASK; + if (!this.isTraversable(altTile) || altMag < LOS_MIN_MAGNITUDE) + return false; + + x += sx; + err -= dy; + } else { + y += sy; + err += dx; + } + } else { + if (shouldMoveX) { + x += sx; + err -= dy; + } + if (shouldMoveY) { + y += sy; + err += dx; + } + } + } + } + + private tracePath(from: TileRef, to: TileRef): TileRef[] | null { + const x0 = from % this.mapWidth; + const y0 = (from / this.mapWidth) | 0; + const x1 = to % this.mapWidth; + const y1 = (to / this.mapWidth) | 0; + + const tiles: TileRef[] = []; + + const dx = Math.abs(x1 - x0); + const dy = Math.abs(y1 - y0); + const sx = x0 < x1 ? 1 : -1; + const sy = y0 < y1 ? 1 : -1; + let err = dx - dy; + + let x = x0; + let y = y0; + + const maxTiles = 100000; + let iterations = 0; + + while (true) { + if (iterations++ > maxTiles) return null; + + const tile = (y * this.mapWidth + x) as TileRef; + if (!this.isTraversable(tile)) return null; + + tiles.push(tile); + + if (x === x1 && y === y1) break; + + const e2 = 2 * err; + const shouldMoveX = e2 > -dy; + const shouldMoveY = e2 < dx; + + if (shouldMoveX && shouldMoveY) { + x += sx; + err -= dy; + + const intermediateTile = (y * this.mapWidth + x) as TileRef; + if (!this.isTraversable(intermediateTile)) { + x -= sx; + err += dy; + y += sy; + err += dx; + + const altTile = (y * this.mapWidth + x) as TileRef; + if (!this.isTraversable(altTile)) return null; + tiles.push(altTile); + + x += sx; + err -= dy; + } else { + tiles.push(intermediateTile); + y += sy; + err += dx; + } + } else { + if (shouldMoveX) { + x += sx; + err -= dy; + } + if (shouldMoveY) { + y += sy; + err += dx; + } + } + } + + return tiles; + } + + private manhattanDist(a: TileRef, b: TileRef): number { + const ax = a % this.mapWidth; + const ay = (a / this.mapWidth) | 0; + const bx = b % this.mapWidth; + const by = (b / this.mapWidth) | 0; + return Math.abs(ax - bx) + Math.abs(ay - by); + } +} diff --git a/src/core/utilities/DebugSpan.ts b/src/core/utilities/DebugSpan.ts new file mode 100644 index 000000000..b33b96acf --- /dev/null +++ b/src/core/utilities/DebugSpan.ts @@ -0,0 +1,159 @@ +type Span = { + name: string; + timeStart: number; + timeEnd?: number; + duration?: number; + data: Record; + children: Span[]; +}; + +const stack: Span[] = []; + +function isEnabled(): boolean { + return globalThis.__DEBUG_SPAN_ENABLED__ === true; +} + +export const DebugSpan = { + isEnabled, + enable(): void { + globalThis.__DEBUG_SPAN_ENABLED__ = true; + }, + disable(): void { + globalThis.__DEBUG_SPAN_ENABLED__ = false; + }, + start(name: string): void { + if (!isEnabled()) return; + + const span: Span = { + name, + timeStart: performance.now(), + data: {}, + children: [], + }; + + const parent = stack[stack.length - 1]; + parent?.children.push(span); + stack.push(span); + }, + end(name?: string): void { + if (!isEnabled()) return; + + if (stack.length === 0) { + const payload = name ? `"${name}"` : ""; + throw new Error(`DebugSpan.end(${payload}): no open span`); + } + + // If name provided, close all spans up to and including the named one + if (name) { + while (stack.length > 0) { + const span = stack.pop()!; + span.timeEnd = performance.now(); + span.duration = span.timeEnd - span.timeStart; + + if (stack.length === 0) { + DebugSpan.storeSpan(span); + } + + if (span.name === name) break; + } + return; + } + + // Default: close just the current span + const span = stack.pop()!; + span.timeEnd = performance.now(); + span.duration = span.timeEnd - span.timeStart; + + if (stack.length === 0) { + DebugSpan.storeSpan(span); + } + }, + storeSpan(span: Span): void { + if (!isEnabled()) return; + + globalThis.__DEBUG_SPANS__ = globalThis.__DEBUG_SPANS__ ?? []; + globalThis.__DEBUG_SPANS__.push(span); + + const extractData = (span: Span): Record => { + return Object.fromEntries( + Object.entries(span.data).filter( + ([key]) => typeof key === "string" && key.startsWith("$"), + ), + ); + }; + + const properties = { + timings: { total: span.duration }, + data: extractData(span), + }; + + if (span.children.length > 0) { + const getChildren = (span: Span): Span[] => + span.children.flatMap((child) => [child, ...getChildren(child)]); + const children = getChildren(span); + for (const childSpan of children) { + properties.timings[childSpan.name] = childSpan.duration; + const childData = extractData(childSpan); + for (const key of Object.keys(childData)) { + properties.data[key] = childData[key]; + } + } + } + + try { + performance.measure(span.name, { + start: span.timeStart, + end: span.timeEnd, + detail: properties, + }); + } catch (err) { + console.error("DebugSpan.storeSpan: performance.measure failed", err); + console.error("Span:", span); + } + + while (globalThis.__DEBUG_SPANS__.length > 100) { + globalThis.__DEBUG_SPANS__.shift(); + } + }, + wrap(name: string, fn: () => T): T { + this.start(name); + + try { + return fn(); + } finally { + this.end(name); + } + }, + set( + key: string, + valueFn: (previous: unknown) => unknown, + root: boolean = true, + ): void { + if (!isEnabled()) return; + + if (stack.length === 0) { + throw new Error(`DebugSpan.set("${key}"): no open span`); + } + + const span = root ? stack[0] : stack[stack.length - 1]; + span.data[key] = valueFn(span.data[key]); + }, + getLastSpan(name?: string): Span | undefined { + if (!isEnabled()) return; + + globalThis.__DEBUG_SPANS__ = globalThis.__DEBUG_SPANS__ ?? []; + + if (name) { + for (let i = globalThis.__DEBUG_SPANS__.length - 1 || 0; i >= 0; i--) { + const span = globalThis.__DEBUG_SPANS__[i]; + if (span.name === name) { + return span; + } + } + + return undefined; + } + + return globalThis.__DEBUG_SPANS__[globalThis.__DEBUG_SPANS__.length - 1]; + }, +}; diff --git a/tests/pathfinding/playground/api/maps.ts b/tests/pathfinding/playground/api/maps.ts index 4bafc6fed..c1a7b084f 100644 --- a/tests/pathfinding/playground/api/maps.ts +++ b/tests/pathfinding/playground/api/maps.ts @@ -2,39 +2,40 @@ import { readdirSync, readFileSync } from "fs"; import { dirname, join } from "path"; import { fileURLToPath } from "url"; import { Game } from "../../../../src/core/game/Game.js"; -import { AStarWaterHierarchical } from "../../../../src/core/pathfinding/algorithms/AStar.WaterHierarchical.js"; +import { DebugSpan } from "../../../../src/core/utilities/DebugSpan.js"; import { setupFromPath } from "../../utils.js"; // Available comparison adapters -// Note: "hpa" runs same algorithm without debug overhead for fair timing comparison -export const COMPARISON_ADAPTERS = ["hpa", "a.baseline", "a.generic", "a.full"]; +// Note: "hpa.cached" runs same algorithm without debug overhead for fair timing comparison +export const COMPARISON_ADAPTERS = [ + "hpa.cached", + "hpa", + "a.baseline", + "a.generic", + "a.full", +]; export interface MapInfo { name: string; displayName: string; } +export interface GraphBuildData { + nodes: any[]; + edges: any[]; + nodesCount: number; + edgesCount: number; + clustersCount: number; + buildTime: number; +} + export interface MapCache { game: Game; - hpaStar: AStarWaterHierarchical; + graphBuildData: GraphBuildData | null; } const cache = new Map(); -/** - * Global configuration for map loading - */ -let config = { - cachePaths: true, -}; - -/** - * Set configuration options - */ -export function setConfig(options: { cachePaths?: boolean }) { - config = { ...config, ...options }; -} - /** * Get the resources/maps directory path */ @@ -105,6 +106,25 @@ export function listMaps(): MapInfo[] { return maps.sort((a, b) => a.displayName.localeCompare(b.displayName)); } +/** + * Extract graph build data from DebugSpan + */ +function extractGraphBuildData(): GraphBuildData | null { + const span = DebugSpan.getLastSpan(); + if (!span || span.name !== "AbstractGraphBuilder:build") { + return null; + } + + return { + nodes: (span.data.nodes as any[]) || [], + edges: (span.data.edges as any[]) || [], + nodesCount: (span.data.nodesCount as number) || 0, + edgesCount: (span.data.edgesCount as number) || 0, + clustersCount: (span.data.clustersCount as number) || 0, + buildTime: span.duration || 0, + }; +} + /** * Load a map from cache or disk */ @@ -116,21 +136,17 @@ export async function loadMap(mapName: string): Promise { const mapsDir = getMapsDirectory(); + // Enable DebugSpan to capture graph build data + DebugSpan.enable(); + // Use the existing setupFromPath utility to load the map const game = await setupFromPath(mapsDir, mapName, { disableNavMesh: false }); - // Get pre-built graph from game - const graph = game.miniWaterGraph(); - if (!graph) { - throw new Error(`No water graph available for map: ${mapName}`); - } - - // Initialize AStarWaterHierarchical with minimap and graph - const hpaStar = new AStarWaterHierarchical(game.miniMap(), graph, { - cachePaths: config.cachePaths, - }); + // Capture graph build data from DebugSpan + const graphBuildData = extractGraphBuildData(); + DebugSpan.disable(); - const cacheEntry: MapCache = { game, hpaStar }; + const cacheEntry: MapCache = { game, graphBuildData }; // Store in cache cache.set(mapName, cacheEntry); @@ -142,7 +158,7 @@ export async function loadMap(mapName: string): Promise { * Get map metadata for client */ export async function getMapMetadata(mapName: string) { - const { game, hpaStar } = await loadMap(mapName); + const { game, graphBuildData } = await loadMap(mapName); // Extract map data const mapData: number[] = []; @@ -153,48 +169,83 @@ export async function getMapMetadata(mapName: string) { } } - // Extract static graph data from GameMapHPAStar - // Access internal graph via type casting (test code only) - const graph = (hpaStar as any).graph; + const graph = game.miniWaterGraph(); const miniMap = game.miniMap(); + const clusterSize = graph?.clusterSize ?? 0; - // Convert nodes to client format - const allNodes = graph.getAllNodes().map((node: any) => ({ - id: node.id, - x: miniMap.x(node.tile), - y: miniMap.y(node.tile), - })); - - // Convert edges to client format - const edges: Array<{ + // Use graphBuildData from DebugSpan if available, otherwise fall back to direct access + let allNodes: Array<{ id: number; x: number; y: number }>; + let edges: Array<{ fromId: number; toId: number; from: number[]; to: number[]; cost: number; - }> = []; - for (let i = 0; i < graph.edgeCount; i++) { - const edge = graph.getEdge(i); - if (!edge) continue; - - const nodeA = graph.getNode(edge.nodeA); - const nodeB = graph.getNode(edge.nodeB); - if (!nodeA || !nodeB) continue; - - edges.push({ - fromId: edge.nodeA, - toId: edge.nodeB, - from: [miniMap.x(nodeA.tile) * 2, miniMap.y(nodeA.tile) * 2], - to: [miniMap.x(nodeB.tile) * 2, miniMap.y(nodeB.tile) * 2], - cost: edge.cost, + }>; + + if (graphBuildData) { + // Convert nodes from DebugSpan data (AbstractNode format) + allNodes = graphBuildData.nodes.map((node: any) => ({ + id: node.id, + x: miniMap.x(node.tile), + y: miniMap.y(node.tile), + })); + + // Convert edges from DebugSpan data (AbstractEdge format) + edges = graphBuildData.edges.map((edge: any) => { + const nodeA = graphBuildData.nodes.find((n: any) => n.id === edge.nodeA); + const nodeB = graphBuildData.nodes.find((n: any) => n.id === edge.nodeB); + return { + fromId: edge.nodeA, + toId: edge.nodeB, + from: nodeA + ? [miniMap.x(nodeA.tile) * 2, miniMap.y(nodeA.tile) * 2] + : [0, 0], + to: nodeB + ? [miniMap.x(nodeB.tile) * 2, miniMap.y(nodeB.tile) * 2] + : [0, 0], + cost: edge.cost, + }; }); - } - console.log( - `Map ${mapName}: ${allNodes.length} nodes, ${edges.length} edges`, - ); + console.log( + `Map ${mapName}: ${allNodes.length} nodes, ${edges.length} edges (from DebugSpan, built in ${graphBuildData.buildTime.toFixed(2)}ms)`, + ); + } else if (graph) { + // Fallback: extract directly from graph + allNodes = graph.getAllNodes().map((node: any) => ({ + id: node.id, + x: miniMap.x(node.tile), + y: miniMap.y(node.tile), + })); + + edges = []; + for (let i = 0; i < graph.edgeCount; i++) { + const edge = graph.getEdge(i); + if (!edge) continue; + + const nodeA = graph.getNode(edge.nodeA); + const nodeB = graph.getNode(edge.nodeB); + if (!nodeA || !nodeB) continue; + + edges.push({ + fromId: edge.nodeA, + toId: edge.nodeB, + from: [miniMap.x(nodeA.tile) * 2, miniMap.y(nodeA.tile) * 2], + to: [miniMap.x(nodeB.tile) * 2, miniMap.y(nodeB.tile) * 2], + cost: edge.cost, + }); + } - const clusterSize = graph.clusterSize; + console.log( + `Map ${mapName}: ${allNodes.length} nodes, ${edges.length} edges (fallback)`, + ); + } else { + // No graph available + allNodes = []; + edges = []; + console.log(`Map ${mapName}: no graph available`); + } return { name: mapName, @@ -205,6 +256,7 @@ export async function getMapMetadata(mapName: string) { allNodes, edges, clusterSize, + buildTime: graphBuildData?.buildTime, }, adapters: COMPARISON_ADAPTERS, }; diff --git a/tests/pathfinding/playground/api/pathfinding.ts b/tests/pathfinding/playground/api/pathfinding.ts index 9cc69aa53..e1a8fd32f 100644 --- a/tests/pathfinding/playground/api/pathfinding.ts +++ b/tests/pathfinding/playground/api/pathfinding.ts @@ -1,13 +1,7 @@ import { TileRef } from "../../../../src/core/game/GameMap.js"; -import { AStarWaterHierarchical } from "../../../../src/core/pathfinding/algorithms/AStar.WaterHierarchical.js"; -import { BresenhamSmoothingTransformer } from "../../../../src/core/pathfinding/smoothing/BresenhamPathSmoother.js"; -import { ComponentCheckTransformer } from "../../../../src/core/pathfinding/transformers/ComponentCheckTransformer.js"; -import { MiniMapTransformer } from "../../../../src/core/pathfinding/transformers/MiniMapTransformer.js"; -import { ShoreCoercingTransformer } from "../../../../src/core/pathfinding/transformers/ShoreCoercingTransformer.js"; -import { - PathFinder, - SteppingPathFinder, -} from "../../../../src/core/pathfinding/types.js"; +import { PathFinding } from "../../../../src/core/pathfinding/PathFinder.js"; +import { SteppingPathFinder } from "../../../../src/core/pathfinding/types.js"; +import { DebugSpan } from "../../../../src/core/utilities/DebugSpan.js"; import { getAdapter } from "../../utils.js"; import { COMPARISON_ADAPTERS, loadMap } from "./maps.js"; @@ -19,6 +13,7 @@ interface PrimaryResult { debug: { nodePath: Array<[number, number]> | null; initialPath: Array<[number, number]> | null; + cachedSegmentsUsed: number | null; timings: Record; }; } @@ -73,63 +68,54 @@ function pathToCoords( } /** - * Build the full transformer chain like PathFinding.Water() does + * Extract timings from DebugSpan hierarchy + * Flattens nested spans into { spanName: duration } format */ -function buildWrappedPathFinder( - hpaStar: AStarWaterHierarchical, - game: any, - graph: any, -): PathFinder { - const miniMap = game.miniMap(); - const componentCheckFn = (t: TileRef) => graph.getComponentId(t); - - // Chain: hpaStar -> ComponentCheck -> Bresenham -> ShoreCoercing -> MiniMap - const withComponentCheck = new ComponentCheckTransformer( - hpaStar, - componentCheckFn, - ); - const withSmoothing = new BresenhamSmoothingTransformer( - withComponentCheck, - miniMap, - ); - const withShoreCoercing = new ShoreCoercingTransformer( - withSmoothing, - miniMap, - ); - const withMiniMap = new MiniMapTransformer(withShoreCoercing, game, miniMap); - - return withMiniMap; +function extractTimings(span: { + name: string; + duration?: number; + children: any[]; +}): Record { + const timings: Record = {}; + + if (span.duration !== undefined) { + timings[span.name] = span.duration; + } + + for (const child of span.children) { + Object.assign(timings, extractTimings(child)); + } + + return timings; } /** - * Compute primary path using AStarWaterHierarchical with debug info - * Uses the same transformer chain as PathFinding.Water() + * Compute primary path using PathFinding.Water with debug info */ function computePrimaryPath( - hpaStar: AStarWaterHierarchical, game: any, - graph: any, fromRef: TileRef, toRef: TileRef, ): PrimaryResult { const miniMap = game.miniMap(); - // Build wrapped pathfinder with all transformers - const wrappedPf = buildWrappedPathFinder(hpaStar, game, graph); + // Use standard PathFinding.Water + const pf = PathFinding.Water(game); - // Enable debug mode to capture internal state - hpaStar.debugMode = true; + // Enable DebugSpan to capture internal state + DebugSpan.enable(); - const start = performance.now(); - const path = wrappedPf.findPath(fromRef, toRef); - const time = performance.now() - start; + const path = pf.findPath(fromRef, toRef); - const debugInfo = hpaStar.debugInfo; + // Get span data and disable + const span = DebugSpan.getLastSpan(); + DebugSpan.disable(); // Convert node path (miniMap coords) to full map coords let nodePath: Array<[number, number]> | null = null; - if (debugInfo?.nodePath) { - nodePath = debugInfo.nodePath.map((tile: TileRef) => { + const spanNodePath = span?.data?.nodePath as TileRef[] | undefined; + if (spanNodePath) { + nodePath = spanNodePath.map((tile: TileRef) => { const x = miniMap.x(tile) * 2; const y = miniMap.y(tile) * 2; return [x, y] as [number, number]; @@ -138,22 +124,32 @@ function computePrimaryPath( // Convert initialPath (miniMap TileRefs) to full map coords let initialPath: Array<[number, number]> | null = null; - if (debugInfo?.initialPath) { - initialPath = debugInfo.initialPath.map((tile: TileRef) => { + const spanInitialPath = span?.data?.initialPath as TileRef[] | undefined; + if (spanInitialPath) { + initialPath = spanInitialPath.map((tile: TileRef) => { const x = miniMap.x(tile) * 2; const y = miniMap.y(tile) * 2; return [x, y] as [number, number]; }); } + let cachedSegmentsUsed: number | null = null; + if (span?.data?.cachedSegmentsUsed !== undefined) { + cachedSegmentsUsed = span.data.cachedSegmentsUsed as number; + } + + // Extract timings from span hierarchy + const timings = span ? extractTimings(span) : {}; + return { path: pathToCoords(path, game), length: path ? path.length : 0, - time, + time: timings["hpa:findPath"] || 0, debug: { nodePath, initialPath, - timings: debugInfo?.timings ?? {}, + cachedSegmentsUsed, + timings, }, }; } @@ -189,8 +185,7 @@ export async function computePath( to: [number, number], options: { adapters?: string[] } = {}, ): Promise { - const { game, hpaStar } = await loadMap(mapName); - const graph = game.miniWaterGraph(); + const { game } = await loadMap(mapName); // Convert coordinates to TileRefs const fromRef = game.ref(from[0], from[1]); @@ -204,8 +199,8 @@ export async function computePath( throw new Error(`End point (${to[0]}, ${to[1]}) is not water`); } - // Compute primary path (HPA* with debug) - const primary = computePrimaryPath(hpaStar, game, graph, fromRef, toRef); + // Compute primary path (PathFinding.Water with debug) + const primary = computePrimaryPath(game, fromRef, toRef); // Compute comparison paths const selectedAdapters = options.adapters ?? COMPARISON_ADAPTERS; diff --git a/tests/pathfinding/playground/public/client.js b/tests/pathfinding/playground/public/client.js index 8c9d68d8e..0016ccdb7 100644 --- a/tests/pathfinding/playground/public/client.js +++ b/tests/pathfinding/playground/public/client.js @@ -20,6 +20,7 @@ const state = { // Colors for comparison paths const COMPARISON_COLORS = { + "hpa.cached": "#00ffff", // cyan hpa: "#ff8800", // orange "a.baseline": "#ff00ff", // magenta "a.generic": "#88ff00", // lime @@ -814,20 +815,6 @@ function updatePathInfo(result) { function updateTimingsPanel(result) { const primary = result.primary; const timings = primary && primary.debug ? primary.debug.timings : {}; - - // Use timings.total (excludes debug overhead) instead of raw time - const hpaTime = timings.total || 0; - - // Show HPA* time and path length (or 0.00 in light gray if no data) - const hpaTimeEl = document.getElementById("hpaTime"); - if (hpaTime > 0) { - hpaTimeEl.textContent = `${hpaTime.toFixed(2)}ms`; - hpaTimeEl.classList.remove("faded"); - } else { - hpaTimeEl.textContent = "0.00ms"; - hpaTimeEl.classList.add("faded"); - } - const hpaTilesEl = document.getElementById("hpaTiles"); if (primary && primary.length > 0) { hpaTilesEl.textContent = `- ${primary.length} tiles`; @@ -840,8 +827,9 @@ function updateTimingsPanel(result) { const earlyExitEl = document.getElementById("timingEarlyExit"); const earlyExitValueEl = document.getElementById("timingEarlyExitValue"); earlyExitEl.style.display = "flex"; - if (timings.earlyExitLocalPath !== undefined) { - earlyExitValueEl.textContent = `${timings.earlyExitLocalPath.toFixed(2)}ms`; + const earlyExitTime = timings["earlyExit"]; + if (earlyExitTime !== undefined) { + earlyExitValueEl.textContent = `${earlyExitTime.toFixed(2)}ms`; earlyExitValueEl.style.color = "#f5f5f5"; } else { earlyExitValueEl.textContent = "—"; @@ -852,8 +840,9 @@ function updateTimingsPanel(result) { const findNodesEl = document.getElementById("timingFindNodes"); const findNodesValueEl = document.getElementById("timingFindNodesValue"); findNodesEl.style.display = "flex"; - if (timings.findNodes !== undefined) { - findNodesValueEl.textContent = `${timings.findNodes.toFixed(2)}ms`; + const nodeLookupTime = timings["nodeLookup"]; + if (nodeLookupTime !== undefined) { + findNodesValueEl.textContent = `${nodeLookupTime.toFixed(2)}ms`; findNodesValueEl.style.color = "#f5f5f5"; } else { findNodesValueEl.textContent = "—"; @@ -866,8 +855,9 @@ function updateTimingsPanel(result) { "timingAbstractPathValue", ); abstractPathEl.style.display = "flex"; - if (timings.findAbstractPath !== undefined) { - abstractPathValueEl.textContent = `${timings.findAbstractPath.toFixed(2)}ms`; + const abstractPathTime = timings["abstractPath"]; + if (abstractPathTime !== undefined) { + abstractPathValueEl.textContent = `${abstractPathTime.toFixed(2)}ms`; abstractPathValueEl.style.color = "#f5f5f5"; } else { abstractPathValueEl.textContent = "—"; @@ -878,14 +868,28 @@ function updateTimingsPanel(result) { const initialPathEl = document.getElementById("timingInitialPath"); const initialPathValueEl = document.getElementById("timingInitialPathValue"); initialPathEl.style.display = "flex"; - if (timings.buildInitialPath !== undefined) { - initialPathValueEl.textContent = `${timings.buildInitialPath.toFixed(2)}ms`; + const initialPathTime = timings["initialPath"]; + if (initialPathTime !== undefined) { + initialPathValueEl.textContent = `${initialPathTime.toFixed(2)}ms`; initialPathValueEl.style.color = "#f5f5f5"; } else { initialPathValueEl.textContent = "—"; initialPathValueEl.style.color = "#666"; } + // Smooth Path + const smoothPathEl = document.getElementById("timingSmoothPath"); + const smoothPathValueEl = document.getElementById("timingSmoothPathValue"); + smoothPathEl.style.display = "flex"; + const smoothPathTime = timings["smoothingTransformer"]; + if (smoothPathTime !== undefined) { + smoothPathValueEl.textContent = `${smoothPathTime.toFixed(2)}ms`; + smoothPathValueEl.style.color = "#f5f5f5"; + } else { + smoothPathValueEl.textContent = "—"; + smoothPathValueEl.style.color = "#666"; + } + // Show comparisons section const comparisonsSection = document.getElementById("comparisonsSection"); const comparisonsContainer = document.getElementById("comparisonsContainer"); @@ -905,6 +909,23 @@ function updateTimingsPanel(result) { } } + // Use total span time from DebugSpan + let hpaTime = timings["findPath"] || 0; + + if (compMap["hpa.cached"]) { + hpaTime = compMap["hpa.cached"].time; + } + + // Show HPA* time and path length (or 0.00 in light gray if no data) + const hpaTimeEl = document.getElementById("hpaTime"); + if (hpaTime > 0) { + hpaTimeEl.textContent = `${hpaTime.toFixed(2)}ms`; + hpaTimeEl.classList.remove("faded"); + } else { + hpaTimeEl.textContent = "0.00ms"; + hpaTimeEl.classList.add("faded"); + } + // Find fastest time overall (including HPA*) when we have data const compTimes = result.comparisons ? result.comparisons.map((c) => c.time).filter((t) => t > 0) diff --git a/tests/pathfinding/playground/public/index.html b/tests/pathfinding/playground/public/index.html index 6dbe07701..f03d041d3 100644 --- a/tests/pathfinding/playground/public/index.html +++ b/tests/pathfinding/playground/public/index.html @@ -196,6 +196,10 @@

Pathfinding Playground

Initial Path:
+
diff --git a/tests/pathfinding/playground/public/styles.css b/tests/pathfinding/playground/public/styles.css index 8587fc022..0ecf5fecf 100644 --- a/tests/pathfinding/playground/public/styles.css +++ b/tests/pathfinding/playground/public/styles.css @@ -522,6 +522,10 @@ canvas { background: rgba(255, 255, 255, 0.15); } +.comparison-row.active .comp-name { + color: #fff; +} + .comparison-row:last-child { border-bottom: none; } diff --git a/tests/pathfinding/playground/server.ts b/tests/pathfinding/playground/server.ts index 9beed0456..3bedee84f 100644 --- a/tests/pathfinding/playground/server.ts +++ b/tests/pathfinding/playground/server.ts @@ -6,20 +6,9 @@ import { clearCache as clearMapCache, getMapMetadata, listMaps, - setConfig, } from "./api/maps.js"; import { clearAdapterCaches, computePath } from "./api/pathfinding.js"; -// Parse command-line arguments -const args = process.argv.slice(2); -const noCache = args.includes("--no-cache"); - -// Configure map loading -if (noCache) { - setConfig({ cachePaths: false }); - console.log("Path caching disabled (--no-cache)"); -} - const app = express(); const PORT = process.env.PORT ?? 5555; @@ -203,9 +192,6 @@ app.listen(PORT, () => { Server running at: http://localhost:${PORT} -Configuration: - - Path caching: ${noCache ? "disabled" : "enabled"} - Press Ctrl+C to stop `); }); diff --git a/tests/pathfinding/utils.ts b/tests/pathfinding/utils.ts index e2d39b3e5..08c96ca63 100644 --- a/tests/pathfinding/utils.ts +++ b/tests/pathfinding/utils.ts @@ -9,7 +9,7 @@ import { GameType, PlayerInfo, } from "../../src/core/game/Game"; -import { createGame } from "../../src/core/game/GameImpl"; +import { createGame, GameImpl } from "../../src/core/game/GameImpl"; import { TileRef } from "../../src/core/game/GameMap"; import { genTerrainFromBin } from "../../src/core/game/TerrainMapLoader"; import { UserSettings } from "../../src/core/game/UserSettings"; @@ -86,16 +86,24 @@ export function getAdapter( // Recreate AStarWaterHierarchical without cache, this approach was chosen // over adding cache toggles to the existing game instance // to avoid adding side effect from benchmark to the game - const graph = game.miniWaterGraph(); - if (!graph) { - throw new Error("miniWaterGraph not available"); - } - const hpa = new AStarWaterHierarchical(game.miniMap(), graph, { - cachePaths: false, - }); - (game as any)._miniWaterHPA = hpa; - return PathFinding.Water(game); + const originalGame = game as any; + const clonedGame = new GameImpl( + originalGame._humans, + originalGame._nations, + originalGame._map, + originalGame.miniGameMap, + originalGame._config, + originalGame._stats, + ); + + (clonedGame as any)._miniWaterHPA = new AStarWaterHierarchical( + clonedGame.miniMap(), + (clonedGame as any)._miniWaterGraph!, + { cachePaths: false }, + ); + + return PathFinding.Water(clonedGame); } case "hpa.cached": return PathFinding.Water(game); diff --git a/tests/util/Setup.ts b/tests/util/Setup.ts index 6d8699cea..5e038bdc2 100644 --- a/tests/util/Setup.ts +++ b/tests/util/Setup.ts @@ -30,28 +30,40 @@ export async function setup( const binMapDir = path.join(__dirname, "..", "testdata", "maps", mapName); const mapBinPath = path.join(binMapDir, "map.bin"); const miniMapBinPath = path.join(binMapDir, "map4x.bin"); + const manifestPath = path.join(binMapDir, "manifest.json"); let gameMap, miniGameMap; if (fsSync.existsSync(mapBinPath) && fsSync.existsSync(miniMapBinPath)) { - // Binary map format + // Binary map format — test data files lack the 4-byte width/height header + // that genTerrainFromBin expects, so prepend it from the manifest. + const manifest = JSON.parse(fsSync.readFileSync(manifestPath, "utf-8")); + const mapBinBuffer = fsSync.readFileSync(mapBinPath); const miniMapBinBuffer = fsSync.readFileSync(miniMapBinPath); - const mapBinString = String.fromCharCode(...new Uint8Array(mapBinBuffer)); - const miniMapBinString = String.fromCharCode( - ...new Uint8Array(miniMapBinBuffer), + + const mapWithHeader = prependDimensionHeader( + new Uint8Array(mapBinBuffer), + manifest.map.width, + manifest.map.height, + ); + const miniMapWithHeader = prependDimensionHeader( + new Uint8Array(miniMapBinBuffer), + manifest.map4x.width, + manifest.map4x.height, + ); + + gameMap = await genTerrainFromBin(uint8ArrayToBinaryString(mapWithHeader)); + miniGameMap = await genTerrainFromBin( + uint8ArrayToBinaryString(miniMapWithHeader), ); - gameMap = await genTerrainFromBin(mapBinString); - miniGameMap = await genTerrainFromBin(miniMapBinString); } else { // Legacy PNG map format const mapPath = path.join(__dirname, "..", "testdata", `${mapName}.png`); const imageBuffer = await fs.readFile(mapPath); const { map, miniMap } = await generateMap(imageBuffer, false); - gameMap = await genTerrainFromBin(String.fromCharCode.apply(null, map)); - miniGameMap = await genTerrainFromBin( - String.fromCharCode.apply(null, miniMap), - ); + gameMap = await genTerrainFromBin(uint8ArrayToBinaryString(map)); + miniGameMap = await genTerrainFromBin(uint8ArrayToBinaryString(miniMap)); } // Configure the game @@ -82,6 +94,41 @@ export async function setup( return createGame(humans, [], gameMap, miniGameMap, config); } +/** + * Prepend a 4-byte little-endian width/height header to raw terrain data, + * matching the format that genTerrainFromBin expects. + */ +function prependDimensionHeader( + rawData: Uint8Array, + width: number, + height: number, +): Uint8Array { + const header = new Uint8Array(4); + header[0] = width & 0xff; + header[1] = (width >> 8) & 0xff; + header[2] = height & 0xff; + header[3] = (height >> 8) & 0xff; + const result = new Uint8Array(4 + rawData.length); + result.set(header); + result.set(rawData, 4); + return result; +} + +/** + * Convert a Uint8Array to a binary string without exceeding the call stack. + * Using spread or .apply on large arrays blows the stack limit. + */ +function uint8ArrayToBinaryString(bytes: Uint8Array): string { + const CHUNK = 8192; + let result = ""; + for (let i = 0; i < bytes.length; i += CHUNK) { + result += String.fromCharCode( + ...bytes.subarray(i, Math.min(i + CHUNK, bytes.length)), + ); + } + return result; +} + export function playerInfo(name: string, type: PlayerType): PlayerInfo { return new PlayerInfo("fr", name, type, null, name); } From 67ff7cb121782b082037ca8d3c1c2a5b55bcdef3 Mon Sep 17 00:00:00 2001 From: 1brucben <1benjbruce@gmail.com> Date: Sat, 21 Feb 2026 04:34:53 +0100 Subject: [PATCH 24/34] Pathfinding - optimize naval invasions (#2932) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://pf-pt-4.openfront.dev/ Hello again! Pathfinding. It's fast, but inaccurate. This PR makes it more accurate and actually faster. Sadly it is _faster_ because of a blunder in previous PR (using BucketQueue where MinHeap would be better), not because of a new tech. More importantly, it is more accurate. And that's what people apparently want. Most of the functional changes relate to `SpatialQuery` module. This is the thingy that answers "we know the target, which tile of my territory is the best to launch an invasion". To make it compute a path from South America to the deep inland China river, it has to work on a coerced map, one with a very small resolution, so small in fact, that every 4096 map tiles gets compressed to just one pixel. I hope you see where this is going. Previously we selected a random coastal tile within this big pixel (honestly it wasn't random at all, but could very well be for the illustrative purposes). Now, we try to be a bit more deliberate. Since we already know the rough location of the probably best tile, we can exclude all other tiles from the computation. Imagine a player's territory spans both Americas on global map - that's a lot of shores. But since we already know the best tile is somewhere close to Miami, the problem space was greatly reduced, no need to consider all other shores. But pathing to the target in China from Miami is still crazy expensive. This is where second trick comes to play - instead of pathing all the way to China, we select a _waypoint_ in the rough direction of China, about 100 to 200 tiles away. This way we fairly cheaply select best tile to launch an invasion towards this abstract point. And chances are, this point is far enough, the newly computed path is very close to being optimal. When you throw a dart from far away, the difference between scoring 10 and missing is very small. This is why aiming in the general direction of the board - as opposed to the ceiling - is usually good enough. opposed bank of a river?! Well, pathing from America to China is cool, but most players wouldn't notice the difference on such long paths, what about the short ones? We now try more accurate pathing first and defer to hierarchy only if it fails. This produces much better paths for short invasions. While the fix described above ensures the accuracy is improved also on medium-to-long routes. Yes. https://github.com/user-attachments/assets/9cf9586f-c99a-416d-b856-8cf0a21c35ed Grab a 🥕. Remember `tests/pathfinding/playground` is mostly generated code and go easy on it. It's enough for it to work and do it's job of visualizing the paths. No need for throughout review of these files. - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced regression is found: moleole --- .../pathfinding/algorithms/AStar.Water.ts | 8 +- .../algorithms/AStar.WaterBounded.ts | 42 +- .../algorithms/AStar.WaterHierarchical.ts | 48 ++ .../pathfinding/algorithms/PriorityQueue.ts | 43 +- src/core/pathfinding/spatial/SpatialQuery.ts | 143 ++++- .../transformers/SmoothingWaterTransformer.ts | 3 + .../playground/api/spatialQuery.ts | 161 ++++++ tests/pathfinding/playground/public/client.js | 535 +++++++++++++++++- .../pathfinding/playground/public/index.html | 79 ++- .../pathfinding/playground/public/styles.css | 120 +++- tests/pathfinding/playground/server.ts | 53 ++ 11 files changed, 1171 insertions(+), 64 deletions(-) create mode 100644 tests/pathfinding/playground/api/spatialQuery.ts diff --git a/src/core/pathfinding/algorithms/AStar.Water.ts b/src/core/pathfinding/algorithms/AStar.Water.ts index 6452114a5..d6a366293 100644 --- a/src/core/pathfinding/algorithms/AStar.Water.ts +++ b/src/core/pathfinding/algorithms/AStar.Water.ts @@ -1,6 +1,6 @@ import { GameMap, TileRef } from "../../game/GameMap"; import { PathFinder } from "../types"; -import { BucketQueue, PriorityQueue } from "./PriorityQueue"; +import { MinHeap, PriorityQueue } from "./PriorityQueue"; const LAND_BIT = 7; // Bit 7 in terrain indicates land const MAGNITUDE_MASK = 0x1f; @@ -45,11 +45,7 @@ export class AStarWater implements PathFinder { this.gScore = new Uint32Array(this.numNodes); this.cameFrom = new Int32Array(this.numNodes); - // Account for scaled costs + tie-breaker headroom - const maxDim = map.width() + map.height(); - const maxF = - (this.heuristicWeight + 1) * BASE_COST * maxDim + COST_SCALE * maxDim; - this.queue = new BucketQueue(maxF); + this.queue = new MinHeap(this.numNodes); } findPath(start: number | number[], goal: number): number[] | null { diff --git a/src/core/pathfinding/algorithms/AStar.WaterBounded.ts b/src/core/pathfinding/algorithms/AStar.WaterBounded.ts index aa8bdd693..8af127ef4 100644 --- a/src/core/pathfinding/algorithms/AStar.WaterBounded.ts +++ b/src/core/pathfinding/algorithms/AStar.WaterBounded.ts @@ -1,6 +1,6 @@ import { GameMap, TileRef } from "../../game/GameMap"; import { PathFinder } from "../types"; -import { BucketQueue } from "./PriorityQueue"; +import { MinHeap } from "./PriorityQueue"; const LAND_BIT = 7; const MAGNITUDE_MASK = 0x1f; @@ -33,7 +33,7 @@ export class AStarWaterBounded implements PathFinder { private readonly gScoreStamp: Uint32Array; private readonly gScore: Uint32Array; private readonly cameFrom: Int32Array; - private readonly queue: BucketQueue; + private readonly queue: MinHeap; private readonly terrain: Uint8Array; private readonly mapWidth: number; private readonly heuristicWeight: number; @@ -54,11 +54,7 @@ export class AStarWaterBounded implements PathFinder { this.gScore = new Uint32Array(maxSearchArea); this.cameFrom = new Int32Array(maxSearchArea); - const maxDim = Math.ceil(Math.sqrt(maxSearchArea)); - // Account for scaled costs + tie-breaker headroom - const maxF = - (this.heuristicWeight + 1) * BASE_COST * maxDim * 2 + COST_SCALE * maxDim; - this.queue = new BucketQueue(maxF); + this.queue = new MinHeap(maxSearchArea * 4); } findPath(start: number | number[], goal: number): number[] | null { @@ -209,6 +205,8 @@ export class AStarWaterBounded implements PathFinder { closedStamp[neighborLocal] !== stamp && (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const ny = currentY - 1; + const distToGoal = Math.abs(currentX - goalX) + Math.abs(ny - goalY); const magnitude = neighborTerrain & MAGNITUDE_MASK; const cost = BASE_COST + getMagnitudePenalty(magnitude); const tentativeG = currentG + cost; @@ -219,11 +217,7 @@ export class AStarWaterBounded implements PathFinder { cameFrom[neighborLocal] = currentLocal; gScore[neighborLocal] = tentativeG; gScoreStamp[neighborLocal] = stamp; - const ny = currentY - 1; - const h = - weight * - BASE_COST * - (Math.abs(currentX - goalX) + Math.abs(ny - goalY)); + const h = weight * BASE_COST * distToGoal; const f = tentativeG + h + crossTieBreaker(currentX, ny); queue.push(neighborLocal, f); } @@ -238,6 +232,8 @@ export class AStarWaterBounded implements PathFinder { closedStamp[neighborLocal] !== stamp && (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const ny = currentY + 1; + const distToGoal = Math.abs(currentX - goalX) + Math.abs(ny - goalY); const magnitude = neighborTerrain & MAGNITUDE_MASK; const cost = BASE_COST + getMagnitudePenalty(magnitude); const tentativeG = currentG + cost; @@ -248,11 +244,7 @@ export class AStarWaterBounded implements PathFinder { cameFrom[neighborLocal] = currentLocal; gScore[neighborLocal] = tentativeG; gScoreStamp[neighborLocal] = stamp; - const ny = currentY + 1; - const h = - weight * - BASE_COST * - (Math.abs(currentX - goalX) + Math.abs(ny - goalY)); + const h = weight * BASE_COST * distToGoal; const f = tentativeG + h + crossTieBreaker(currentX, ny); queue.push(neighborLocal, f); } @@ -267,6 +259,8 @@ export class AStarWaterBounded implements PathFinder { closedStamp[neighborLocal] !== stamp && (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const nx = currentX - 1; + const distToGoal = Math.abs(nx - goalX) + Math.abs(currentY - goalY); const magnitude = neighborTerrain & MAGNITUDE_MASK; const cost = BASE_COST + getMagnitudePenalty(magnitude); const tentativeG = currentG + cost; @@ -277,11 +271,7 @@ export class AStarWaterBounded implements PathFinder { cameFrom[neighborLocal] = currentLocal; gScore[neighborLocal] = tentativeG; gScoreStamp[neighborLocal] = stamp; - const nx = currentX - 1; - const h = - weight * - BASE_COST * - (Math.abs(nx - goalX) + Math.abs(currentY - goalY)); + const h = weight * BASE_COST * distToGoal; const f = tentativeG + h + crossTieBreaker(nx, currentY); queue.push(neighborLocal, f); } @@ -296,6 +286,8 @@ export class AStarWaterBounded implements PathFinder { closedStamp[neighborLocal] !== stamp && (neighbor === goal || (neighborTerrain & landMask) === 0) ) { + const nx = currentX + 1; + const distToGoal = Math.abs(nx - goalX) + Math.abs(currentY - goalY); const magnitude = neighborTerrain & MAGNITUDE_MASK; const cost = BASE_COST + getMagnitudePenalty(magnitude); const tentativeG = currentG + cost; @@ -306,11 +298,7 @@ export class AStarWaterBounded implements PathFinder { cameFrom[neighborLocal] = currentLocal; gScore[neighborLocal] = tentativeG; gScoreStamp[neighborLocal] = stamp; - const nx = currentX + 1; - const h = - weight * - BASE_COST * - (Math.abs(nx - goalX) + Math.abs(currentY - goalY)); + const h = weight * BASE_COST * distToGoal; const f = tentativeG + h + crossTieBreaker(nx, currentY); queue.push(neighborLocal, f); } diff --git a/src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts b/src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts index ce8ceb2a7..78a8ff6bc 100644 --- a/src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts +++ b/src/core/pathfinding/algorithms/AStar.WaterHierarchical.ts @@ -12,6 +12,7 @@ export class AStarWaterHierarchical implements PathFinder { private abstractAStar: AbstractGraphAStar; private localAStar: AStarWaterBounded; private localAStarMultiCluster: AStarWaterBounded; + private localAStarShortPath: AStarWaterBounded; private sourceResolver: SourceResolver; constructor( @@ -41,6 +42,11 @@ export class AStarWaterHierarchical implements PathFinder { maxMultiClusterNodes, ); + // BoundedAStar for short path multi-source (120 + 2*10 padding = 140) + const shortPathSize = 140; + const maxShortPathNodes = shortPathSize * shortPathSize; + this.localAStarShortPath = new AStarWaterBounded(map, maxShortPathNodes); + // SourceResolver for multi-source search this.sourceResolver = new SourceResolver(this.map, this.graph); } @@ -62,6 +68,10 @@ export class AStarWaterHierarchical implements PathFinder { sources: TileRef[], target: TileRef, ): TileRef[] | null { + // Early exit: try bounded A* for sources close to target + const shortPath = this.tryShortPathMultiSource(sources, target); + if (shortPath) return shortPath; + // 1. Resolve target to abstract node const targetNode = this.sourceResolver.resolveTarget(target); if (!targetNode) return null; @@ -82,6 +92,44 @@ export class AStarWaterHierarchical implements PathFinder { return this.findPathSingle(winningSource, target); } + private tryShortPathMultiSource( + sources: TileRef[], + target: TileRef, + ): TileRef[] | null { + const SHORT_PATH_THRESHOLD = 120; + const PADDING = 10; + + const candidates = sources.filter( + (s) => this.map.manhattanDist(s, target) <= SHORT_PATH_THRESHOLD, + ); + if (candidates.length === 0) return null; + + const toX = this.map.x(target); + const toY = this.map.y(target); + let minX = toX, + maxX = toX, + minY = toY, + maxY = toY; + + for (const s of candidates) { + const sx = this.map.x(s); + const sy = this.map.y(s); + minX = Math.min(minX, sx); + maxX = Math.max(maxX, sx); + minY = Math.min(minY, sy); + maxY = Math.max(maxY, sy); + } + + const bounds = { + minX: Math.max(0, minX - PADDING), + maxX: Math.min(this.map.width() - 1, maxX + PADDING), + minY: Math.max(0, minY - PADDING), + maxY: Math.min(this.map.height() - 1, maxY + PADDING), + }; + + return this.localAStarShortPath.searchBounded(candidates, target, bounds); + } + findPathSingle(from: TileRef, to: TileRef): TileRef[] | null { const dist = this.map.manhattanDist(from, to); diff --git a/src/core/pathfinding/algorithms/PriorityQueue.ts b/src/core/pathfinding/algorithms/PriorityQueue.ts index c8f525f0b..df7f52919 100644 --- a/src/core/pathfinding/algorithms/PriorityQueue.ts +++ b/src/core/pathfinding/algorithms/PriorityQueue.ts @@ -18,7 +18,20 @@ export class MinHeap implements PriorityQueue { push(node: number, priority: number): void { if (this.size >= this.capacity) { - throw new Error(`MinHeap capacity exceeded: ${this.capacity}`); + console.error( + `MinHeap capacity exceeded (${this.capacity}). ` + + "Resizing, but this indicates a bug. Please investigate.", + ); + + this.capacity *= 2; + + const newHeap = new Int32Array(this.capacity); + const newPri = new Float32Array(this.capacity); + newHeap.set(this.heap); + newPri.set(this.priorities); + + this.heap = newHeap; + this.priorities = newPri; } let i = this.size++; @@ -94,6 +107,8 @@ export class MinHeap implements PriorityQueue { export class BucketQueue implements PriorityQueue { private buckets: Int32Array[]; private bucketSizes: Int32Array; + private bucketStamp: Uint32Array; + private stamp = 0; private minBucket: number; private maxBucket: number; private size: number; @@ -102,6 +117,7 @@ export class BucketQueue implements PriorityQueue { this.maxBucket = maxPriority + 1; this.buckets = new Array(this.maxBucket); this.bucketSizes = new Int32Array(this.maxBucket); + this.bucketStamp = new Uint32Array(this.maxBucket); this.minBucket = this.maxBucket; this.size = 0; } @@ -113,7 +129,9 @@ export class BucketQueue implements PriorityQueue { this.buckets[bucket] = new Int32Array(64); } - const size = this.bucketSizes[bucket]; + const size = + this.bucketStamp[bucket] === this.stamp ? this.bucketSizes[bucket] : 0; + if (size >= this.buckets[bucket].length) { const newBucket = new Int32Array(this.buckets[bucket].length * 2); newBucket.set(this.buckets[bucket]); @@ -121,7 +139,8 @@ export class BucketQueue implements PriorityQueue { } this.buckets[bucket][size] = node; - this.bucketSizes[bucket]++; + this.bucketSizes[bucket] = size + 1; + this.bucketStamp[bucket] = this.stamp; this.size++; if (bucket < this.minBucket) { @@ -131,11 +150,13 @@ export class BucketQueue implements PriorityQueue { pop(): number { while (this.minBucket < this.maxBucket) { - const size = this.bucketSizes[this.minBucket]; - if (size > 0) { - this.bucketSizes[this.minBucket]--; - this.size--; - return this.buckets[this.minBucket][size - 1]; + if (this.bucketStamp[this.minBucket] === this.stamp) { + const size = this.bucketSizes[this.minBucket]; + if (size > 0) { + this.bucketSizes[this.minBucket]--; + this.size--; + return this.buckets[this.minBucket][size - 1]; + } } this.minBucket++; } @@ -147,7 +168,11 @@ export class BucketQueue implements PriorityQueue { } clear(): void { - this.bucketSizes.fill(0); + this.stamp++; + if (this.stamp > 0xffffffff) { + this.bucketStamp.fill(0); + this.stamp = 1; + } this.minBucket = this.maxBucket; this.size = 0; } diff --git a/src/core/pathfinding/spatial/SpatialQuery.ts b/src/core/pathfinding/spatial/SpatialQuery.ts index 1336a636f..9128dd0b4 100644 --- a/src/core/pathfinding/spatial/SpatialQuery.ts +++ b/src/core/pathfinding/spatial/SpatialQuery.ts @@ -1,12 +1,27 @@ import { Game, Player, TerraNullius } from "../../game/Game"; import { TileRef } from "../../game/GameMap"; +import { DebugSpan } from "../../utilities/DebugSpan"; import { PathFinding } from "../PathFinder"; +import { AStarWaterBounded } from "../algorithms/AStar.WaterBounded"; type Owner = Player | TerraNullius; +const REFINE_MAX_SEARCH_AREA = 100 * 100; + export class SpatialQuery { + private boundedAStar: AStarWaterBounded | null = null; + constructor(private game: Game) {} + private getBoundedAStar(): AStarWaterBounded { + this.boundedAStar ??= new AStarWaterBounded( + this.game.map(), + REFINE_MAX_SEARCH_AREA, + ); + + return this.boundedAStar; + } + /** * Find nearest tile matching predicate using BFS traversal. * Uses Manhattan distance filter, ignores terrain barriers. @@ -64,27 +79,125 @@ export class SpatialQuery { * Returns null for terra nullius (no borderTiles). */ closestShoreByWater(owner: Owner, target: TileRef): TileRef | null { - if (!owner.isPlayer()) return null; + return DebugSpan.wrap("SpatialQuery.closestShoreByWater", () => { + if (!owner.isPlayer()) return null; - const gm = this.game; - const player = owner as Player; + const gm = this.game; + const player = owner as Player; - // Target must be water or shore (land adjacent to water) - if (!gm.isWater(target) && !gm.isShore(target)) return null; + // Target must be water or shore (land adjacent to water) + if (!gm.isWater(target) && !gm.isShore(target)) return null; - const targetComponent = gm.getWaterComponent(target); - if (targetComponent === null) return null; + const targetComponent = gm.getWaterComponent(target); + if (targetComponent === null) return null; - const isValidTile = (t: TileRef) => { - if (!gm.isShore(t) || !gm.isLand(t)) return false; - const tComponent = gm.getWaterComponent(t); - return tComponent === targetComponent; + const isValidTile = (t: TileRef) => { + if (!gm.isShore(t) || !gm.isLand(t)) return false; + const tComponent = gm.getWaterComponent(t); + return tComponent === targetComponent; + }; + + const shores = Array.from(player.borderTiles()).filter(isValidTile); + if (shores.length === 0) return null; + + const path = PathFinding.Water(gm).findPath(shores, target); + if (!path || path.length === 0) return null; + + return DebugSpan.wrap("SpatialQuery.refineStartTile", () => + this.refineStartTile(path, shores, gm), + ); + }); + } + + private refineStartTile( + path: TileRef[], + shores: TileRef[], + gm: Game, + ): TileRef { + const CANDIDATE_RADIUS = 20; + const MIN_WAYPOINT_DIST = 50; + const MAX_WAYPOINT_DIST = 200; + const PADDING = 10; + + if (path.length <= MIN_WAYPOINT_DIST) { + return path[0]; + } + + const bestTile = path[0]; + const map = gm.map(); + + const candidates = shores.filter( + (s) => map.manhattanDist(s, bestTile) <= CANDIDATE_RADIUS, + ); + + if (candidates.length <= 1) return bestTile; + + // Precompute candidate bounds + let candMinX = map.x(candidates[0]); + let candMaxX = candMinX; + let candMinY = map.y(candidates[0]); + let candMaxY = candMinY; + + for (let i = 1; i < candidates.length; i++) { + const sx = map.x(candidates[i]); + const sy = map.y(candidates[i]); + candMinX = Math.min(candMinX, sx); + candMaxX = Math.max(candMaxX, sx); + candMinY = Math.min(candMinY, sy); + candMaxY = Math.max(candMaxY, sy); + } + + // Binary search for furthest waypoint that keeps bounds within limit + let lo = MIN_WAYPOINT_DIST; + let hi = Math.min(MAX_WAYPOINT_DIST, path.length - 1); + let bestWaypointIdx = lo; + + for (let i = 0; i < 5 && lo <= hi; i++) { + const mid = (lo + hi) >> 1; + const wp = path[mid]; + const wpX = map.x(wp); + const wpY = map.y(wp); + + const minX = Math.min(candMinX, wpX) - PADDING; + const maxX = Math.max(candMaxX, wpX) + PADDING; + const minY = Math.min(candMinY, wpY) - PADDING; + const maxY = Math.max(candMaxY, wpY) + PADDING; + + const area = (maxX - minX + 1) * (maxY - minY + 1); + if (area <= REFINE_MAX_SEARCH_AREA) { + bestWaypointIdx = mid; + lo = mid + 1; + } else { + hi = mid - 1; + } + } + + const waypoint = path[bestWaypointIdx]; + const wpX = map.x(waypoint); + const wpY = map.y(waypoint); + + const bounds = { + minX: Math.max(0, Math.min(candMinX, wpX) - PADDING), + maxX: Math.min(map.width() - 1, Math.max(candMaxX, wpX) + PADDING), + minY: Math.max(0, Math.min(candMinY, wpY) - PADDING), + maxY: Math.min(map.height() - 1, Math.max(candMaxY, wpY) + PADDING), }; - const shores = Array.from(player.borderTiles()).filter(isValidTile); - if (shores.length === 0) return null; + const boundsArea = + (bounds.maxX - bounds.minX + 1) * (bounds.maxY - bounds.minY + 1); + if (boundsArea > REFINE_MAX_SEARCH_AREA) return bestTile; + + const refinedPath = this.getBoundedAStar().searchBounded( + candidates, + waypoint, + bounds, + ); + + DebugSpan.set("$candidates", () => candidates); + DebugSpan.set("$refinedPath", () => refinedPath); + DebugSpan.set("$originalBestTile", () => bestTile); + DebugSpan.set("$newBestTile", () => refinedPath?.[0] ?? bestTile); - const path = PathFinding.Water(gm).findPath(shores, target); - return path?.[0] ?? null; + return refinedPath?.[0] ?? bestTile; } } diff --git a/src/core/pathfinding/transformers/SmoothingWaterTransformer.ts b/src/core/pathfinding/transformers/SmoothingWaterTransformer.ts index 63b30c97f..5b4bd0b0c 100644 --- a/src/core/pathfinding/transformers/SmoothingWaterTransformer.ts +++ b/src/core/pathfinding/transformers/SmoothingWaterTransformer.ts @@ -54,6 +54,9 @@ export class SmoothingWaterTransformer implements PathFinder { this.refineEndpoints(smoothed), ); + // Pass 3: LOS smoothing again (refinement may create new shortcut opportunities) + smoothed = DebugSpan.wrap("smoother:los2", () => this.losSmooth(smoothed)); + return smoothed; } diff --git a/tests/pathfinding/playground/api/spatialQuery.ts b/tests/pathfinding/playground/api/spatialQuery.ts new file mode 100644 index 000000000..df209fd77 --- /dev/null +++ b/tests/pathfinding/playground/api/spatialQuery.ts @@ -0,0 +1,161 @@ +import { TileRef } from "../../../../src/core/game/GameMap.js"; +import { PathFinding } from "../../../../src/core/pathfinding/PathFinder.js"; +import { SpatialQuery } from "../../../../src/core/pathfinding/spatial/SpatialQuery.js"; +import { DebugSpan } from "../../../../src/core/utilities/DebugSpan.js"; +import { loadMap } from "./maps.js"; + +export interface SpatialQueryResult { + selectedShore: [number, number] | null; + path: Array<[number, number]> | null; + shores: Array<[number, number]>; + debug: { + candidates: Array<[number, number]> | null; + refinedPath: Array<[number, number]> | null; + originalBestTile: [number, number] | null; + newBestTile: [number, number] | null; + timings: Record; + }; +} + +/** + * Extract timings from DebugSpan hierarchy + */ +function extractTimings(span: { + name: string; + duration?: number; + children: any[]; +}): Record { + const timings: Record = {}; + + if (span.duration !== undefined) { + timings[span.name] = span.duration; + } + + for (const child of span.children) { + Object.assign(timings, extractTimings(child)); + } + + return timings; +} + +/** + * Convert TileRef to coordinate tuple + */ +function tileToCoord(tile: TileRef, game: any): [number, number] { + return [game.x(tile), game.y(tile)]; +} + +/** + * Convert TileRef array to coordinate array + */ +function tilesToCoords( + tiles: TileRef[] | null | undefined, + game: any, +): Array<[number, number]> | null { + if (!tiles) return null; + return tiles.map((tile) => tileToCoord(tile, game)); +} + +/** + * Compute spatial query for transport ship launch + */ +export async function computeSpatialQuery( + mapName: string, + ownedTiles: number[], + target: [number, number], +): Promise { + const { game } = await loadMap(mapName); + + const targetRef = game.ref(target[0], target[1]) as TileRef; + + // Validate target is water or shore + if (!game.isWater(targetRef) && !game.isShore(targetRef)) { + throw new Error( + `Target (${target[0]}, ${target[1]}) must be water or shore`, + ); + } + + // Convert owned tile indices to TileRefs + const ownedRefs = ownedTiles.map((idx) => { + const x = idx % game.width(); + const y = Math.floor(idx / game.width()); + return game.ref(x, y) as TileRef; + }); + + // Create mock player that returns owned tiles as border tiles + // The SpatialQuery will filter to actual shore tiles + const mockPlayer = { + isPlayer: () => true, + smallID: () => 999, // Arbitrary ID for visualization + borderTiles: function* () { + for (const tile of ownedRefs) { + yield tile; + } + }, + }; + + // Get target water component for filtering + const targetComponent = game.getWaterComponent(targetRef); + + // Pre-compute all valid shore tiles for visualization + const allShores: TileRef[] = []; + for (const tile of ownedRefs) { + if (game.isShore(tile) && game.isLand(tile)) { + const tComponent = game.getWaterComponent(tile); + if (tComponent === targetComponent) { + allShores.push(tile); + } + } + } + + // Enable DebugSpan to capture internal state + DebugSpan.enable(); + + // Run spatial query + const spatialQuery = new SpatialQuery(game); + const selectedShore = spatialQuery.closestShoreByWater( + mockPlayer as any, + targetRef, + ); + + // Get span data + const span = DebugSpan.getLastSpan(); + DebugSpan.disable(); + + // Extract debug info from span + let candidates: TileRef[] | null = null; + let refinedPath: TileRef[] | null = null; + let originalBestTile: TileRef | null = null; + let newBestTile: TileRef | null = null; + + if (span?.data) { + candidates = (span.data.$candidates as TileRef[] | undefined) ?? null; + refinedPath = (span.data.$refinedPath as TileRef[] | undefined) ?? null; + originalBestTile = + (span.data.$originalBestTile as TileRef | undefined) ?? null; + newBestTile = (span.data.$newBestTile as TileRef | undefined) ?? null; + } + + // Compute full path if we have a selected shore + let path: TileRef[] | null = null; + if (selectedShore) { + path = PathFinding.Water(game).findPath(selectedShore, targetRef); + } + + const timings = span ? extractTimings(span) : {}; + + return { + selectedShore: selectedShore ? tileToCoord(selectedShore, game) : null, + path: tilesToCoords(path, game), + shores: allShores.map((t) => tileToCoord(t, game)), + debug: { + candidates: tilesToCoords(candidates, game), + refinedPath: tilesToCoords(refinedPath, game), + originalBestTile: originalBestTile + ? tileToCoord(originalBestTile, game) + : null, + newBestTile: newBestTile ? tileToCoord(newBestTile, game) : null, + timings, + }, + }; +} diff --git a/tests/pathfinding/playground/public/client.js b/tests/pathfinding/playground/public/client.js index 0016ccdb7..c40a5ef9f 100644 --- a/tests/pathfinding/playground/public/client.js +++ b/tests/pathfinding/playground/public/client.js @@ -16,6 +16,11 @@ const state = { isMapLoading: false, // Loading state for map switching isHpaLoading: false, // Separate loading state for HPA* activeRefreshButton: null, // Track which refresh button is spinning + // Transport Ship mode + mode: "pathfinding", // "pathfinding" | "transport" + paintedTiles: new Set(), // Set of tile indices (y * width + x) + brushSize: 5, + transportResult: null, // Result from spatial query }; // Colors for comparison paths @@ -36,6 +41,8 @@ let dragStartX = 0; let dragStartY = 0; let dragStartPanX = 0; let dragStartPanY = 0; +let isPainting = false; +let isErasing = false; let mapCanvas, overlayCanvas, interactiveCanvas; let mapCtx, overlayCtx, interactiveCtx; @@ -203,6 +210,109 @@ function initializeControls() { document.getElementById("clearPoints").addEventListener("click", () => { clearPoints(); }); + + // Mode switch buttons + document.querySelectorAll(".mode-button").forEach((btn) => { + btn.addEventListener("click", () => { + const newMode = btn.dataset.mode; + if (newMode !== state.mode) { + setMode(newMode); + } + }); + }); + + // Transport controls + const brushSizeInput = document.getElementById("brushSize"); + const brushSizeValue = document.getElementById("brushSizeValue"); + brushSizeInput.addEventListener("input", (e) => { + state.brushSize = parseInt(e.target.value); + brushSizeValue.textContent = state.brushSize; + }); + + document.getElementById("clearTerritory").addEventListener("click", () => { + state.paintedTiles.clear(); + state.transportResult = null; + updateTransportInfo(); + renderInteractive(); + }); +} + +// Set application mode +function setMode(newMode) { + state.mode = newMode; + + // Update UI + document.querySelectorAll(".mode-button").forEach((btn) => { + btn.classList.toggle("active", btn.dataset.mode === newMode); + }); + + const transportControls = document.getElementById("transportControls"); + const timingsPanel = document.getElementById("timingsPanel"); + const debugPanel = document.querySelector(".debug-panel"); + + if (newMode === "transport") { + transportControls.style.display = "block"; + timingsPanel.style.top = "280px"; + debugPanel.style.display = "none"; + setStatus("Paint territory, then click water target"); + } else { + transportControls.style.display = "none"; + timingsPanel.style.top = "280px"; + debugPanel.style.display = "flex"; + if (state.startPoint && state.endPoint) { + setStatus("Path computed successfully"); + } else if (state.startPoint) { + setStatus("Click on map to set end point"); + } else { + setStatus("Click on map to set start point"); + } + } + + renderInteractive(); +} + +// Update transport info display +function updateTransportInfo() { + const paintedCount = document.getElementById("paintedCount"); + const shoreCount = document.getElementById("shoreCount"); + + paintedCount.textContent = state.paintedTiles.size; + + // Count shore tiles + let shores = 0; + if (state.mapData) { + for (const idx of state.paintedTiles) { + if (isLandShore(idx)) { + shores++; + } + } + } + shoreCount.textContent = shores; +} + +// Check if tile is a land shore (land adjacent to water) +function isLandShore(tileIdx) { + const x = tileIdx % state.mapWidth; + const y = Math.floor(tileIdx / state.mapWidth); + + // Must be land + if (state.mapData[tileIdx] !== 0) return false; + + // Check 4 neighbors for water + const neighbors = [ + [x - 1, y], + [x + 1, y], + [x, y - 1], + [x, y + 1], + ]; + + for (const [nx, ny] of neighbors) { + if (nx < 0 || nx >= state.mapWidth || ny < 0 || ny >= state.mapHeight) + continue; + const nIdx = ny * state.mapWidth + nx; + if (state.mapData[nIdx] === 1) return true; + } + return false; } // Helper function to check if mouse is over a start/end point @@ -250,6 +360,20 @@ function schedulePathRecalc() { // If not enough time has passed, skip this call (throttle) } +// Throttled spatial query recalculation (max once per 50ms for heavier computation) +let lastSpatialQueryTime = 0; +function scheduleSpatialQueryRecalc() { + const now = Date.now(); + const timeSinceLastCall = now - lastSpatialQueryTime; + + if (timeSinceLastCall >= 50) { + lastSpatialQueryTime = now; + if (state.endPoint && state.paintedTiles.size > 0) { + requestSpatialQuery(state.endPoint); + } + } +} + // Initialize drag and click controls function initializeDragControls() { const wrapper = document.getElementById("canvasWrapper"); @@ -260,10 +384,46 @@ function initializeDragControls() { const canvasX = (e.clientX - rect.left - panX) / zoomLevel; const canvasY = (e.clientY - rect.top - panY) / zoomLevel; - // Check if clicking on a point + // Transport mode: check for dragging end point first, then painting + if (state.mode === "transport") { + // Check if clicking on end point to drag it + const pointAtMouse = getPointAtPosition(canvasX, canvasY); + if (pointAtMouse === "end") { + draggingPoint = "end"; + wrapper.style.cursor = "move"; + dragStartX = e.clientX; + dragStartY = e.clientY; + return; + } + + const tileX = Math.floor(canvasX); + const tileY = Math.floor(canvasY); + + if ( + tileX >= 0 && + tileX < state.mapWidth && + tileY >= 0 && + tileY < state.mapHeight + ) { + const tileIdx = tileY * state.mapWidth + tileX; + const isLand = state.mapData[tileIdx] === 0; + + if (isLand) { + // Start painting (or erasing with ctrl/right-click) + isErasing = e.ctrlKey || e.button === 2; + isPainting = true; + paintAtPosition(tileX, tileY, isErasing); + wrapper.style.cursor = isErasing ? "crosshair" : "pointer"; + return; + } + } + // Fall through to panning if not on land + } + + // Pathfinding mode: check if clicking on a point const pointAtMouse = getPointAtPosition(canvasX, canvasY); - if (pointAtMouse) { + if (pointAtMouse && state.mode === "pathfinding") { // Start dragging the point draggingPoint = pointAtMouse; wrapper.style.cursor = "move"; @@ -284,6 +444,53 @@ function initializeDragControls() { const canvasX = (e.clientX - rect.left - panX) / zoomLevel; const canvasY = (e.clientY - rect.top - panY) / zoomLevel; + // Transport mode: continue painting + if (isPainting && state.mode === "transport") { + const tileX = Math.floor(canvasX); + const tileY = Math.floor(canvasY); + paintAtPosition(tileX, tileY, isErasing); + return; + } + + // Transport mode: dragging end point + if (draggingPoint === "end" && state.mode === "transport") { + const tileX = Math.floor(canvasX); + const tileY = Math.floor(canvasY); + + if ( + tileX >= 0 && + tileX < state.mapWidth && + tileY >= 0 && + tileY < state.mapHeight + ) { + const tileIndex = tileY * state.mapWidth + tileX; + const isWater = state.mapData[tileIndex] === 1; + + if (isWater) { + draggingPointPosition = [tileX, tileY]; + state.endPoint = [tileX, tileY]; + renderInteractive(); + + // Throttled spatial query recomputation + if (state.paintedTiles.size > 0) { + scheduleSpatialQueryRecalc(); + } + } + } + return; + } + + // Transport mode: check hover over end point + if (state.mode === "transport" && !isDragging) { + const pointAtMouse = getPointAtPosition(canvasX, canvasY); + if (pointAtMouse !== hoveredPoint) { + hoveredPoint = pointAtMouse; + renderInteractive(); + wrapper.style.cursor = hoveredPoint ? "move" : "grab"; + } + return; + } + if (draggingPoint) { // Dragging a start/end point - snap to water tile const tileX = Math.floor(canvasX); @@ -395,6 +602,26 @@ function initializeDragControls() { const dx = Math.abs(e.clientX - dragStartX); const dy = Math.abs(e.clientY - dragStartY); + // Transport mode: finish painting + if (isPainting) { + isPainting = false; + isErasing = false; + wrapper.style.cursor = "grab"; + return; + } + + // Transport mode: finish dragging end point + if (draggingPoint === "end" && state.mode === "transport") { + if (state.endPoint && state.paintedTiles.size > 0) { + requestSpatialQuery(state.endPoint); + } + draggingPoint = null; + draggingPointPosition = null; + renderInteractive(); + wrapper.style.cursor = "grab"; + return; + } + if (draggingPoint) { // Finished dragging a point // Request final path update to ensure we have the path for the final position @@ -408,7 +635,11 @@ function initializeDragControls() { updateURLState(); } else if (isDragging && dx < 5 && dy < 5) { // Was panning but didn't move much - treat as click - handleMapClick(e); + if (state.mode === "transport") { + handleTransportClick(e); + } else { + handleMapClick(e); + } } isDragging = false; @@ -418,13 +649,16 @@ function initializeDragControls() { const canvasX = (e.clientX - rect.left - panX) / zoomLevel; const canvasY = (e.clientY - rect.top - panY) / zoomLevel; const pointAtMouse = getPointAtPosition(canvasX, canvasY); - wrapper.style.cursor = pointAtMouse ? "move" : "grab"; + wrapper.style.cursor = + pointAtMouse && state.mode === "pathfinding" ? "move" : "grab"; }); wrapper.addEventListener("mouseleave", () => { isDragging = false; draggingPoint = null; draggingPointPosition = null; + isPainting = false; + isErasing = false; tooltip.classList.remove("visible"); wrapper.style.cursor = "grab"; @@ -437,6 +671,13 @@ function initializeDragControls() { } }); + // Prevent context menu on right-click (for erasing) + wrapper.addEventListener("contextmenu", (e) => { + if (state.mode === "transport") { + e.preventDefault(); + } + }); + wrapper.addEventListener("wheel", (e) => { e.preventDefault(); @@ -446,7 +687,7 @@ function initializeDragControls() { const oldZoom = zoomLevel; const zoomDelta = e.deltaY > 0 ? 0.9 : 1.1; - zoomLevel = Math.max(0.1, Math.min(5, zoomLevel * zoomDelta)); + zoomLevel = Math.max(0.1, Math.min(10, zoomLevel * zoomDelta)); panX = mouseX - (mouseX - panX) * (zoomLevel / oldZoom); panY = mouseY - (mouseY - panY) * (zoomLevel / oldZoom); @@ -535,6 +776,155 @@ function clearPoints() { renderInteractive(); } +// Paint tiles in a brush area +function paintAtPosition(centerX, centerY, erase = false) { + const radius = Math.floor(state.brushSize / 2); + let changed = false; + + for (let dy = -radius; dy <= radius; dy++) { + for (let dx = -radius; dx <= radius; dx++) { + const x = centerX + dx; + const y = centerY + dy; + + if (x < 0 || x >= state.mapWidth || y < 0 || y >= state.mapHeight) + continue; + + const idx = y * state.mapWidth + x; + const isLand = state.mapData[idx] === 0; + + if (!isLand) continue; + + if (erase) { + if (state.paintedTiles.has(idx)) { + state.paintedTiles.delete(idx); + changed = true; + } + } else { + if (!state.paintedTiles.has(idx)) { + state.paintedTiles.add(idx); + changed = true; + } + } + } + } + + if (changed) { + updateTransportInfo(); + renderInteractive(); + } +} + +// Handle clicks in transport mode +function handleTransportClick(e) { + if (!state.currentMap || state.isMapLoading) return; + + const wrapper = document.getElementById("canvasWrapper"); + const rect = wrapper.getBoundingClientRect(); + + const canvasX = (e.clientX - rect.left - panX) / zoomLevel; + const canvasY = (e.clientY - rect.top - panY) / zoomLevel; + const tileX = Math.floor(canvasX); + const tileY = Math.floor(canvasY); + + if ( + tileX < 0 || + tileX >= state.mapWidth || + tileY < 0 || + tileY >= state.mapHeight + ) { + return; + } + + const idx = tileY * state.mapWidth + tileX; + const isWater = state.mapData[idx] === 1; + + if (!isWater) { + return; + } + + // Clicked on water - run spatial query + if (state.paintedTiles.size === 0) { + showError("Paint some territory first"); + return; + } + + requestSpatialQuery([tileX, tileY]); +} + +// Request spatial query computation +async function requestSpatialQuery(target) { + setStatus("Computing spatial query...", true); + + try { + // Only send shore tiles (land adjacent to water) - much smaller payload + const ownedTiles = Array.from(state.paintedTiles).filter((idx) => + isLandShore(idx), + ); + + const response = await fetch("/api/spatial-query", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + map: state.currentMap, + ownedTiles, + target, + }), + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.message || "Spatial query failed"); + } + + const result = await response.json(); + state.transportResult = result; + state.endPoint = target; + + renderInteractive(); + updateTransportTimings(result); + + if (result.selectedShore) { + setStatus( + `Shore selected: (${result.selectedShore[0]}, ${result.selectedShore[1]})`, + ); + } else { + setStatus("No valid shore found"); + } + } catch (error) { + showError(`Spatial query failed: ${error.message}`); + } +} + +// Update timings panel for transport mode +function updateTransportTimings(result) { + const hpaTimeEl = document.getElementById("hpaTime"); + const hpaTilesEl = document.getElementById("hpaTiles"); + + if (result.path) { + hpaTilesEl.textContent = `- ${result.path.length} tiles`; + } else { + hpaTilesEl.textContent = ""; + } + + const totalTime = + result.debug?.timings?.["SpatialQuery.closestShoreByWater"] ?? 0; + if (totalTime > 0) { + hpaTimeEl.textContent = `${totalTime.toFixed(2)}ms`; + hpaTimeEl.classList.remove("faded"); + } else { + hpaTimeEl.textContent = "0.00ms"; + hpaTimeEl.classList.add("faded"); + } + + // Hide pathfinding-specific timing breakdown in transport mode + document.getElementById("timingEarlyExit").style.display = "none"; + document.getElementById("timingFindNodes").style.display = "none"; + document.getElementById("timingAbstractPath").style.display = "none"; + document.getElementById("timingInitialPath").style.display = "none"; + document.getElementById("timingSmoothPath").style.display = "none"; + document.getElementById("comparisonsSection").style.display = "none"; +} + // Update transform for pan/zoom function updateTransform() { const transform = `translate(${panX}px, ${panY}px) scale(${zoomLevel})`; @@ -1164,6 +1554,135 @@ function mapToScreen(mapX, mapY) { }; } +// Render transport mode elements +function renderTransportMode() { + const tileSize = Math.max(1, zoomLevel); + + // Draw painted territory + if (state.paintedTiles.size > 0) { + interactiveCtx.fillStyle = "rgba(66, 135, 245, 0.5)"; + + for (const idx of state.paintedTiles) { + const x = idx % state.mapWidth; + const y = Math.floor(idx / state.mapWidth); + const screen = mapToScreen(x, y); + interactiveCtx.fillRect(screen.x, screen.y, tileSize, tileSize); + } + } + + // Draw all shore tiles (dark blue squares) + if (state.transportResult && state.transportResult.shores) { + interactiveCtx.fillStyle = "#2a4a6a"; + + for (const [x, y] of state.transportResult.shores) { + const screen = mapToScreen(x, y); + interactiveCtx.fillRect(screen.x, screen.y, tileSize, tileSize); + } + } + + // Draw refinement candidates (muted yellow/gold squares) + if (state.transportResult?.debug?.candidates) { + interactiveCtx.fillStyle = "rgba(200, 170, 80, 0.7)"; + + for (const [x, y] of state.transportResult.debug.candidates) { + const screen = mapToScreen(x, y); + interactiveCtx.fillRect(screen.x, screen.y, tileSize, tileSize); + } + } + + // Draw refined path (magenta) + if (state.transportResult?.debug?.refinedPath) { + interactiveCtx.strokeStyle = "#ff00ff"; + interactiveCtx.lineWidth = Math.max(1, zoomLevel * 0.8); + interactiveCtx.lineCap = "round"; + interactiveCtx.lineJoin = "round"; + interactiveCtx.beginPath(); + + for (let i = 0; i < state.transportResult.debug.refinedPath.length; i++) { + const [x, y] = state.transportResult.debug.refinedPath[i]; + const screen = mapToScreen(x + 0.5, y + 0.5); + if (i === 0) { + interactiveCtx.moveTo(screen.x, screen.y); + } else { + interactiveCtx.lineTo(screen.x, screen.y); + } + } + interactiveCtx.stroke(); + } + + // Draw full path (cyan) + if (state.transportResult && state.transportResult.path) { + interactiveCtx.strokeStyle = "#00ffff"; + interactiveCtx.lineWidth = Math.max(1, zoomLevel); + interactiveCtx.lineCap = "round"; + interactiveCtx.lineJoin = "round"; + interactiveCtx.beginPath(); + + for (let i = 0; i < state.transportResult.path.length; i++) { + const [x, y] = state.transportResult.path[i]; + const screen = mapToScreen(x + 0.5, y + 0.5); + if (i === 0) { + interactiveCtx.moveTo(screen.x, screen.y); + } else { + interactiveCtx.lineTo(screen.x, screen.y); + } + } + interactiveCtx.stroke(); + } + + // Draw original best tile (orange square) if different from new best + if (state.transportResult?.debug?.originalBestTile) { + const [ox, oy] = state.transportResult.debug.originalBestTile; + const newBest = state.transportResult.debug.newBestTile; + + // Only show if different from new best + if (!newBest || ox !== newBest[0] || oy !== newBest[1]) { + const screen = mapToScreen(ox, oy); + interactiveCtx.fillStyle = "#ff8800"; + interactiveCtx.fillRect(screen.x, screen.y, tileSize, tileSize); + } + } + + // Draw selected shore (green square) + if (state.transportResult && state.transportResult.selectedShore) { + const [sx, sy] = state.transportResult.selectedShore; + const screen = mapToScreen(sx, sy); + interactiveCtx.fillStyle = "#44ff44"; + interactiveCtx.fillRect(screen.x, screen.y, tileSize, tileSize); + } + + // Draw target point (red circle, matching pathfinding mode style) + if (state.endPoint) { + const markerSize = Math.max(4, 3 * zoomLevel); + let mapX, mapY; + if (draggingPoint === "end" && draggingPointPosition) { + mapX = draggingPointPosition[0] + 0.5; + mapY = draggingPointPosition[1] + 0.5; + } else { + mapX = state.endPoint[0] + 0.5; + mapY = state.endPoint[1] + 0.5; + } + + const screen = mapToScreen(mapX, mapY); + + // Highlight ring if hovered + if (hoveredPoint === "end") { + interactiveCtx.strokeStyle = "#ff4444"; + interactiveCtx.lineWidth = Math.max(2, zoomLevel * 0.5); + interactiveCtx.globalAlpha = 0.5; + interactiveCtx.beginPath(); + interactiveCtx.arc(screen.x, screen.y, markerSize + 3, 0, Math.PI * 2); + interactiveCtx.stroke(); + interactiveCtx.globalAlpha = 1.0; + } + + interactiveCtx.fillStyle = "#ff4444"; + interactiveCtx.beginPath(); + interactiveCtx.arc(screen.x, screen.y, markerSize, 0, Math.PI * 2); + interactiveCtx.fill(); + } +} + // Render truly interactive/dynamic overlay (paths, points, highlights) at screen coordinates function renderInteractive() { // Clear viewport-sized canvas (super fast!) @@ -1178,6 +1697,12 @@ function renderInteractive() { const markerSize = Math.max(4, 3 * zoomLevel); + // Transport mode: render painted territory and results + if (state.mode === "transport") { + renderTransportMode(); + return; + } + // Check what to show const showUsedNodes = document.getElementById("showUsedNodes").dataset.active === "true"; diff --git a/tests/pathfinding/playground/public/index.html b/tests/pathfinding/playground/public/index.html index f03d041d3..f4dcbaf79 100644 --- a/tests/pathfinding/playground/public/index.html +++ b/tests/pathfinding/playground/public/index.html @@ -118,11 +118,88 @@

Pathfinding Playground

+
+ + +
+
Select a scenario to begin
+ + +
@@ -149,7 +226,7 @@

Pathfinding Playground

- + 1.0x