From 59d9bc95f197635e48544a77f732782fb98f1701 Mon Sep 17 00:00:00 2001 From: jun Date: Thu, 27 Aug 2026 02:12:09 +0900 Subject: [PATCH 1/4] fix: stop deleting reused branches, and finish the glm-5.3-flash correction Three more findings from the dev-versus-main review. The closed-PR branch cleanup matched branches by NAME alone. Any branch whose same-name historical pull requests were all closed became a deletion candidate, without checking that the branch still pointed at one of their head commits. A `codex/`-style name reused for new work inherited the closed history of every PR that had ever carried that label, and the commits it carried had never been in a pull request at all. The planner now requires the current tip to match a closed head SHA, and keeps the branch when either SHA is unknown. The script had no test of any kind, which is how this shipped; it has eight now, including one per existing safety rule so the tip check cannot be reordered ahead of them. glm-5.3-flash was still routed through the vision sidecar on eight providers. The correction commit fixed the two Alibaba entries and left umans, cline-pass, nvidia, zai, zhipu-bigmodel-coding, both Volcengine plans and ollama-cloud behind. That list means "the proxy describes this model's images", so a native VLM sitting in it got a text description of a picture it could read itself: no error, a worse answer, an extra call. The parity assertion is now written across the whole registry rather than per provider, because the defect was entries drifting apart rather than one being wrong. It was also missing from ZAI_GLM_53_MODELS, so on Z.AI it advertised a 1M context with a null effort ladder, no default effort and no output cap while its siblings carried three tiers, a max default and 131072 tokens. The parity test pinned that gap in place because it was written from the incomplete state instead of from the family definition. And the Moonshot `$ref` normalizer overwrote numeric bounds with the sibling's instead of intersecting them. Its comment claimed the node "narrows the target", which is true only when the node happens to be narrower - a node declaring minLength 1 beside a target declaring minLength 5 emitted minLength 1, a contract weaker than either side asked for. That is the same failure the required/properties composition already fixed for set-valued keywords. Lower bounds now take the max, upper bounds the min, and a test covers both directions so the fix cannot become "always prefer the target", which would discard a real narrowing. Each fix is mutation-verified: disabling the tip comparison turns the reused-branch test red on its own, and the looser-bound test was red before the intersection landed and green after. --- .github/scripts/closed-pr-branch-cleanup.cjs | 74 +++++++- .../workflows/cleanup-closed-pr-branches.yml | 9 +- src/adapters/openai-chat.ts | 50 ++++++ src/providers/registry.ts | 58 ++++++- tests/closed-pr-branch-cleanup.test.ts | 160 ++++++++++++++++++ tests/moonshot-tool-schema.test.ts | 60 +++++++ tests/provider-registry-parity.test.ts | 38 ++++- 7 files changed, 433 insertions(+), 16 deletions(-) create mode 100644 tests/closed-pr-branch-cleanup.test.ts diff --git a/.github/scripts/closed-pr-branch-cleanup.cjs b/.github/scripts/closed-pr-branch-cleanup.cjs index aaca0f6498..57142f19fe 100644 --- a/.github/scripts/closed-pr-branch-cleanup.cjs +++ b/.github/scripts/closed-pr-branch-cleanup.cjs @@ -23,6 +23,20 @@ function normalizeBranchName(value) { return String(value || "").trim(); } +/** + * A commit id, lowercased for comparison. + * + * The REST and GraphQL APIs are not consistent about case, and a full 40-character + * sha compared case-sensitively against an abbreviated or upper-case one silently + * reads as "different" - which here would mean "keep", so the failure direction is + * safe, but it would make the guard useless rather than protective. Anything that + * is not a plausible hex object id becomes null, i.e. unknown. + */ +function normalizeOid(value) { + const text = String(value || "").trim().toLowerCase(); + return /^[0-9a-f]{7,64}$/.test(text) ? text : null; +} + function isProtectedBranch(name) { return PROTECTED_BRANCHES.includes(normalizeBranchName(name)); } @@ -45,6 +59,8 @@ const KEEP_REASONS = Object.freeze({ CROSS_REPOSITORY: "cross-repository-head", MISSING_CLOSED_AT: "missing-closed-at", WITHIN_GRACE: "within-grace-period", + MOVED_SINCE_CLOSE: "branch-moved-since-close", + UNKNOWN_HEAD_SHA: "unknown-head-sha", }); /** @@ -63,12 +79,23 @@ const KEEP_REASONS = Object.freeze({ * contributor's repository and this token has no business there. * - A grace period after `closed_at` leaves room to reopen a PR that was * closed by mistake. + * - The branch must still POINT AT a commit one of those closed pull requests + * had as its head. Matching by NAME alone deletes reused work: `codex/`-style + * names get picked up again all the time, and a branch recreated for new work + * inherits the closed history of every PR that ever used that name. The tip + * moved, so the branch is not the closed PR's branch any more - it only shares + * its label. + * - A branch whose current tip cannot be determined is kept. An unknown tip is + * not evidence of an abandoned branch, and this job's mistakes are not + * recoverable. * * @param {object} input * @param {Array} input.pullRequests Pull requests with - * `headRefName`, `baseRefName`, `state`, `merged`, `closedAt`, and - * `isCrossRepository`. - * @param {Array} input.branches Branch names that currently exist. + * `headRefName`, `headRefOid`, `baseRefName`, `state`, `merged`, `closedAt`, + * and `isCrossRepository`. + * @param {Array} input.branches Branches + * that currently exist. A bare string carries no tip, which is treated as an + * unknown tip and kept. * @param {number} [input.now] Current time in milliseconds. * @param {number} [input.graceDays] Days to wait after `closedAt`. * @returns {{ deletions: Array<{branch: string, pullRequests: number[]}>, @@ -80,7 +107,17 @@ function planClosedPrBranchDeletions({ now = Date.now(), graceDays = DEFAULT_GRACE_DAYS, }) { - const existing = new Set(branches.map(normalizeBranchName).filter(Boolean)); + // Accepts both shapes so an older caller passing bare names still works - it + // just gets the conservative answer, because a name without a tip cannot be + // proven safe to delete. + /** @type {Map} */ + const existing = new Map(); + for (const entry of branches) { + const name = normalizeBranchName(typeof entry === "string" ? entry : entry && entry.name); + if (!name) continue; + const oid = typeof entry === "string" ? null : normalizeOid(entry && entry.oid); + existing.set(name, oid); + } const graceMs = Math.max(0, Number(graceDays) || 0) * 24 * 60 * 60 * 1000; /** @type {Map} */ @@ -104,7 +141,7 @@ function planClosedPrBranchDeletions({ const deletions = []; const keeps = []; - for (const branch of [...existing].sort()) { + for (const branch of [...existing.keys()].sort()) { if (isProtectedBranch(branch)) { keeps.push({ branch, reason: KEEP_REASONS.PROTECTED }); continue; @@ -141,6 +178,33 @@ function planClosedPrBranchDeletions({ continue; } + // The tip check, last because it is the most expensive claim to satisfy and + // the cheaper rules above have already excluded most branches. + // + // A closed PR's head branch is only THIS branch if the branch still points at + // a commit that PR had as its head. Without this, a name reused for new work + // is deleted on the strength of an unrelated PR that happened to share the + // label months earlier - and a deleted branch whose commits were never pushed + // anywhere else is gone. + const currentOid = existing.get(branch) || null; + if (!currentOid) { + keeps.push({ branch, reason: KEEP_REASONS.UNKNOWN_HEAD_SHA }); + continue; + } + const closedOids = new Set( + related.map((pr) => normalizeOid(pr && pr.headRefOid)).filter(Boolean), + ); + // An empty set means the API gave us no head SHA for any of them, which is the + // unknown case again rather than a licence to delete. + if (closedOids.size === 0) { + keeps.push({ branch, reason: KEEP_REASONS.UNKNOWN_HEAD_SHA }); + continue; + } + if (!closedOids.has(currentOid)) { + keeps.push({ branch, reason: KEEP_REASONS.MOVED_SINCE_CLOSE }); + continue; + } + deletions.push({ branch, pullRequests: related diff --git a/.github/workflows/cleanup-closed-pr-branches.yml b/.github/workflows/cleanup-closed-pr-branches.yml index c260bc03a8..4b0c1229a9 100644 --- a/.github/workflows/cleanup-closed-pr-branches.yml +++ b/.github/workflows/cleanup-closed-pr-branches.yml @@ -70,6 +70,10 @@ jobs: merged: Boolean(pr.merged_at), closedAt: pr.closed_at, headRefName: pr.head && pr.head.ref, + // The tip this PR actually pointed at. Without it the planner cannot + // tell a genuinely abandoned branch from a name someone reused, and + // keeps the branch instead of deleting it. + headRefOid: pr.head && pr.head.sha, baseRefName: pr.base && pr.base.ref, // A fork head lives in the contributor's repository. Comparing // repo ids (not names) keeps a same-name fork from looking local. @@ -82,7 +86,10 @@ jobs: repo, per_page: 100, }); - const branches = rawBranches.map((branch) => branch.name); + const branches = rawBranches.map((branch) => ({ + name: branch.name, + oid: branch.commit && branch.commit.sha, + })); const protectedByGitHub = new Set( rawBranches.filter((branch) => branch.protected).map((branch) => branch.name), ); diff --git a/src/adapters/openai-chat.ts b/src/adapters/openai-chat.ts index cc8dcaad89..417f4ede4e 100644 --- a/src/adapters/openai-chat.ts +++ b/src/adapters/openai-chat.ts @@ -1041,6 +1041,48 @@ function unionRequired(target: unknown, sibling: unknown): unknown { */ const MOONSHOT_DATA_VALUED_KEYWORDS = new Set(["enum", "const", "default", "examples"]); +/** + * Numeric assertions whose intersection is a bound, and which direction tightens. + * + * `$ref` under 2020-12 is an in-place applicator: the node and its target BOTH apply, so + * the emitted schema must be their INTERSECTION. The previous code overwrote the target + * with the node and called that "the narrower reading", which holds only when the node + * happens to be narrower. A node declaring `minLength: 1` beside a target declaring + * `minLength: 5` shipped `minLength: 1` - a contract weaker than either side asked for, + * emitted silently, which is the same failure mode the `required` composition fixed for + * set-valued keywords. + * + * "max" means the surviving value is the larger of the two (lower bounds), "min" the + * smaller (upper bounds). A keyword absent from this table keeps the overwrite: for + * `type`, `format`, `description` and friends there is no ordering to intersect along, + * and the node is the more specific statement. + */ +const MOONSHOT_BOUND_KEYWORDS: Record = { + minLength: "max", + minItems: "max", + minProperties: "max", + minimum: "max", + exclusiveMinimum: "max", + maxLength: "min", + maxItems: "min", + maxProperties: "min", + maximum: "min", + exclusiveMaximum: "min", +}; + +/** + * Intersect one numeric bound. Either side being absent or non-finite yields the other, + * because an unstated bound constrains nothing - returning `undefined` there would drop + * a constraint the remaining side genuinely made. + */ +function intersectBound(target: unknown, sibling: unknown, direction: "max" | "min"): unknown { + const a = typeof target === "number" && Number.isFinite(target) ? target : null; + const b = typeof sibling === "number" && Number.isFinite(sibling) ? sibling : null; + if (a === null) return b === null ? sibling : sibling; + if (b === null) return target; + return direction === "max" ? Math.max(a, b) : Math.min(a, b); +} + /** * Compose two `properties` maps. A property named in BOTH the referenced target and the * node is the same conjunction problem `required` had: letting the sibling win discards @@ -1130,6 +1172,14 @@ function normalizeMoonshotSchemaNode( merged[key] = composeProperties(merged[key] as Record, normalized); continue; } + // Numeric bounds intersect rather than overwrite: both the node and its target + // apply, so the surviving bound is the stricter of the two in whichever direction + // that keyword tightens. + const boundDirection = MOONSHOT_BOUND_KEYWORDS[key]; + if (boundDirection && key in merged) { + merged[key] = intersectBound(merged[key], normalized, boundDirection); + continue; + } merged[key] = normalized; } return merged; diff --git a/src/providers/registry.ts b/src/providers/registry.ts index 40feec0bfd..d15814d830 100644 --- a/src/providers/registry.ts +++ b/src/providers/registry.ts @@ -340,9 +340,31 @@ const ANTHROPIC_MODEL_CONTEXT_WINDOWS: Record = { "claude-sonnet // The non-Z.AI providers below are speculative on purpose: they carry 5.2 today and are // expected to pick 5.3 up on their usual lag. Providers whose live /v1/models discovery is // enabled self-correct on the next successful fetch; static ones need a follow-up refresh. -const ZAI_GLM_53_MODELS = ["glm-5.3", "glm-5.3[1m]"]; +// Every 5.3 family member, so the effort ladder, the default effort and the output +// cap are derived in ONE place. `glm-5.3-flash` was seeded into the model list and +// the context map by hand and left out of this constant, which meant it advertised +// a 1M context with a null effort ladder, no default effort and no output cap while +// its siblings carried three tiers, a `max` default and 131072 tokens. A member +// added to the list but not to the family is a model whose metadata silently +// disappears. +const ZAI_GLM_53_MODELS = ["glm-5.3", "glm-5.3[1m]", "glm-5.3-flash"]; const ZAI_GLM_52_MODELS = ["glm-5.2", "glm-5.2[1m]"]; const ZAI_GLM_5X_MODELS = [...ZAI_GLM_53_MODELS, ...ZAI_GLM_52_MODELS]; +/** + * The 5.x rows whose images the PROXY has to describe, which is NOT the same set as + * the 5.x rows themselves. + * + * `glm-5.3-flash` is a native VLM (docs.z.ai/guides/vlm/glm-5.3-flash), so listing it + * in `noVisionModels` sent an image through the vision sidecar and handed the model a + * text description of a picture it could have read itself - no error, worse answer, + * extra call. The correction commit fixed the Alibaba entries and left the eight + * providers that reach this constant behind. + * + * Kept separate from ZAI_GLM_5X_MODELS rather than filtered at each use site: that + * constant also drives `modelSupportsReasoningSummaries` and + * `preserveReasoningContentModels`, where flash DOES belong. + */ +const ZAI_GLM_5X_SIDECAR_VISION_MODELS = ZAI_GLM_5X_MODELS.filter(id => id !== "glm-5.3-flash"); const ZAI_GLM_52_REASONING_EFFORTS = ["low", "medium", "high", "xhigh", "max"]; /** * GLM-5.3 does NOT share 5.2's five-tier ladder. docs.z.ai/devpack/latest-model folds every @@ -471,7 +493,9 @@ const OPENCODE_GO_THINKING_TOGGLE_MODELS = [ * images through the proxy's vision sidecar (src/codex/catalog/provider-fetch.ts), a claim nobody * has verified for BigModel-hosted GLM. */ -const ZHIPU_BIGMODEL_TEXT_MODELS = ["glm-4.6", "glm-4.7", "glm-4.7-flash", "glm-5", "glm-5.1", "glm-5.2", "glm-5.3", "glm-5.3-flash"]; +// `glm-5.3-flash` is deliberately absent: it is a native VLM +// (docs.z.ai/guides/vlm/glm-5.3-flash), unlike glm-5.3 itself. +const ZHIPU_BIGMODEL_TEXT_MODELS = ["glm-4.6", "glm-4.7", "glm-4.7-flash", "glm-5", "glm-5.1", "glm-5.2", "glm-5.3"]; const ZHIPU_BIGMODEL_MODELS = [...ZHIPU_BIGMODEL_TEXT_MODELS, "glm-4.6v"]; const ZHIPU_BIGMODEL_INPUT_MODALITIES: Record = { ...Object.fromEntries(ZHIPU_BIGMODEL_TEXT_MODELS.map(id => [id, ["text"]])), @@ -694,6 +718,9 @@ const VOLCENGINE_AGENT_PLAN_MODELS = [ const VOLCENGINE_PLAN_INPUT_MODALITIES: Record = { "kimi-k2.6": ["text", "image"], "minimax-m3": ["text", "image"], + // Native VLM (docs.z.ai/guides/vlm/glm-5.3-flash), so it is declared here and left + // out of the text-only list below. + "glm-5.3-flash": ["text", "image"], }; // Every other Plan model is text-only. Declaring this explicitly keeps the vision // sidecar from advertising image input for models that cannot accept it — the same @@ -704,7 +731,6 @@ const VOLCENGINE_PLAN_TEXT_ONLY_MODELS = [ "deepseek-v4-pro", "deepseek-v4-flash", "glm-5.3", - "glm-5.3-flash", "glm-5.2", "doubao-seed-2.0-pro", ]; @@ -812,6 +838,7 @@ const NVIDIA_NIM_VISION_MODELS = [ "minimaxai/minimax-m3", "moonshotai/kimi-k2.6", "moonshotai/kimi-k2.5", "stepfun-ai/step-3.7-flash", "thinkingmachines/inkling", "mistralai/mistral-medium-3.5-128b", + "z-ai/glm-5.3-flash", ]; /** * The catalog advertises image input only for `noVisionModels` members, so a natively @@ -845,7 +872,11 @@ const NVIDIA_NIM_NO_VISION_MODELS = [ "nvidia/nemotron-3-ultra-550b-a55b", "nvidia/nemotron-mini-4b-instruct", "nvidia/nvidia-nemotron-nano-9b-v2", "openai/gpt-oss-120b", "openai/gpt-oss-20b", - "poolside/laguna-xs-2.1", "z-ai/glm-5.3", "z-ai/glm-5.3-flash", "z-ai/glm-5.2", + // z-ai/glm-5.3-flash belongs in NVIDIA_NIM_VISION_MODELS, not here: Z.AI documents + // it under docs.z.ai/guides/vlm/. The header above says an id must be classified + // deliberately rather than assumed from its name, and inheriting glm-5.3's + // text-only verdict because of the shared prefix is exactly that mistake. + "poolside/laguna-xs-2.1", "z-ai/glm-5.3", "z-ai/glm-5.2", ]; const KIMI_CODING_MODEL_CONTEXT_WINDOWS: Record = Object.fromEntries( KIMI_CODING_MODELS.map(id => [id, id === "k3[1m]" ? KIMI_K3_1M_CONTEXT_WINDOW : KIMI_K3_STANDARD_CONTEXT_WINDOW]), @@ -976,7 +1007,11 @@ const UMANS_GLM_REASONING_EFFORTS = ["high", "xhigh", "max"]; // 260814: Z.AI folds GLM-5.3 efforts into low/high/max, so `low` is a real tier here and // `xhigh` is not distinct from `max` (docs.z.ai/devpack/latest-model). const UMANS_GLM_53_REASONING_EFFORTS = ["low", "high", "max"]; -const UMANS_TEXT_ONLY_MODELS = ["umans-glm-5.3", "umans-glm-5.3-flash", "umans-glm-5.2", "umans-glm-5.1"]; +// `umans-glm-5.3-flash` is NOT here: Z.AI documents glm-5.3-flash under +// docs.z.ai/guides/vlm/, so it takes images natively and does not need the proxy's +// vision sidecar. The seeding pass classified it from the family name and a later +// pass corrected only some of the providers; this is one it missed. +const UMANS_TEXT_ONLY_MODELS = ["umans-glm-5.3", "umans-glm-5.2", "umans-glm-5.1"]; const UMANS_MODEL_CONTEXT_WINDOWS: Record = { "umans-coder": 262_144, "umans-kimi-k2.7": 262_144, @@ -1030,6 +1065,11 @@ const CLINE_PASS_IMAGE_MODELS = new Set([ "cline-pass/mimo-v2.5", "cline-pass/minimax-m3", "cline-pass/qwen3.7-plus", + // Native VLM (docs.z.ai/guides/vlm/), so its images do not go through the proxy's + // sidecar. Adding it here moves it out of CLINE_PASS_TEXT_ONLY_MODELS and flips its + // declared modalities to ["text", "image"] in one edit, because both are derived + // from this set. + "cline-pass/glm-5.3-flash", ]); const CLINE_PASS_MODALITY_KNOWN_MODELS = CLINE_PASS_MODELS.filter(id => id !== "cline-pass/qwen3.8-max"); const CLINE_PASS_TEXT_ONLY_MODELS = CLINE_PASS_MODALITY_KNOWN_MODELS.filter(id => !CLINE_PASS_IMAGE_MODELS.has(id)); @@ -2199,7 +2239,7 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [ modelContextWindows: { "glm-5.3": 1_000_000, "glm-5.3[1m]": 1_000_000, "glm-5.3-flash": 1_000_000, "glm-5.2": 1_000_000, "glm-5.2[1m]": 1_000_000 }, // Z.AI's OpenAI path returns 400 code 1211 for bracketed model ids. modelSuffixBracketStrip: true, - noVisionModels: ZAI_GLM_5X_MODELS, + noVisionModels: ZAI_GLM_5X_SIDECAR_VISION_MODELS, modelReasoningEfforts: ZAI_GLM_5X_REASONING_EFFORTS, modelDefaultReasoningEfforts: Object.fromEntries(ZAI_GLM_53_MODELS.map(id => [id, "max"])), modelMaxOutputTokens: Object.fromEntries(ZAI_GLM_53_MODELS.map(id => [id, 131_072])), @@ -2280,7 +2320,7 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [ jawcodeBundle: "zai", modelContextWindows: { "glm-5.3": 1_000_000, "glm-5.3[1m]": 1_000_000, "glm-5.3-flash": 1_000_000, "glm-5.2": 1_000_000, "glm-5.2[1m]": 1_000_000 }, modelSuffixBracketStrip: true, - noVisionModels: ZAI_GLM_5X_MODELS, + noVisionModels: ZAI_GLM_5X_SIDECAR_VISION_MODELS, modelReasoningEfforts: ZAI_GLM_5X_REASONING_EFFORTS, modelSupportsReasoningSummaries: Object.fromEntries(ZAI_GLM_5X_MODELS.map(id => [id, true])), preserveReasoningContentModels: ZAI_GLM_5X_MODELS, @@ -2513,7 +2553,9 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [ models: ["glm-5.3", "glm-5.3-flash", "glm-5.2", "deepseek-v4-pro", "qwen3-coder:480b", "gpt-oss:120b", "kimi-k2.6", "minimax-m3", "qwen3.5:397b", "gemma4:31b"], defaultModel: "glm-5.3", noVisionModels: [ - "glm-5.3", "glm-5.3-flash", "glm-5.2", "glm-5.1", "glm-5", "glm-4.7", + // glm-5.3-flash is absent on purpose: native VLM + // (docs.z.ai/guides/vlm/glm-5.3-flash), so its images skip the sidecar. + "glm-5.3", "glm-5.2", "glm-5.1", "glm-5", "glm-4.7", "minimax-m2.7", "minimax-m2.5", "minimax-m2.1", "nemotron-3-ultra", "nemotron-3-super", "deepseek-v4-pro", "deepseek-v4-flash", diff --git a/tests/closed-pr-branch-cleanup.test.ts b/tests/closed-pr-branch-cleanup.test.ts new file mode 100644 index 0000000000..63cd46f204 --- /dev/null +++ b/tests/closed-pr-branch-cleanup.test.ts @@ -0,0 +1,160 @@ +/** + * Deletion planning for .github/scripts/closed-pr-branch-cleanup.cjs. + * + * This job deletes branches, so every test here is a safety test. It had no + * coverage at all, which is how a name-only match reached main: the planner + * selected any branch whose same-NAME historical pull requests were all closed, + * without checking that the branch still pointed at one of their head commits. + * A `codex/`-style name reused for new work inherited the closed history of + * every PR that had ever carried that label. + */ +import { describe, expect, test } from "bun:test"; + +// eslint-disable-next-line @typescript-eslint/no-require-imports +const cleanup = require("../.github/scripts/closed-pr-branch-cleanup.cjs") as { + DEFAULT_GRACE_DAYS: number; + KEEP_REASONS: Record; + PROTECTED_BRANCHES: string[]; + isProtectedBranch: (name: string) => boolean; + planClosedPrBranchDeletions: (input: { + pullRequests?: unknown[]; + branches?: unknown[]; + now?: number; + graceDays?: number; + }) => { deletions: { branch: string; pullRequests: number[] }[]; keeps: { branch: string; reason: string }[] }; +}; + +const { KEEP_REASONS, planClosedPrBranchDeletions } = cleanup; + +const NOW = Date.parse("2026-08-27T00:00:00Z"); +const LONG_AGO = new Date(NOW - 90 * 24 * 60 * 60 * 1000).toISOString(); +const OLD_TIP = "a".repeat(40); +const NEW_TIP = "b".repeat(40); + +function closedPr(over: Record = {}) { + return { + number: 42, + state: "CLOSED", + merged: false, + closedAt: LONG_AGO, + headRefName: "codex/some-work", + headRefOid: OLD_TIP, + baseRefName: "dev", + isCrossRepository: false, + ...over, + }; +} + +function plan(pullRequests: unknown[], branches: unknown[]) { + return planClosedPrBranchDeletions({ pullRequests, branches, now: NOW, graceDays: 14 }); +} + +function keepReason(result: ReturnType, branch: string): string | undefined { + return result.keeps.find(k => k.branch === branch)?.reason; +} + +describe("closed-PR branch cleanup planning", () => { + test("an abandoned branch still at the closed PR tip is deleted", () => { + // The case the job exists for. If this stops passing the job has become + // a no-op, which is a different failure from deleting live work but still + // a failure. + const result = plan( + [closedPr()], + [{ name: "codex/some-work", oid: OLD_TIP }], + ); + expect(result.deletions).toEqual([{ branch: "codex/some-work", pullRequests: [42] }]); + }); + + test("BUG-R4: a branch reused for new work is kept, not deleted", () => { + // Same NAME, different tip. Before the SHA guard this returned a deletion + // for a branch carrying commits that had never been in any pull request. + const result = plan( + [closedPr()], + [{ name: "codex/some-work", oid: NEW_TIP }], + ); + expect(result.deletions).toEqual([]); + expect(keepReason(result, "codex/some-work")).toBe(KEEP_REASONS.MOVED_SINCE_CLOSE); + }); + + test("a tip matching ANY of several closed PRs is enough", () => { + // Reopening and reclosing a branch, or two PRs from the same head, must not + // make the branch undeletable forever - matching one closed head is the bar. + const result = plan( + [ + closedPr({ number: 7, headRefOid: OLD_TIP }), + closedPr({ number: 9, headRefOid: NEW_TIP }), + ], + [{ name: "codex/some-work", oid: NEW_TIP }], + ); + expect(result.deletions).toEqual([{ branch: "codex/some-work", pullRequests: [7, 9] }]); + }); + + test("an unknown current tip is kept", () => { + // A bare string carries no tip. An older caller passing names gets the + // conservative answer rather than the old destructive one. + const result = plan([closedPr()], ["codex/some-work"]); + expect(result.deletions).toEqual([]); + expect(keepReason(result, "codex/some-work")).toBe(KEEP_REASONS.UNKNOWN_HEAD_SHA); + }); + + test("an unknown closed head SHA is kept", () => { + const result = plan( + [closedPr({ headRefOid: null })], + [{ name: "codex/some-work", oid: OLD_TIP }], + ); + expect(result.deletions).toEqual([]); + expect(keepReason(result, "codex/some-work")).toBe(KEEP_REASONS.UNKNOWN_HEAD_SHA); + }); + + test("SHA comparison ignores case", () => { + // The REST and GraphQL APIs disagree about case. A case-sensitive compare + // would keep every branch and quietly turn the job into a no-op. + const result = plan( + [closedPr({ headRefOid: OLD_TIP.toUpperCase() })], + [{ name: "codex/some-work", oid: OLD_TIP }], + ); + expect(result.deletions).toHaveLength(1); + }); + + test("the existing safety rules still hold ahead of the tip check", () => { + // Each of these must win BEFORE the SHA comparison, so a matching tip cannot + // override them. Asserted through the keep reason, not just the empty + // deletion list: the reason is what proves which rule fired. + const at = (name: string, oid: string | null = OLD_TIP) => [{ name, oid }]; + + const merged = plan([closedPr({ merged: true })], at("codex/some-work")); + expect(keepReason(merged, "codex/some-work")).toBe(KEEP_REASONS.MERGED); + + const open = plan([closedPr({ state: "OPEN" })], at("codex/some-work")); + expect(keepReason(open, "codex/some-work")).toBe(KEEP_REASONS.OPEN); + + const fork = plan([closedPr({ isCrossRepository: true })], at("codex/some-work")); + expect(keepReason(fork, "codex/some-work")).toBe(KEEP_REASONS.CROSS_REPOSITORY); + + const stacked = plan( + [ + closedPr(), + closedPr({ number: 43, state: "OPEN", headRefName: "codex/child", baseRefName: "codex/some-work" }), + ], + at("codex/some-work"), + ); + expect(keepReason(stacked, "codex/some-work")).toBe(KEEP_REASONS.BASE_OF_OPEN); + + const recent = plan( + [closedPr({ closedAt: new Date(NOW - 60 * 60 * 1000).toISOString() })], + at("codex/some-work"), + ); + expect(keepReason(recent, "codex/some-work")).toBe(KEEP_REASONS.WITHIN_GRACE); + + const protectedBranch = plan([closedPr({ headRefName: "dev" })], at("dev")); + expect(keepReason(protectedBranch, "dev")).toBe(KEEP_REASONS.PROTECTED); + }); + + test("a branch no pull request ever used is out of scope entirely", () => { + // Neither deleted nor reported as a keep: this job only speaks about + // branches it can attribute to a pull request. + const result = plan([closedPr()], [{ name: "codex/never-a-pr", oid: NEW_TIP }]); + expect(result.deletions).toEqual([]); + expect(keepReason(result, "codex/never-a-pr")).toBeUndefined(); + }); +}); diff --git a/tests/moonshot-tool-schema.test.ts b/tests/moonshot-tool-schema.test.ts index 80ceb5e5b9..ae37643172 100644 --- a/tests/moonshot-tool-schema.test.ts +++ b/tests/moonshot-tool-schema.test.ts @@ -226,6 +226,66 @@ describe("Moonshot tool schema normalization (issue #2673)", () => { expect(value.enum).toEqual(["x", "y"]); }); + // BUG-R6: "the node narrows the target" was asserted, never enforced. + // + // The test above uses a node whose minLength is TIGHTER than the target's, so a plain + // overwrite and a real narrowing are indistinguishable there. When the node is LOOSER, + // the two diverge and the overwrite ships the weaker contract - the opposite of what + // the comment claims and of what `$ref` means under 2020-12, where the node and its + // target both apply. + test("a looser sibling assertion does not relax the target", async () => { + const parameters = await emittedParameters("https://api.moonshot.ai/v1", { + name: "loosening_tool", + parameters: { + type: "object", + $defs: { + Tight: { + type: "string", + minLength: 5, + maxLength: 10, + minimum: 10, + maximum: 100, + }, + }, + properties: { + value: { + $ref: "#/$defs/Tight", + // Every one of these is weaker than the target's. + minLength: 1, + maxLength: 99, + minimum: 0, + maximum: 1_000, + }, + }, + }, + }); + + const value = (parameters?.properties as Record>).value!; + // The intersection, per keyword direction: lower bounds take the max, upper bounds + // take the min. Both sides apply, so the surviving constraint is the stricter one. + expect(value.minLength).toBe(5); + expect(value.minimum).toBe(10); + expect(value.maxLength).toBe(10); + expect(value.maximum).toBe(100); + }); + + test("a tighter sibling assertion still wins", async () => { + // The other direction, so the fix cannot be "always prefer the target" - that would + // discard a genuine narrowing, which is the mirror-image bug. + const parameters = await emittedParameters("https://api.moonshot.ai/v1", { + name: "tightening_tool", + parameters: { + type: "object", + $defs: { Loose: { type: "string", minLength: 1, maxLength: 100 } }, + properties: { value: { $ref: "#/$defs/Loose", minLength: 5, maxLength: 10 } }, + }, + }); + + const value = (parameters?.properties as Record>).value!; + expect(value.minLength).toBe(5); + expect(value.maxLength).toBe(10); + }); + test("a deeply nested ref-free schema is bounded instead of exhausting the stack", async () => { // The second blocker: the expansion budget counts $ref inlines only, so a schema with // no refs at all walked unbounded. This nests far past any real tool. diff --git a/tests/provider-registry-parity.test.ts b/tests/provider-registry-parity.test.ts index 1f155d76df..53c7fc2076 100644 --- a/tests/provider-registry-parity.test.ts +++ b/tests/provider-registry-parity.test.ts @@ -369,8 +369,42 @@ describe("provider registry parity", () => { .filter(entry => entry.modelSuffixBracketStrip) .map(entry => entry.id); expect(zai?.modelContextWindows).toEqual({ "glm-5.3": 1_000_000, "glm-5.3[1m]": 1_000_000, "glm-5.3-flash": 1_000_000, "glm-5.2": 1_000_000, "glm-5.2[1m]": 1_000_000 }); - expect(zai?.modelDefaultReasoningEfforts).toEqual({ "glm-5.3": "max", "glm-5.3[1m]": "max" }); - expect(zai?.modelMaxOutputTokens).toEqual({ "glm-5.3": 131_072, "glm-5.3[1m]": 131_072 }); + // BUG-R5: glm-5.3-flash is a native VLM (docs.z.ai/guides/vlm/glm-5.3-flash), so it + // must never sit in noVisionModels - that list routes a model's images through the + // proxy's vision sidecar, which hands the model a text description of a picture it + // can read itself. The seeding pass classified it from the family name; the + // correction pass fixed the Alibaba entries and missed eight other providers. + // + // Asserted across the WHOLE registry rather than per provider, because the defect + // was not one entry being wrong - it was a set of entries drifting apart, and only + // a global assertion catches the next provider to seed it. + for (const entry of PROVIDER_REGISTRY) { + const flashIds = (entry.models ?? []).filter(id => String(id).includes("glm-5.3-flash")); + for (const id of flashIds) { + expect(entry.noVisionModels ?? []).not.toContain(id); + // An explicit modality declaration must include image. Absent is allowed: an + // unclassified model falls through to native passthrough, which is correct here. + const declared = entry.modelInputModalities?.[id]; + if (declared) expect(declared).toContain("image"); + } + } + // The sibling it is most often confused with stays text-only, so the assertion above + // cannot pass by making every GLM row a VLM. + expect(zai?.noVisionModels ?? []).toContain("glm-5.3"); + // `glm-5.3-flash` belongs in all three maps. It was seeded into the model list + // and the context map alone, so it advertised a 1M window with no effort ladder, + // no default effort and no output cap - and this assertion pinned that gap in + // place rather than catching it, because it was written from the incomplete + // state instead of from the family definition. + expect(zai?.modelDefaultReasoningEfforts).toEqual({ "glm-5.3": "max", "glm-5.3[1m]": "max", "glm-5.3-flash": "max" }); + expect(zai?.modelMaxOutputTokens).toEqual({ "glm-5.3": 131_072, "glm-5.3[1m]": 131_072, "glm-5.3-flash": 131_072 }); + // Every 5.3 row carries the same three-tier ladder. Asserted per member rather + // than as one object literal so adding a member cannot quietly skip it. + for (const id of ["glm-5.3", "glm-5.3[1m]", "glm-5.3-flash"]) { + expect(zai?.modelReasoningEfforts?.[id]).toEqual(["low", "high", "max"]); + expect(zai?.modelDefaultReasoningEfforts?.[id]).toBe("max"); + expect(zai?.modelMaxOutputTokens?.[id]).toBe(131_072); + } expect(providerConfigSeed(zai!).modelSuffixBracketStrip).toBe(true); expect(providerConfigSeed(zai!).modelDefaultReasoningEfforts?.["glm-5.3"]).toBe("max"); expect(deriveKeyLoginMap().zai.modelMaxOutputTokens?.["glm-5.3[1m]"]).toBe(131_072); From b0e893e71507777524d6bca314bb9952655e07cc Mon Sep 17 00:00:00 2001 From: jun Date: Thu, 27 Aug 2026 02:36:25 +0900 Subject: [PATCH 2/4] test(ci): import the cleanup helper without a lint suppression The hygiene gate flagged the new eslint-disable for no-require-imports, and it was right to: the repo already reaches CommonJS helpers through await import() (ci-workflows.test.ts:5030), so the suppression was covering for a spelling choice rather than an unavoidable constraint. The interop shim is deliberate rather than defensive. A .cjs module reached through ESM can arrive either directly or under default depending on the loader, and picking whichever object actually carries the planner keeps the test honest about what it is calling instead of asserting against undefined. --- tests/closed-pr-branch-cleanup.test.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/closed-pr-branch-cleanup.test.ts b/tests/closed-pr-branch-cleanup.test.ts index 63cd46f204..b18fdd7016 100644 --- a/tests/closed-pr-branch-cleanup.test.ts +++ b/tests/closed-pr-branch-cleanup.test.ts @@ -10,8 +10,12 @@ */ import { describe, expect, test } from "bun:test"; -// eslint-disable-next-line @typescript-eslint/no-require-imports -const cleanup = require("../.github/scripts/closed-pr-branch-cleanup.cjs") as { +/** + * Dynamic import rather than `require`: the repo's other CommonJS-helper tests reach for + * `await import(...)` (ci-workflows.test.ts:5030), and a `no-require-imports` suppression + * here would be a new lint suppression for a problem that has a supported spelling. + */ +interface CleanupModule { DEFAULT_GRACE_DAYS: number; KEEP_REASONS: Record; PROTECTED_BRANCHES: string[]; @@ -22,9 +26,15 @@ const cleanup = require("../.github/scripts/closed-pr-branch-cleanup.cjs") as { now?: number; graceDays?: number; }) => { deletions: { branch: string; pullRequests: number[] }[]; keeps: { branch: string; reason: string }[] }; -}; +} -const { KEEP_REASONS, planClosedPrBranchDeletions } = cleanup; +const cleanup = await import("../.github/scripts/closed-pr-branch-cleanup.cjs") as unknown as CleanupModule & { default?: CleanupModule }; +// A .cjs module reached through ESM interop may arrive under `default`; taking whichever +// carries the planner keeps the test honest about what it is calling. +const api: CleanupModule = typeof cleanup.planClosedPrBranchDeletions === "function" + ? cleanup + : cleanup.default!; +const { KEEP_REASONS, planClosedPrBranchDeletions } = api; const NOW = Date.parse("2026-08-27T00:00:00Z"); const LONG_AGO = new Date(NOW - 90 * 24 * 60 * 60 * 1000).toISOString(); From f25dab804716b9c251ad7a149362793f9533597c Mon Sep 17 00:00:00 2001 From: jun Date: Thu, 27 Aug 2026 02:52:17 +0900 Subject: [PATCH 3/4] test(providers): move two more assertions that pinned the incomplete state Both were written from what the registry happened to serve rather than from the family definition, so adding glm-5.3-flash to ZAI_GLM_53_MODELS broke them. codex-catalog expected modelSupportsReasoningSummaries to hold exactly the four older 5.3 ids. That map is derived from the family constant, and flash belongs in it: the reasoning-summary question and the vision-sidecar question have different answers for this model, and only the second one excludes it. cline-pass had my own editing mistake in it - I had added the id to a noVisionModels literal that is computed from CLINE_PASS_IMAGE_MODELS, so the expectation contradicted the derivation it was checking. Removed; the list already excludes flash on its own. --- tests/cline-pass-provider.test.ts | 1 - tests/codex-catalog.test.ts | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/cline-pass-provider.test.ts b/tests/cline-pass-provider.test.ts index 94072bc60a..c5e80cbecf 100644 --- a/tests/cline-pass-provider.test.ts +++ b/tests/cline-pass-provider.test.ts @@ -72,7 +72,6 @@ describe("ClinePass provider", () => { expect(entry?.modelMaxInputTokens).toBeUndefined(); expect(entry?.noVisionModels).toEqual([ "cline-pass/glm-5.3", - "cline-pass/glm-5.3-flash", "cline-pass/glm-5.2", "cline-pass/deepseek-v4-pro", "cline-pass/deepseek-v4-flash", diff --git a/tests/codex-catalog.test.ts b/tests/codex-catalog.test.ts index e507e8778f..a2f5b52fdc 100644 --- a/tests/codex-catalog.test.ts +++ b/tests/codex-catalog.test.ts @@ -4747,6 +4747,10 @@ describe("Codex catalog routed normalization", () => { "glm-5.2[1m]": true, "glm-5.3": true, "glm-5.3[1m]": true, + // glm-5.3-flash joined ZAI_GLM_53_MODELS, which is what modelSupportsReasoningSummaries + // is derived from. It belongs in the family for reasoning metadata even though it is + // excluded from the vision-sidecar list - the two answer different questions. + "glm-5.3-flash": true, }); }); From bbfdd65fdac7bd936268025ca90eda56f34b67e2 Mon Sep 17 00:00:00 2001 From: jun Date: Thu, 27 Aug 2026 02:31:55 +0900 Subject: [PATCH 4/4] feat(codex): show the commit-attribution layer, and stop rows claiming always-on The prompt panel was under-reporting the prompt by a whole developer section. ext/git-attribution contributes one - the instruction to add a Co-authored-by: Codex trailer to commits the model writes and a Generated with Codex. line to pull requests it opens - and LAYER_INVENTORY had no entry for it. It is runtime-conditional, not a config toggle. lib.rs:33-80 resolves enablement from the auth server and caches it per thread, and features/src/lib.rs:277 records the old config flag as removed, so there is no key for this GUI to write and nothing in [features] to point a user at. The row therefore renders with no switch at all, which is the existing rule for a layer Codex cannot suppress: a disabled control would claim a capability that does not exist. Its order is null because it registers through extensions.context_contributors() rather than appearing in world_state.rs, so its position is registration-order dependent. That exposed a sorting bug: the panel collapsed a null order to 0, which put such a layer at the very TOP and claimed it is assembled first. Null now sorts last. Rendering the page in a real browser then caught something a unit test had not. The row said "Always on" while its dialog described a condition - and so did plugins, which has been shipping that contradiction since the panel landed. The condition map existed and only the dialog read it. The row reads it now, so the two surfaces cannot disagree about the same layer. The probe reports this layer as not-exposed rather than guessing a tag. The Rust source names a marker pair, but a world-state section is diff-rendered and emits nothing on a turn where its state has not changed: live codex debug prompt-input at 0.145.0 returned 32978 bytes with no such block. The probe header already records that inferring tags from Rust constants produced a wrong mapping once, so this id goes in the unmapped list. Nine locales carry the three new strings. The about text says what a user needs to decide with: that Codex resolves this from the account, and that turning it off sends the opposite instruction rather than sending nothing. --- .../2692-git-attribution-row.png | Bin 0 -> 126254 bytes .../components/codex-set/PromptLayerRow.tsx | 19 ++++- .../components/codex-set/prompt-layer-copy.ts | 9 +- gui/src/i18n/de.ts | 3 + gui/src/i18n/en.ts | 3 + gui/src/i18n/fr.ts | 3 + gui/src/i18n/ja.ts | 3 + gui/src/i18n/ko.ts | 3 + gui/src/i18n/ru.ts | 3 + gui/src/i18n/tr.ts | 3 + gui/src/i18n/zh-TW.ts | 3 + gui/src/i18n/zh.ts | 3 + gui/src/pages/codex-set-prompt.tsx | 8 +- gui/tests/codex-set-prompt-layers.test.tsx | 79 ++++++++++++++++++ src/codex/prompt-layers.ts | 18 ++++ src/codex/prompt-text-probe.ts | 7 ++ tests/codex-prompt-layers.test.ts | 19 +++++ 17 files changed, 182 insertions(+), 4 deletions(-) create mode 100644 docs-site/public/pr-screenshots/2692-git-attribution-row.png diff --git a/docs-site/public/pr-screenshots/2692-git-attribution-row.png b/docs-site/public/pr-screenshots/2692-git-attribution-row.png new file mode 100644 index 0000000000000000000000000000000000000000..464f4df1e2b96eec3b8ea0413988a85f47cb03fc GIT binary patch literal 126254 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

NM3T|d_3e{K(^oWUU9+R($2-{-Kf~?3g-{@ zxDbn`)!wZ<8MJaw8R)D+drJ@Q&CwHr>e@qUm1^w5gZ<%kZNw zfWjCTr2=Wa|J!*lca8mdP$FQsJ(pNaCKgymU|{lubhbnz0yww-w~LsKT&)oz91-S7 zH-CcmzWQ0YAY+vMo|6@=HJ4s(#RHaoHj2hFua31B&c6#90dggl;6K* zQ~3KM3F*@Rsk(X2gD4q&W;x*UiMvbHWtb|Ni%~HXacHV0vi^#Sg@hpgI|8ZzK@9eV zy)oPHDb%#I#45Dd?-zXtL?n>%zrv^gkMzwC2@T|2h;*I6dhXxZ=6_UVpKG`Mi>>^x zLstJ+O0fS2h* z0oMN?e53ytk+q3R_qWZ&D7!`+GAtH_irv)|C3ds|K|y=FfR4Z4)e5*3K;beQB6b4D zLz%lg?S7LLE=Y9-_JWj_mwo$3@+izok7?%eLpm?BgOI1;{-fDA)_LTT0*w? z4*~>>&}YE4!tT}iW9+%)1V>?^o?@I#Vx3!zf+Gd|?xYKZrg0F=}sqM16 zFK^(o^_MOi5v{dKWJ8*=Pj~phaY@_z-lqvC+iZRyfs_Vt~w` zi|A~ihJ)O%-NBVUoo90H~Q~)DetvcxAY?1k$ z1|ac1=`$%iXA8?T+;|VcE$1Tt)S7R$-!Ap)OW@38y_e_4QN2aze#O%HVeAEYnW|aB!lSWySBtX`@Q94B z7|JoEuh@?TsjaQL{#TOb;Z;Df-+3WPixDI3HchM!vAHMa!_oOAJsL|skxOGiWr`h( zj4$T!ssJ&)(q0Q?3QV=7n@5qW=U_7ibAa5R^0QLEo3TLgJV?(1$DKhi(M)-dV)xn7 z@L4l=jT9&T80#Z#nKnMgXHm#kx?Iw&f${1~V)u%+J8mhgZP_D>d8_{T-GBdHCUPd!OX)9uSEa-<5$i>J*KaBq{TZ-t;GKQ;mLkR%DxT! zaEw6R^nNfsImYdNjDXE0H)OpxkNI9 zP~+!ytH7AM71)klW+ryIMw8vYZ&oTG6MK^>hjL;#{N_r?^dc}$nTwuX-TPNuFouIz z(&a8%cRA!~JqI;A?)z;Ntq_mcK~6UJsOFD;%EOF1hi+=$&RkVy!&=p>aW85q83SF^ zXqh)RUsfkBpRP1_c_+ruqV4RJfGzorS;Yi&ykGMv?8Ny1{k~d@jo^?ruWg3e#}%w2 z@@(cfDl$bT6Pre8?4(W>SVZ4TYPC12D7*08!eC21_k-Z&*z^828VCW)QnRI3Y;(}DpRq9xkH+|EDi*4Cy#*Qp%gPu0@BII5QP)CuOfi!7o zXsE3u_htCxoJSp}yg;Sh+budr_lbkMDEC6~o32zT(l6~h^YsmUfki7kPx-pmff?|# zF}s>CNZoTOuC-TXvA`$+Ol!t9uJ1e=v1TzMARjXFg1Qs>cSWD}J&%K52h%P z3Xd>c{vAWId~taPPggiV{|s9XmP0M>O1h_HXq1_YRA}1YFbdeIGd_7M7bZaP3lCT# z;>Zc7q$ti5adsNm&M}{ex~ldjC)3Qp%=1LLS+PP&iQJ9^&G1RH95cVcG4rD`Cf$S5 zDK>TmrHQRV;w1Ia_SpwgKl%gu_NM;Q*7pm0F`h16J>FF=pJKvp*2t#+32k9)(;d3& z+gncrmR6^d#+1%Jm1_)Xl^7+}(R&gi+2F&?9aCsu6n`U?%^?TU3h%x_^%Vclg~#so zfdI;+lf16v5IUdUWy?hM>;tn^d5OpC4y->kc;r_YaW4N*z3ph)af9pSk!OT@)PzEB z-%In-Q9Z*-X^TtuSah@hcEihA-zd8{);H~Dtc+kipvXPd)3)gqSyy7)rkfqr)hWtr zJDxSICKNj?c*sQE$thLb16AA01VPHqHX*-%LNTS_=h4Lu=PSpo9-&)y4URlI=yYaa ztLG%@O|3`0Z(4axTs!D`zW@%l8CH>bK)_;`>Izhr25qO-&FdSqF80!yUDBwT(mwm7 z<%pYwx_ZZ(aF;We_j4#-rP2vmWP2H-eU;N;Bvo^XyV}qx&BpC*osbMo;nw|HV^zbR ztcead1C19vOfuF6C7$R+aGq_HZ&2Ubt2fb~$|o>1$nW3fE0r{OhEArE&)Vg7mzmp9 zw%YosG*>$1gXfT{g}T$|l}RmKb33U7Fnw`Z8%tt8I#LXm{%EZ+dHOb6j2^cbtkyEyiVLW z;$UonBX&4FUzT;U-FHJ?Q>-!7{nC8 z51H^*wo%;FlDcvyU*oNsK>E)XYUh>Ep7Nay6A{Pldz*c8vn5u#ocm=LC1{J;Hi=)? zbBQ`H@Rc!1e0VC&Or-kj5TjN9rF)ipKe35b`pK}f)cc>!`guUxMtoHI&9l0+7p-L> zOm>IlcP0ETP+cY!7C6W5tjck~`63-935{XSr~=&&8t(Ag1}%y&A-+%eCId?Md~&R0 z`mMlWX!J%kYn?gQZl4u1cZPlWi?({_S6UreHv0c)?(3`{Hu_h8EhU-4Bp$8ZPjn~_ zc6LJTQWRmz<;6C-q^$|&M z#GI-^ze{Rns0mgHg7AcBE>au`cl*nUT1iewT7vL*EC3?c`TC zEzLfBPX|%lLd9K9B^vMH-GWwsPeU)djD8#EXZPRh6K zInA9&v6p2km@;FkFQLlOKDAY|Bk#+XWV5QP7Bu0YmoC9ezVLLRKEW$)kF;X#NfDlj zTrHnftIR)X8!^D8%uPeH#qrc@m!Zubw=c(GP_!ve$~HCH>TJUcNsGRWoigL$UttHMY*@y|%$Y0KzxOOLP()FQ z4_OJ*Ga2qr%d~qPP5TRmU+2&ga=UKY@fxj*KuE)IByU4S$$DOAiCEPK6$3J@w&>E( z{O~naK{aBCru?eAfd4S&(8PROdrNy*uAFC^HY6Knm~k=-fHb?JHhI^S(R4~r z;*P3t;Wdt%lGY@b8dj|D+b*4@2|w3qYq&llkX;hA5lF}Flll9X?3*n-?RA}%UP{5m z&X=y<(2wd(ijbD8rVVgJnHC_m!Pe_`=rq1do%v z$cJjFv<|!`79)5ldT z$X*!D(i-ctNIaU|p%P!jOpeJ(FQ9a%FQk;DVYUogVa*S}ys_tSz9Clgy&PS%KRtN{ zvPNDRhQ`h{2ogw+n!+nftlw&uAk!b1?xEwkk)mhMqT}TD3gvJ8BaTD*kJ0aGkx<}TQ!JR@anu* zmQ(#V*e|_v!SL^J(4%L~`jMS$b#9M;_P;o8xZ-@}S}$J`x5vIIHm_ID94S*9(7$+{ zhP37Z5Y5iFX8#S@jPAuMMqc5@e<9RB)FkzcFz2#O3? z9i}u2o-OlxoE*z{_APd2nB|w$JJr-#HiRsUqG>@3)Y(}CvCrOL`YijkkCnd;xNRX- z*l3;YJ3(#YV6w}bYrGdVXgSHzu*Jt$`G<$;VxfTA3CQq;w*c!UIXiMv*EQ5CJXg*% zi`sT_iW?gW@!0eUWt46iykNjxL~@&l*6`Cs05ER99-UY^-Pn5O)Hbi@44=6MLe(UG zvg}-9*)CskcHrB?s&^ALV|%1hz&1XFF2yh-v|KOdJkUWjuD>xHS!kuq*no=s?I=T0 z33(<>>iFI&)meH&<-I6`T9Px6l2-C zs~c8|4haWTODwqKvRx-eZ%-HY%1+iSGo4ZQixuM*3Y2l^a2m?1uQ4RGH7c`f!+@1Y z8Gp%Fo~R+)oB0a;qkFF2t8+jdIB(kIigIw1I6mD9=zf zSwDT3JAT`Ajq)yw@4KG5S9$X`VID)*#;G&ylic?hzqImxevj@Kh;r#ZL*BZ<^CI1C zo95*?wytT(dxa{6Wqy#d*suKTdLAx%vB{Rpkr? zsr4moJ?J>X3Vl-*yCXW(Mg#3YhB;-@31!MY*io5v=0!=_oDJ9As}ZR?b`?lCH|M;f z?|08jLUZeNQ?@@lgv0zC58Y9jFRBhqKif-vcg7~1&pLneUW3nQ8D{O6QhFCJ1gBk; zm7xDRSQ=)?vu6(QX9*nsdg2N)OsBv4%A`lt8bW&UA!FL zz*d*c)fCmLrIW_0@-qlF5h<7alJ>2Ceo%bM{MT?l6dP^h9P$->Lx$5+UM|xc>%UZE zzhI_&?6oB987l+=sf9Ujx@u%wJdh(=w^wjlGc|@cuB?#Cn&z_T5`FUMy z@2TuxOT+9DL3P2Kbr02SUgem2+5KHJu~GPPeWQR)S_KqR6Nk2N$$ol!;eC^FU5AYG zs-gEznrv@MCQASI@T8=@<3Y#ffqM16tGLYV{O#G2KfAd3CLJv;_b7W+gC@mWi&NIN ze-5jnD0j9Y1_kSLy$!KbtS9`?iebSIuLS(RQ)|J9{Qk*Fob&GC%m{hnu_v7`pNY+pLA;V>!`zk`lzP!eftu@6V9-}dUW_o(Wgw3G z`P*kbuI+fJ$~CD$zE)}e58Dp~Hf`$hn(sW?uLePN4M-I@So9|#rW#lv+;97!0M4O( z?)AkhzvvMVmP{AWS>})$T@|OlY%8W2c6oySLTCREtBn6aEcGwY`hScB8Jw3w$|6HS zMP>Du;m2G$xK8M`C;?<~5R)SG7ut-0s+NOq`sb_RB81w%zvTZX-sisvStB3x@9+M; z5Aa4&aMOea4AvfSxR_sA4CkrdejyhGW}Jwx1*GbvY{};U`A=V=jT=eH0XUu8jEssZ zc?;(+lWPq0T7-)PjJ7|19~TjARAB}bNPzt~e|!Q$^UHs`nF2pJrn9pXB=%rW2sA-p z93n~Oj~{;X+g%8`YI1!iK&pfU!jFL3=nlb_N2v!zNr|H{|KGicuZU>y76$@MI$ zLpTHgclVoV$YoBu=)#N8bQKEJ^^vocV9S zb;}wVmx$$L!I%Pt8ph9pBGvpFVzaDwbt@O5a!&$dJe?7f<59~? z`QmL9E*Wu8id)DVF?8|ATKwug*Hd0b&A_Zw~-YEKhAvME@rYOekM;qLIOO zxHryqTNrSI`3!TpH_&!~v6ltLP#_K_ev<%jU3m-OA;Wc#n06r2fTBXF%n+ptjsT2F zXozAQgyR951hZg|!Y>X`K&5#bbaU|SegQ$sz%{bO4)WX(FVq(r$ij22hWXkC%rxVp zyfpzBY<261y#j8L%*do zo8UW*gP`^}TcbhpqRL>2z|XO7{x@e+!JD@*QVgvDgrcnKo*Z6%q zKn(K&XacQZEE6IgY57gjvIjwMj97!lO7H6h#<)@LGr?+uy(8=k^0abLRc;_g`^c09 zG85ccMdK%-W*)u=e9AWy2XBBN@enQ;FCcJEAk;}DyadT(mjeAeD0s-{Ju@?)x-#GD zObL7Z7*dbg25u|>D;|o^-0IFo_|soPEChsh!(@g(z#EnYg6O!cVD(1!N3ad~6O^t_ z@ECO5H;lt#xe#WSC&UWEaDg#kIrF||EEkuoXO@_2@LZ~6 zbWHqvppbIX!*L^1_W(9-_??~r2k`$Z8*hXW8wH-yA?uvqope}uFw@Atkxo4vEO7!7 zn$#dzh(n4VOjCebGrJ*98+m++a(kakOk`PDFeV%pC5AuhbtVZ0otgy7qh5eJGpr<( zqlDzG)s;1npW%t0z}rLIbm#1x{0m%w`3!cY4#7-*R16F<_Xe2+7ZI;L;VwX07msz` zXh+<#nB+BFkreD{|f-rZvE)3?cyu zbV!Z=-8v6E?$Gq0*1#F&%Q1a|0#3IB`6W0Q?884WfF~>LR%yl^W)HQ_Q)u2UFuYa& zD1f^^qnqOI>^}Rr?BmrkFp*X}R+ekVWJcW!mSMXecK)^Tha*)OICPqCJ|8mh=Kz!sj%p+m9rDXzxUBNP; z%aW;IgNHjMVreB*Rr5DSVf4msQgGhu2qhcXV6X?QtxKnIRr)ce?m71p(Bm3tU?ry# zRX+f$XSp9w%TmAI+KL>*`*nwxarNywJxa4B?@4XSJ?!l>SO`A_UNIxnhpDzda4}4*D`rXZ40(SjV-}fbgCl?LyyucKG4_uN?4cSiZu}O%P zN*{xh5YVAC!C7Q35vHWT3LcskYCVzx=il|+B-nNPxYZZ6&jGD zaKsTNwLjm3$2r_1m9EN9p>aW)7||ptwBb0A%G>RcEv zeHGn4O=H~fQ7+4Ee%1VnPo!5Pk0va)p=jmB8yHxFr(bebT&Hlh`J>zEw;QeKHEar4 zL%aNt6Tbuo>0ueb|B9fxeYek0oSyO&MwN6N=(ZJK$68gK+&c-Ge)sKzXrM3jIUdR4 z4PCaTRc6+{Q~_2-c&FbE4J!ZWKNY4qpb`)USm0A5Y<=NP7a(Q`;spW&o}!im1$>NA z;Ls`5jSK#)?lh|I6b}6fodxX2nF<>cAJenG$B!Q$HV*Z2vvI-=LFR4N(=gCOewJL>Fq4;=JlnvsC(9wbCY0wkE-1h2LE=cgI!A}LiDiWhb zPtH0k2#bwCUp|&hdnaZ;BC}rJulw`&cMaL2nEltu5xEv2tr`dVQ97dgof1}@jEwisFknb zAZL9JR!wtelYYwrOWlpFnTPH`gsTj;fzfO;wTN>iC5}}fJT#=LbSS-W?vz!cO^mFm zUzrm3wMHTl$NO|RjInM)9b1b3GH|&cpqK33&I6F}NNx=-fTtatsL`dUGY}MTZh*B& z*jR$)B@^(LgV%M%xIWeK8UHUKdfZVhlFLcZGg4rN%0OE3H7JTQ&n1+d1ET*5xW(c> zKTXeU!wsK70$g7S9|bZfJ@WaEwg)5FeDJGKCy<|pQoOdG;Wt@i>||u28GoKu0S;@Puj&BV!5$5_+u7y$UGvsm6y7>*V)gZr;j~iUC#QMM2AOA7>G9FA51f zFVNt_Esf#avHk2quxbiAQQ_ot zdpyxnzM%8!+lS#_mth^%i#I^@_*(w_N>#nQ)|gQ1YNhy?`RNq?1swX{jQx9i4TWf& z)7-ssffu6^|6B{d1R=u%y!z68s<>PbIt`qUzZ<3Pz`YU_Ms2B(vDQg`1yUd88N1P< zBoUV(cR1^+GjYXD?r)j99dv(39|O%ajk4YuAtnXZR!s9DoV`)l3BBenXgp(5s*gK~ML;{6YW01cXJR^54Zw zngxJ%4r}b3@o8NQJofo7vrwl4VY<{Du^&X3WTtZ<+=4gPU3dE~B<=x>gHBEC!eB0> z8w$2t?G5Cj(5Skv3^K2OF@*vfQT>!|fshxZZYJE+ZC&FQUt^|-&LrV5^_a4~k_Q(N z0!tEwHp%gjvBCRgvjpl{WRU0-&oe~7$ggaOxPAgt5^yw-$03Oz6&v%0KvWUgx~>F> zHE7Y+889COJzuO!T&?Tq%O+Luc7v>6=y84(o~4R9XPx~7S=R-A(?F||koFjn7u*;_ zwz!jU^Xdha0kx(n|JH_?nF*94fsZqNwg$i(#2a=VH#IoDGRdL)LH`b1C@if6ifR~m z!S{j-1qe{+)G#~R0jTk<9_d2adkyD}_pa}^j~XqCm6YVq4i5mNc#${(7BdIX-8x1z zA>v$e7BTch&YSJZhkwz=1mI2wb`3)z zco+!b>l*Ur?r_n-TdXF(a?P>mebD;umyb?uIMszi+bcStV}K~3X>v6z#NHN@W*J=ZD;7wq*05^z&{kr8$ z03ae~p!&-8MGD7rK#>b9dJD5!*@cWt;9X2?X-3IsQ?hy;f_!tMU5`*lVOoGi_5R1nbz=Agyjkyixf`lMZQ zKMVctKtR}XAspTC_18c(YxNskzbyM~EC71*z#%}8C(}}(%$Y8keIQC%fuSL2rhULU zv@BcWj%7py0l;O80G;H9Il#n=xMGFUlm`jvb~7l@xOmj0O`$W(Iz`(D>gM-PK04}% z$LU*PR;ZLFJ6YTnV+F9|#&ekySXipN+f?xrunpWUUjoyw%S&O2;oEMRL>i3W1@YDW zV56kb;XKCUh&q4>n6$L}N^KcJpMhcrL3h>5TS!)k|8K9Qj`B@{7l}z%I|O|JP*~7= zrUsfzdCT)|cJ1a3U}nrUbQ4KSa(zPV~G3UWdEMQ&7l ztqjY`+`S;Fm^-EZ%xYPdm6a91l{xW4glxy`Kn&}#a(&nB@(oe1*%uoBzyfG5GCQB@ z^RFDUdXLU}1z^?+re%PmC;yeBn}$~|w|HtYKZB#&j$Qq`TcaHx7YM zNDX39SwK$Ibu$ZxY{T!#(1?%8Vu-=6B1{xtK0BWo?cTEc)0tK!iSy5B-YlWF{cuH$ zJ7izq@ex&%*cI6NqN9^@aE9~~wK^=^EFGDbLhuK@Ul8epE(tn>ZD?yNo~2*c+bw&- zW&rao`wb%MXIAIg)twFj$h@zl`st2@DaSdr&`Q(00I0NDn|`^Q$-tx?ec3Bh_1twW zhD088o{*aLS#^qj3(U_+d?qp?qS3$e6R+s7*i(}9wt4a>xiIxd99k+(2IwG=CPodT84gi zYT?kHL;>EZ58abQbftIhc zid)q4StpOLUXBsB4KB~vhUMPAA1CR;Jl|?L0{QP4>PEYnlD{G)__n{sWKck29XTyA zdo`p=S(mNMb>E#*n1WKySx8Btcj*I49mB}YzirZewuvV@;E;N6eUzmRfjlkGUOmSb zuN?`6Vd_ub#8rdwkn9@)2^RpXM7Qoq>AP`)(YlBl%n`D1YPDff;kzm;q*QI>9E)*< z6Q4f@Tx;6=3IExPZe)?F98nl zY?cgNPLyHoSwGl@KL9E^u8_y$=jN{j-TDLU6vKADLp`AyK=`=Hr5@kNB#siqUq^6r zkSSR9XC^cH>>z*`h*Y3dX^UFL!R}pY5IeywX_6I7PI6%y2< zAvj7TI0pt-^kfug?NOJWi8?c!u+_{yOZCM5$~5`Zo~20!`X-#_q&a6nQW;g*SGp_T?cSdv7oFD{OzCLTLKR8dS$82x6|bB zz@G+Dfq%-q#h~Zr&|kU5=(1E#|F~m~3q>V|U=-RD{n_#mWX89OC=oJFI@#WQJQl#b z$JVYv`B^AyUEIZzJ_ysK&#b(Qt}apur<1=-ChIYtv=~N&nO5)KB`aOc`y;o3@icM( zx=0>I7Y5KU+-GTl>T~Z7PRw_aMC(bTg^loIusMAPPy;HHt!X&}V{ zScS!&?I^I!@RDps>@@bCu~Ix9Q(l`Q|ALU**!WAHnUZl9ruDZ+3WtP&3{)S?K|>0C zrl>_o+(9oX_fEizEE|e!*`pFmXa^GFMM4XoH-Z6TV43O^3PwZZsS>N@9r~;VkJcMe^In z*VLFU>ygJB(-MEGg(;sk$+{3-DKPJu(0XT*oiuS~?6c0_uv_5vzMe7k*6qwK>Dzg3 z#jkqa(ib0;CwX+`p$j-7k*L4Rcsi5ez5n>~VQSh?tz+dAl%GR*9%%V<`@xE5aibiP z9X0!#UpL?2sg_?9b7}HO@KHohID()Q6xb%bB=XdT9c+SGAoYgoT1-{*OUR?>t7ozU zhFLfl4&psB$a2oyN%LOn38_307-upp?7rc9oLO6t#{{<%MjCxM6ZVkJvp@@ zUlAGuw>Zg6seKqCi7W4hWkT&LHI}^WGgnU`{GzqfddErJWH1I44$pMa2GN(!o$HnQ za+48PvF7^y_(jB31-!pO(ZoJCDPi`v{}J6Z|NPFo^%wO+9CtU3=+bKh(U{? ziP&2miN^lQRDDpXoH;nK*`UXnCr?#kanm;KHhUJ<79MJYzZ~b$dZa+&6`=vL9b*3De+t9g~uWws5@v^j;OIXF2vy@V%il%LLRa1>xFwlcr#UwxrL zye;8!mHY&RLNpbq=Y5+yLym2<=ApzE(Ve6$IR_~vuflddvbji}-w`9ToGvGW@5by~bvgZGG85PWGQ(rXx(cqjJJx9MnWQ!|F%tfMM0sFlZp?0PG?z`qP0vH zkqf1eD%~=kr8}><`#tNdw8fD@y3@UJRWr6~AJ?lkSn-St?>{>wK6-Fpb#cF~mh_iQ z5o#%h3=hx24uh6*t`{UnIFeyTW-}fA+uOuaqhPAQg2lWEu8O+VTyOc}E`S14;Y(Z? zsyfd7wni^a>LxG)$SHpSpL2@WBJUxL-GBB=Zerg(qJ3gfUBC6%_>Yaa3^0FzeTkL*>axONYRqbH0A#l@6&K3 zsUZfzSw2)zR5bs=ldbJL2l%DoxBd-hh5T=kR{k?U?q9{Z5)2f=57f1_lK=@pFgj-- zHJIbkgVWl)s6qcwghe@V`Ue`7fSBct|g_i%1NCgW>%+xTt>tDDcj_ z4=5{OB8Frlam!S|-3N>jlwq{$RGG!Og~}h4?>r%wc)bcFj15#Gh-}nJ=%Jwq2t5jCg%Vl8>Cet4qy}D9i;#;4$Qrf_~CO-)rfN!jRP1g zO#{zFq~TzmfZG)DH>0XH?*M5eG$DQfGKQLB4}csJFeSSgOaM7-0RKMi0j-uSqyH{h zBm`*Wj%JzziU#G-{%y1&K;yi*U(UA9VS^O=5X#Wesu*v&e_#QQIMtz5Vhi4J#sn_g z;Pl&zpY`HO9^98l&$XCQE!F_;q^hL^BTVMcd|Q|T6fk<^gOnZ|51a8tme0R|rXPU0mD*2rf%O8r=njZ1_{pAJY@GH_i@~MD-k?cy$V4 z5!S=Qz5tw-1igI+@QyEnp%pqq4Fs{kTL7=?1)ZX7l7NO2D8M?^5HHbicNtLH76XgS zZ}*{gh9V=sX#1W7IN%}e0db(?aWyN!nmbh#2xL4$@ya1G(gCZ;3>!`IK24k9`fj>aftgIyg7Fs|qvlu{}=$HGA za!`0Z)V#a=P$#862RZWxkahx?)_iP=O{NW2e=dM>!FIT=YQBuxb#Wd zr}t7Xopo}R7=cbx+%FlhO|cL01x)!s6%5TXO6=fPHTg^J=V}T-EG(FnN^6Z_*ae8w zk#%oPa=>`wLs?zihiNV-2SB~SO&y$Ho6RJEVGHXxt8}gqF`EMtToN*nKZxaq{|!Hp z$G1g#AefXz{^#FP*(a}sTVhSGRz+Jqr;5Hdn;phr;M~eUEjqgPAEmM^jYwcKoej1H zx+PIIEjLLa5}2ju2ez_~6GvO{`id3-y)y#Q51^zF^6c!2Yd-|`3;f}TrM;us^?N74 zJPB8Ii!T1~E!W0zyatS;D&BpPHh^656f46k*U4`d&=>ipIA%|upO-rVp}Y>E4s;sQ zoXc>d&U5h)RPn(Q;px{C=%rS(0z^M8A7;`*T1Nn+s`W}3T?g*Q!UG8D*1rb3Z4U@_ zS|r_Dz~yL-6u44Pd^C}*c<$#Xp4nZ}=IGWY(iH{*J|jEuNqqTrK)+Q_2v6w*W9JOc zBa6^i`0S8S^I+8LZ;fnM>s2uH5%owuHKj}Q!%tLP;$BKS?-DZY@f$SVfL@lRw~2iL z^Tl2`5g!h0MNA=XfR^WB4EjewI|R6XdpH?lw+u6aEEr1zlQJ5T6?16`Ql4UNUnsqO zR|C|vu7v!f-Z!+z8~lAk2iV(s`I%GI>M{NjsX#2M7(^W(dlJ5(A}AGw%%B5+S%LT& z5^v!PqhXc11DVhq@Q0Z;k=_CeqRL<&V!CrVP??Q%%|CG!mcgRNrT7Vd1ahbRp@r|{ z?+vy3I*Ae({RNi}>-X?1Kv9UYgC$s8ZSu%Orgpz-TTPH~m~r-sC}E?g$vzC|#W7EA z@t{hV7v&crL?5=F-wxR?>p%?rN5t3zLIdehcU1JF>70Vdwv599hw`h#<#@Q9;%;LO zhxh#$eM_$s=Xe|eFm?K^qPw-^YU0YuZ9hAV8K6%?A*krG+FV&uP3*5PtnvoVA6 zS*!e2-Df2gOd%?9Ot?eN#lD((dUB(p>QseS*E!8`{Db??n(g4)4na+I;&qUNdQdZg8%Vx+Z?^*odE=!;_D zYK)KAVzE!-USwy9pgB zcjGWn`CX&)uC@54PuSyv9xD9mWuvI!)QGg=Y&!bc!}qkpj2OhUH)b)?2ur&%((NON z419pFA`pxyw=?Iafbw9@o#wYe7K*3V;nRGJc|*-zt1%0S+EKvh4eV+FrassBm|IQo zjh3N~ccn25td?rDpVl>&NjKP61(O&GOLHT0u~~yYnSNICC^LJ9wSDVT;J6ga@VL=p z&LxKpYGSO=j_JL=pe3%`v1Gib@=Rtbr59)k*P3r++up?|e|!9KF|}IHY|cfQzcu>t zt>3RnJFsO#y=7PJS?~H2HLt#%;Qw&VHU9Ut*Yo6L#zT#j2(k|^b(dr?-h88^*m{}0wdJy-E&e9e`E{I~>(Gji<|diE&HQ)Q z$8m2ys+q>7F`j+?bWXz`_>5pmwpk&^@>CnsN`0+~M2y8-A>$&)=%Otg(iso%UCPq< zBWu@sEA1xw6Wxc7>f*pOm3)+ov)7JkH@b_TqZ|ZhJQzy?+M{&jA9(~9HT77_Yr z^V1{GN5*6`)~{{0Z4~%@+EdId^|xj~uxff@BfKORjU5_W%g*2D_ldC~C(L7jXExxn zK;%fDtXZv>!oIiWalS5>G5KE6oJV>l76$2a2YPu8P1+tX;_PtDw9(*i2)Ef!4|TyQ z-AvtstC>IMi7W*#E#(fDaBH4tvFH^B2~)y%;yo$;IC#dnbC|#0E8qiX02fb>RR6td zF0Xz$mPK#3(??uFD(?3?@sIa{W0p0RS=%Er_}5QiM4{qBBYf{8CC|B@6L1{vRX)b! z!S9i7*424<6qrc1@JlpD&B#;G(M&KCVH{gIFgvxuB}qrthuqb%FI%>llz9zN*;FSa z%|Au--1#yN!%-fdcU=U{MX)r8IK#yRd^3!(v4tX115A<~N zpMTG^hnJ}-drF;Y(;0Ghq8;^%)Uj_Q&}3yKux;;lYPbyNQ`EUI(x1QFX+$fo2Qsck zk+c;Z)voy&semUC-a1ZCQoK6O>9-h*`M zsH5pAcwRp`JE5uRBDNrCFSz#1c8-;se<^~_{l@@)y~r`e4n4k#2^ObLIoPdehg%GS zrq_L{N>`l?gV&BBR#5W}T!J&#&CQ0E+f?Z)cYKN9@9}&0P7>_fJ51V&JFV#~lC-*zh@_w%y*0$fL57$%nr8u9B zrLgCH8KsVlxWQyzyX?&F!%M+b<1x-+aRLpttT)FUEw*()l}_ro0hwV{I|_mW1hz1` zhe}^yGtu2wvd+-VgeCz>qu?Jcl098K&QUROq<(8F_`~pYD8)r4_&+398uwT&_0}B149qnT+}% zo^E>>*hKGt@R$jK^Id}*Rdp5&`m&TV1yyb*)h_qcbq<@Si)GV300QY|xtH5)LlZ50 z#8u!@flM0R7zI|#sdZvL)j~hh>pei0>_T7jE;_AMN2Hp0yA-TkST3cw$b)btJ`QnZ zaaA4#@goV6w(2;06mCn{#K6R~eGvc9QeGgya<2Y|2eCc`*uh0q243z$6J`o*q!%;EJA_Y z(2di8yEHn@;GhTedT40Cn}1`YnW)9$1@A^qBKa=~tdiLxQ@%85i=Vfwf;fqep^6CK zHU^LFsU`6%XK}*pTC+?K|OVak|3`M__tMQlx zq2hTAb$yj~TI;8Ud-#sGzTmmLP^Y42Xh>Z6&UY)#Ccp#)E8VXSsFs=qR zChf(ZH=S#J!K-@>`s!ODcoe0fi1;I}gF!G2F~r4kOPVVAjWSF}_eEGI?ZN2RxQ^_& zxWZ}Nd74oYp?hsF`1M{A3$2B#vUI9H^I2!Jm&}|lw~D&7p<@UW#rWYxsY^Fy%id}~ zemu`A9lNjl6w2veVD}TB2Mx}pJ;b#fOEFUn+lInW%6n@T@veJ%JO(QZEYyIN^YQ!K z2#Oxn6nqRV74&>de05LN1$}0L?RX0Jwzo3ZL-hzNdLE9%XpA5d9^qmPi-`R&+L{cN zW8w>9TR^Pvhw2vSI)V4)onMEQ#aZs}Bx!agw5gill9@0){I;x<;*DR{4sh)*W`I&^8kP&5oCc4Tx&pJM`R9<_gVFV~TNgx2 zskxLmu_H->9=BSPnmiYG=U@qY5?;Vov0VE>QwJBc*kf}3|tM+iesg{DSS4QT`Hnj(QHl1dO= z6<)!AWwOQJcA}hJ(d)9=Wm=44a^qmK-Yk~`pbMya%)aIq+Kr@GEHLQ5v`smH!grke zF>616lRqt~89`Zo-^V{~^~vfW^x)s6#KYajCD5 zSZ6&kBY75Sq2HAmW+gUg?^tADjcz$rl+iYNsi2 zF}oy|!X;(V_J;h0pfMu={-}?5{#7m;L`zFyyDz3N-c&LMXM4VY$mjrKJ4f_0YAOj<`cVnA3(h7@03I8pGd=w0efUcXrS>beXL*XA}e#@)WMr|%w%dsMFEQK+KT;Y-Pe zS^SPMG`%K@CHo=2-i950-V>Kii0*OxumEOZtoZ%HAiGswA&P1YzWvY7o(JQy9Vn=} z52N0(r|CVQn!WHqngEPi8AoU?_j4&OQe*J!H(GgzF=MLM#1WYf3pAKW?33n+)ULzP zg+mptEQgq;gF)-)hi;h1G#)O|=di8VnHSM=$h6NXHbP!%G8#}c@n$6z-^r5G3qemR z6#P1+<|&h@dgK>J&O^uQ=K|699eu2VVx}}$*7@qUf&pp$McZcBMUi8pf{7Eb`3^S& zGP!__*0!z-CyOymt^jQSXvlGdT{?k zYxzH>`1~)h*uUZO|33HfFTUu1kb(aHMo{|C&p}@6-;%j!tif0hrY(A)5QF6fL^jfq zGGIr+6)y)B$8}Jbf<#X3fN2QGzdX$IR1lic4~Zqor9c_K?)?a1IERo11x~*;dcO~- zOzZ`5^N&wJWH)yQ&iC(dFIAf>gS}_+-_aZj;qR3!EiHj$2cvg0Y*pa7fU8(bOAEv} z4|IGN0ndJ*)^&ql9o)ANX=N92rj~$&b&#_dy8`3~Aq0AOQLrMvq(7^cL=6lU~}UJ8X6e-!uYbf!t5{6Z{scmUxU!2`AbTa^Cy7eOUS2FQ+Sr?HmTxN<&mSA@_G;kJXO4%nrL3 zYHiTSE&z8)dZ$+iZX;6!>W2UPW?&6C1i+DI7J&U=T{IG%j{^!haFTsaA_abom$e?M z?0P(oS=Ru$Bda7{xItOd+qW;qtDT>(jsr;-Lv{_~9M6$3yfa5RJn&s+E>)OrL!R{y z5mASX*gRvv*==VS;C0E#Bya>vyn%2WARzd{b)LwkIuBU&dyiG5p9J6IA|OjP>txL$ zVoI}Mmm@e_1CCZX$1)Kh6M{_wg_+E401x+A83fo4@hXKsXB_nbSbgC1QSBrI#q%{^ z-xK^fOUfGb_yL93EuqL6^lvxICo3%pUF^BJ`13s+KwxJ%f+-7`r;jU;&rFbU0{T7! z*O(GJ@kS8h6(F;m={pGh6XK^*aRt|Q;r!^xUYmLU3y5ZSql_8@K0pg%?F-aQSVuOP zeCse80ZMQa#41nFskkrFf*ga9TLnn(NutiiXI6i7t$-L;1Mmp7FOm?V`j?h9^t{JD zQ^ce0hdIMqc`EVnC98lX`wNt!bph`Is)p5&y8`nGDG)N22!jM1%keHyGe8Ypv(M(# zmCXHgJ@>-j`5>Sxo7LGssJRfTLM1spi604!_#pwI=l4U$cd3C&y#v^vA@W6GDSgRP zr9d`UO(7!uskH&T7l4tG*TbNykOYjjhhL zDm5G*c;^Oha&*@_#anIy*#!W9FbNaRJ5b~Muvn;}bls(y%e}}HIxe*&E_oY%ZAc0k zgG`;-qnbUa?2z~qm;r%;vj&U?!Qd(;@r!vC-W?YW(7CF-3Rdc>24`Q~wCjV2-5kP@ z1;fi5?2wC60>wPgT0sCBjt&{**<;M5{`(vHEpweSF!Ru^0A;do&8KlLgLkjofu~2z zi4Glx+mpAzL(o)&xrstJt$f>8R|C+H-`JWgpLr9;@Bo+M7+A2i)a@gXOHF3e^IGR(L8T5$!8)L3>+cV@T)6i07@An%>v9{{*I0dR=^ICgp4OpCw^~kf8`1ZvBQ$Uk z`6>+MI6^ad^aZbjj9o-Z$`6tTu;lN}eD+4b0Vu_>2*Mo~&K;b`;CKi`9o#*zI}DQx zt&Q*1t-Q#a1Go4qO z&G_UYL_J4v6xffvnp3%C$C|q?dvZ@sh&2GQY(=>8TcW=$9D1iX;?|4bG8IF!t$d{p zW>Nk9lp;FnwJ`jGA)9LQ?Fd8lF^UpL5d5Yra*`KAs!V_G+f=%Q6hv5SPFQAxjmH_a z%fSND{$p)(uLOc?g^6={RHx+p)(S;>zf$H{nfeNcNYj>X#Ae)YVZ_z0nB%zAWt;dr z|ME^0fw6qJ`R}ela%E0cd$*Q`H&!HL5r*8+PhTr44Bz1hiv5#Z91)6PNZQZEvdJBs|R($8w+Lc819V#Bjzsa2&2aBftCM zfhU}iolgv0l|eexbthpEk+@szw{TKEn~+;d!<*xK&`VYDr_$KlZ1PF ziM$?<)E!_>&MySJB^`l%%=0eadGkWI5vJ5y4?(E7Yl0_WFu<7z7Ov89kIZ~m^Pj4S zS=52KMTV{tu(wPB6I&@RE#*HW@{yTR6r@0+T!&y4U7Hf9Tg0sb!?9;XEkqh#WA%}} zt&^_sE?*@0t}}kK(us7#bYqF? zse_n-#9wmcvTV?w!hG_L(R-0H+ni!!=ZE%#FPfpch~5+E$6MNjL%9ZBjC?WZWGpsa z-tQ}Z0z8yan7VJZr1<|zfz%cx)t(2gZ;|RO38s9#7no8R-?FYQz^{yRAoruN$btRH zHH3ZM+M1h_ljS`h0hwIo9gdhrZENZ&HGVc2Pjm^_}lfH3!kVTq&8#^7;V~5!c-VQAHS2Wgom2MnS2?5| zelQWb5C&AKnuf6GEq)wweGu8Wa<)gWv35jdv+vF><_j1BtL}b)Y1#|743vAC>YK_9 zT_vIAVhY4AL(X7ZA_PbZ?q6tl4J=0**4eQ1cqtzDaYQTd1Rk9nk3V|O%t+$6^bafm zsX_(NhOGmRF`gFyz{y5ZDqK?kGt!=}_XZ47d8TFrH$OJLGppZ{29vcOjhw@pE2s2= zPi~hwOuoA`-cokP932uO2-+q+JwLd|f7G2jwE6Oq9+!=O{d3`R)v!-avgh--f^TlI z#fe_-BKQ+}^1%k}rcBE5gCP5K`%UfGr3D+QvD$Xn8VW0f-Fp&#ibQfAQ~_n;CGA?2 z$2LGaF~RfP%9Pn_;)~O@?r>)--3I@6nzubFm)dm$9(*g{y_uQ@lFi+<&pp%JpMj*b zTnGR+z#9?L9-FHL&-=ml^>P_d^0`En7s`TkIGZ)9$vmxXATcy+gZxRwFCQSNgJi6Z;Za{TE*&7w{il?8tlfuR%7Iz^gQ= zcDlHYF(PR2lv(H#6lRFYQf{maOK1yofbqec4IbJ0=2 z{99Z2&?2M`>`Je^XlKAPB|8H`LyO#(&+g0g&h=&iQ7Xt{`Xz=nUjeCghx6oTY%sS6 z-o~l(1F)^mRkemRM3y*@GF|e#M{oXgvJF4M9@_WE$R--nVQfE!b?^`x11PEq);cai zt*#G;F!a;+*G9T_zR`59LJjHrR*H8QPk?U#{B*<5L?6)3SKpRDCa77`co9$925zEn9M&c&{kef3TFlIHb% zpMwtpzmE)JPbOMtoILKAjP1n!F5C1hnKKwOSg-rCxjyOpm3?BK(wOHa#oHTjSa!ow z5u}D;ya%u^h91~My$zE%?{^%%-~6z7J&l~2+~%v- zl;hB(a+3hik?!4K^(|<9qGJf0wCB*I!gbl7Cd6sr1B{j##P0Jg$t!`D@IR4>J`J~L zow|&Dj9BI`h&tVUcl`_e9*85Vg+dH&%CD0Ra^P&!%K6+c;e(XPW18sEvw`vUq zQDjDS!e3-&RdV?(-Tr zCS`{=3aZKt{%j%Oi_6%t2NFHq=;ByTwZXzC%z|C-m(b;jhsjiSs|V(jN2ymr={hIu z;{cFWPV)Uu=CIw32_d#7LJjA-)tB48bt_rU@FC&4`+4*--Kh>3HXywGy~Wwyh(xQl z^Qa!GIM6y>V4PF-do#rNSaP0+|a1DHwvJ7)%;tEwO2e-A0#NAv3a*z+xq@~tE!#@Lo z5C4G#Z$Wx+~-wn||v{aYgTkCbw2_$wAVqyarIev}C2!+)uF(O_~v`u}DT|S?I>oPa# zpbKwJ32pR?7Q8!PAE~(Cd9n|(+FQ2>&z7Ym4!=XE-Fw%Oto`6F3^N zsy_-`T&cGdedlk8^14Ga=k1^$gHr*aue-_b2$!>boszmq;Lh!=IPPSP-KbkHhOJl! zWW|X^pp+lLmbK*sL2Pr`${q0|Pz0%RtO^XP^^{Eb=HAwWEJ(maxfqo5UdL*EptAqe zc8l1fO{=5L4~Mxf&Y2!Uocy0aP03ePck2jcj_3dt6_DB~w)^civ#>KC3! zYN>73?-1Ku7atH?Ae_{SL^Zbh7qd^PPv?d> zwG_y$ALwZW%@3hzu}wN2b+Z(o&&EwAEjQ6T1B2~eC~f&yC5}W;kM6&5T0AbAe_ho5Qh!}iXXx_T0Fiio~ll>jP(bMAH>I{EC`@v`iMP*ah5*bIO>5-o5r zliE##-+{+*{R{hS_k6e0-(Sx@5e+kb_1*knIlHKl_p+YJk;#m;HCD@+fmNC1#8g(B zU;zUfy(jo`QXVVWVOk>iszsyBjumKirP`{K`d($Bk+& zj)K!@@xtpw0OBe%R4%Tbwif4%EEg$!VaVq=?h3j;VMX&mzLraN}T!NeR3^Q z)sR)}PqHlpp(Hg}ZF<)-Fg{;XZ(;_7RNV~W7WIc?x_Y+YhX`L&*Mvi!)QfbB>gWE< z#k|te_f9)njnwVeGM0As#pD^B;LV+{gA3Mn+if=pk5-9$#u^@~xs$!|<)!!h5EOef_j#E~X6=JPSL`opTF zy^x2UYxR;MdyG{!yE2<(UX_zK&yl&1`M!C5@?wk(w_oZ#sBDT$jxqCK-3@%);!+jL1f3r}cy&UhYM*(@*X$pSdMzvMqozNIZ8eEE5Q zu<@gY=yinwV<-fOf#lUUfNUv7x!4}kOE+u|SRyforiM-iZH6}lOFulTPy!;T-EW$@ zFs|gZ;e4|BME%FXWauHbpUW>@csit+^Y8&S(6y;^4ogKJtnhbhSeLi_!Wm|dbE{CS zVxe28$v8j5AkDRWEo-1;SACI+O@qhA_}S_pzb&=W``nRUk=#k>oy@nAWy>_QY5yPU z-a4qtJ^B|`x};k~y1N^t8wqLYHfRJT3>ri_Hy|xag9=C}Akr-YA_!7jP*OVH^_;oq zeeWOlow;*=zk7dkXU-hXoO9fJ^X%tY-?cuq_H=t*zU9?7Ze`B~v7al0AK1-V6>~zX4AX zQ_})DX;}ElD?F5lY*7KN7H6w@*~TK*0;Plww**yO(XUHVdM-Pd9O}w$Hi#rnz<5wErd}eL^}@4@6j0U__89 zvsO!FW^;kF(296($SorOnP=;dTo(x`l^(VZUcd4iw}>1JG`xRkjAp6D(m&V6 zv3ryu5&5;ASuSqg;U&?<9jUQ{&GnUID*x7^2dZQDiv z9GVPlaig_q>xwX$RP*NuJnEgXcA@2SbWW;Fr>S4wFTYS>EjC{|cnbpSw zGdTKOR;Qz5GIm>kzx^gP11BlP?5#BY%r=#>#8|&`>~^>pHWgbQM!i$=q%Q92ZVWCJI$wK8+6F|8K%%bL|GHq`kIs`uFd;cIN)Oj;cHkYd*vN0?`e@h=aqKr!=qZ;iUr2!cR8#9eN zSMJYzw7DAa<1vO}Whw*52g4rqv3_4tG{esnB5Uf&=&lSiBtle^r#oycee6Zmawy>o z^adPG&>pR7=K_;ao#1veUV~oe;gzOqM@0~ziH2s&M%zaHW3}+pPCKPI;^^l1$2XTz zb#<|b2?IUm5`Oh2Kk2FP3hgWjgTsp)Yq@6S_4g?U`s0ROieGGZqzErWRa(!BQs zkvT&+$yKlCE<{oUe%dOjr(d`aXYoyb$ad0JmlDmqle;lr@!&eZCFYC@+@yj?(2)Z> zmd}>#+V-t*6!rn2e(|uwXVZTb=>xX559C*xH9||B)WTQfsO{Lls1|kqCfiUSrB|6% zb*BtvRZBU#pdmM|>L3m|we59Ry3n-gMchovgjWw%E(#vWw}?%%8KW^9>US8#R`yRS zJUzA;M`a6xa4op+=!s-9{*yhldlrXH0z&JcBnhocuGEI(NK*$RFiekHHj_f(v`-a_ zIp0me^sPutU!}aS?wot-bW04~iDPx+35E01v9`Vk;pdN^%>IILp!vrWLOr=Hm8M(m z_^<9g3wkHoB9#BV?d-3hjKaMNp(SlV6DXT_Wcbt!S&D@(rfG?kT%TIZTy7 z5;J)eIBn@3%xoW5k-IX}h4C`KlC%Zz=h~^xKPz=TMcPIn_o6})rPUtL<75=xRK2$Y zAw-|@xQp9LB`+Pa-BK{uI&t23l+03DV9}d)8mcS#6>;V{TKcyyPj!5$xpn`0Dq2Nt zP5Dj2W*vWN4-rp`NIq3xBi7c@?oyoYurf`~1*0F(=!b{iheo`6Hz@An!GPpk5Re9F z8kS>9g7iA)hD_2Wfg14ZQxG42l~jBka&t8aHh;1Ms$0C;R-!O zONmi%=;bB~j=Tkqt3XDQcpOmX6^X~zjDsjac&odRM!~8#?&|L$OOF=S_q(5HY=#r5 z6f(4zdpi0^Jp<}^TMPr*#D)Yl#ShK)#(6clhZIgZ2KWL61L<#dKqs!}@rhC7?EMhI zKDDPnz4LCx?x!tIty&Vw3ZnSGz?|0bU%|agpDDyC>pspUV+oZ?Teg}F`1$O1Wg`b; z=?{1Eyx~C#JVcqxCk=nwXj&8K)!9|T2lv5f!T!)LW;lrrx6+kSA1_k`{2(edv{gg( zwA|N;Mv#DrCDnD5y^*TE;;9%J;T5dka&-g!mNy(udYK7GB9jXH=Z^C@i*8txevWend3^xn2O zG<2IKpBJj?$4^pcqv9XON2Y4#qbF1(l@ht-{^FcJ7FOZ0DSm z>7qmsuS(P2xS3UF+sYf%B(4?A7P0w+wKhQ@GwiXo=;GbBblj&=FWa(} zxr0Nd@kQZeQ@P3gRf^JRUsBL0wn(Jr#RU)Pf=I}_VvrXOwQtCp{<%ONJ8VNv>e)Je zEx=S_C26aQL(1q^n6&i~vf$Hb#doF18ite;WYs|-Ed)vUqQ|PJx`(jW2cAfs?$A|F5r(uNcrx~dp zD!AlUIdh4M57)Wq|GD<(oid4h%H)%;)VKmj?mFyiel-t1`A5Y$DjMtcMjiO1>RwkuydmiM|>oK;_`&D`O&PUORMYrK`asMVuW|JO)o!xT4y)d zGV&nII_WFrQ;Pg&1&`Txitvlq@(l(QZb&7@onxxkpmi7gQ**%$AAlFZ z$c4wp;Yc5|el%8K#>KTKO1v~Ay@G1^z4xz%x4X+gKjZw;$i|i zx1$*;PHh@}`A84e!Y{=IQdsihPRrz;z2nvoesnS}1mKAMH5OUhWI2nt>)&_V`<8%k zG8WsS4!5Wk`B^5lxaKqA5}O~PRsAmf*e^q?45yxQ849bn8Ez}IsD1mTzFjbWGV7Fn zOU+V$O}|v*%oDnVsx6XJYTjLa-=^JGw1)+UFtN?l&2Gl_`&Kly9AElsR=V2y5OhRztr||v+-&m|W;)(+x_M6NWA}+ zO~8CO?-$mDYqOpmmsH#6erQhTV32+pU# zkM39(M}FDu=3M+67tWS|E_=gPahd3bNRzrk$M9woor_Ku6zn%}j!K`a=xjsT93w zP}86eP2dNcrXdReEQqI=9AJ3lX9^z22jpjwiqOS0_{qlp1iu>j$xWv7h#mPO(Y6?T z$WJXS3R~po|H@0;kVvXm0EE>YdF3Tj7&$e#IX;XY4J_-xEAk|GJpSMJ-v3h{-^3PT zl_2!!8zA}xZ=BCg4jI@j2q%Ao4?aK`7TSVETaDM_cdBkuQ4nO(HG{;?l^t17r@2%!?_7J~ll=7=l;*UM)u_1t?XIMC5Tx1x1;OK(94C&T@+iy?4}ZU*aUrWH+HLvd zl+5OK#kSWA@aXsJwS54hJFDgGR7?O%0%A3lXca0D!$>p(@?ODfwI@3MFBV|@^2Whi zB2N%WXHQj$TKNo!Ln2rlL2_#z0=T|+*O?JC0!!vE;S|Mw* z8NC?pF;37*fRkDPq7}@PMEdnbl)c-LBqd;7`aeoQI4G#Cbdp7g4q<4iOSty~x<+It zb5AC^9drbP<7@Ec%)xh*l6c422wgn~UlNQV4`5owW$?Ukj3BbB9}pMHBgtFzwe7`FGc%lyJhE*|X_lk=)V(He+;4VeZ#1qj zsx4_YgM##ZpTK)h-dqrPfp7+f;uS7t&U>b8nijggDZUK|w^N0->rj&6KB_|KiJmSn zxPlD#ncKAovmga>D9!PYdG{OkufTsr(0N$e>wvteNd^6_K=^tkrd?Ujv?O)+X{=d~ z^_y2g0tPaj)vM@(x0CjSdtFiiAXh6ip4Lo%2XnXrw0jKcDbEd-r8F|&-ngas*-4-t za)9_;@NL=#(RMK;TARb@@F2~ zk49*gEO1&$FERg^FSyYR44|lyu1@>SHR!9F-!-7_40;cy#A;);2O2PsGp9$$Fv$3> zB0R(qpPk~k5HCf5=d;NKzsUrGeEQ7y5O%K#5(z2SfGZUd_Ovf5TWb^9mXydF1|+_P z6-nL#flrUE+l-s#w>P)d^}G5v5%2(hRhz)2)LlF1yY^tT^ZtlUGi*KfX4o`Q^c*-E zplw1yT8;G8GD0P0XnJH}W|JZPE}f|JuugJRu6Hl@VkS&jfnC@20UKBQ=(b9Cv)F@G zSJx(49$D<*yJ$z0(O&IixT`BM6&A%Dl0NR7eOK+34#{Um4JV+VeuKhbI6Sh=uzOR+ z!6W}pa|7^)Br>Znz{&8OJtYtCQHBGQy7gZ`iLk2t=!7z|C}oz&=0=qun;1OuRp`Nc zxMOP_LCgX=1!$0B^Y62Y%fPIO)B*)Mz!3u+`z9gdEs zLJM5j?kfC@6P1#=C2dZ9=r1>zDk`g(^Aoe%r*k}61A=qid>^J!e1QzK+~E<7x$vl~yo@yKq3s&Z(Of6Ajv=>c}k zKqYPY5_Vmu!AGtYBz^;q38Oo`!w`JsxnNAjIY_7%qj#UGwOS>q$hW8prex9J35VzM zUE=@&Fse5hM_7TTU*|q3fHPPmNH+59F*3QWa9q%&J#v7Wvr3yCWle?Jn`8=z?D|5D z`{8*Q-@fkpV2`l&Jy&Y#$af#BBi*A;A;0G9y&xRaFz@hXaZ$%;gHr1)!w_$*7*r|F zIjX7zIBf6X>|fo|A!5yw-XcfJxS1qY!&fgg*24m)Jz0dedr0LHMxS3*RN$dKM4y*E>zgu#9Ap#K6bo;djan~m|b-;?FX#&sIM5dR(JUATr7grug8Bf|DY!F$ktrn zj4(rzbJgZw>DxHjKMy_iniJ%#l3+*`?3h6V8uFoe0eD@FGd0Q1FuN43QH^ARDf~dn z%SoS;d`4YHp5^*ayPHb!dY1KGQTyY-L&oiRJ0^kb=JG1%kGq=mnzc6eeGxaLHC^JH8_tL8R zqAJM8UE5?Xe)9`%>faL;-+=miFd+W5JdtE-v=ENc@E-SN55f~0Y$9A(o{;m0?WF0R zo>fwcW89ZfuQ8Y3wS5B3u7A@3kMRrtHu_X_z7dXg^)l{{P*0N;oZ4(;e(KAvS1Y6J zPeJeAZz#fS{^R_nz2f38sDAz#elyS^K$=KquCO;Xe0SRC;<-teKF1i=y}@P_XjYWI zQa50F%a5wX=g3i{5T`%P#&<+joiWgH@NV6HGKtT$oxi*bbKQO&)UVP!+XiZEmc;gn@$-GL;DHXJ<&Ygb*O`nMNRc;!WN9;>#m=C`Def2--vIdrU0okZp-G;|P( z&i7EaB;0K+8h=!gEX58|;{Z0ypM=UNzntMft5RBraQ!`%Xj4eq+=1-DhaN;-S0Ap| zNPhPngF{&!x)!AIgRquoaI}xDrfLLdHeQkTcFZWcbTzAZ=(}5K4uHcd&Y$`jeV)d3 zMSMkPgRl9?UtA*E8xYkyT=g3i55DfZ_EVpG4=CDNA^IHmiZ7`&75DuEi*o45f*>El z(Vn3)3Kdf@s+g4jj82rJ*&#C(g3FgSd#o|=BdXy82}k5gi|=WY^c8u5+*UIf=^&1l zxW1gj|CO$zB5GsN8M?nTQ^wGa$-@SJTv@bW0CMie+V-Nm?chZ2_x|j#U*2IQFpnjR z@9}}S$|q!{DJ6YfHOS=w^VZ!=UiKJL{(P*U)qM9AC_vXM}1d3{r2E>W0Ugq@-S`N7&j?CUXiM#ZY z%0+Dl{KFRK@V7M`DBr|VKQ2rgHC?hWn?8kQRU%$m$_x>g=?pLF@_c8@8IHJoPs2fX z?5d1L7Ft*Gdy2wy>&FTlL2?<*S-FBiuW_rUnjt~>j>dhZP<jik8a$- zd4-d@rO>0G^o#|q6}I)6}Q#$dEEs8_x)q$E2@-_qmaRA2P-UxAryepLoErMmZ( zOO@T}6@te=TUGlkG5HIXVTK{E50I!fz^#DIxY!^C8!d3b4&(VJhc^Raa{Nu3^w5+FG zo`Xux>&Z>_%mx=tABUIgjFWMA{8X;S=OkZl!NedbxL!b9!axl2El=vWZ68NM|hq5lR;8+Ma1*;8J_Efr-t z#*L&fj`xc>DQucY4}}AfO$fCEaO_lWD!P3KQ5%yq9EDe}RxomW$&BR)C!WiFlcnYO z=$GXS_N56>`fKo3fpBx`YHbo5+T)|~-M=ZRN68Z{IrnF!n^%Iw!$~}yLM_aMVVY|E z`}>x#G7?y4s=pF9${B2>oB^ zLkF`ZH{wJG&B_!jM3HA54%*-ebCcy zD-2*r-GvcJDeV~M-FQ0DWf+fp&&Fg#K}ZR@O%x2DmUrJ!wT0}Cs6$t`>Gk=F3j*yF z1!?hHH3%h5@Iu38_H!&d^gYzg%4yBSKt#dVECpF}NH7;nNn1@Y+=6T@cH$){MmOv3 zOr3|0ufvE6_At@NL3p#B>DyJeU}F=EDu`(Mzz+%eN*6#Dzah7ixLqpd_(DHO64oS_ z74PdY?|-v>da3<(?HsU5u%YkV2DEkNE;(-i4X;}skQBcV?({DfFxQMkqty*az_@;& zUcv*GMr7_>lANgqP0yeDF}?dUUg~CNAlJL%KWQfx2(<||=+SBqDjeUDSp3BQZU)iY zM4lqo6dl?QUF#TtJ>W)M2Tdjn%r3O{Yh$G(yrSj<3Wx*{lyLSi-_mg=Rk5wl!&}&U z*mXevlNAnga1%_o?IzGo|NI1dlH0&F3Vl(P!K)f);%1;~QrckmSw0ccAHY?+1sNEZW=Z-A3p(Iwd#<`5EhicMp6qeO>p;si{g2NZ(c9*`TU-5UJ+%~wWf7to=Q zsxWGxenlMY-r&&7c={F=1HmokEIlO>Zud6rZl*jEGy&^48{;rm`0)FXsUN_RU4SM7 z;m8DA=_f+x+@45e2sk@>9(wXLc>z0gffR)NSAs`1IsG*lWo)cf$Dp~SutwUKdF)1(o<+bu8=%5&uffoK z?QKsi;5r%WzK|z5FaHG*wAB?t*kA9Y3z#ydJi(ZTsPMY-GMw03*pAtM%fa+E^(7Xj zBzOj7PyS}zu4I;9{sgDSKwhnO_N^pfZBWLUbn7sv3TiEFQldfm1%lPrW(TmDJK=F8 zY^mz5%(Qk6N8ZaCY1l-B&mbmnGwTF2x`OAh9Xm!r7b-`p+~5Um&5vO#@B&)3`+yeh z@a`1Q@!qNah%*o0Hb1O#Qf=2!(>juY{uG1cGmS*nMyvK55n!`w6+6V zfzGc#pibQ)?r1OQ`!EDIhFI`C7(PS6P_TKnxw-7lfigWru33GqH;$QB7>w~^cc*uw zSmQzCdKv1(U*M;mIX?(<*h0ANC}@%qKcD#+Of*(N8HY0zLmx6vSn~wz2|{%iV8U>{ ziG*zA!88zmzk3Lpm-;AOSl#kr2pr#~f{Ssz>4HO8e$8P;_fz$e`*V%k>Ts>xv{IGA?A|>6rw{wR8Cgo2hSrl!~NDx{pUS9|6R^_!s2O zVAhI70IrTpl5r+C;bD0<9-OVzdw)jlkDTA$IkKH~9*toqtb_=OaIJi`1nQSly>JwPdQSzK~NL-&3K zwlaZiupSBwXaa+gW`1YV;Fs&n!$a({=cWb6Dp%q;?j)Ak+SPwJ0=K)oz()L+gZlsR z{>89I3^HCJA5YCf9?>np%vZPo8>5kYUdwv5if6$%Gntq;L{SqcaQ%Z7OG+!X5&pqI zb03ZaK{!>lasdKvfu?Z8-SXkS|L*;Fw186T|7h8Q=?zg>PxX}%@UU52rL-Qm|5B%) zr_d6`abH)ydUP7vi;B5_TndJjjmud;-zzld3fZ-TnjbFwipFaf5GU*|7;K4x4IO5- zu&?koS7dx$>!*?V3u;ouRIoEd1oT2@Kv^LTLuTO5XOact7R$T81|asvNzQ&mCea`R zmM(ot=LYc_n9#^8V9T<{5NtsZV>#@dd`Tfa&Hql35qmfJ=h+!fJkFoYDB8c8F8Ki6Y>t|h!CJjY`-BO zC?JMJ>dYUd0OphYcBc;D11K;1P7Ale1iN?$f>b2&*xU|^0pgXAxN8CRKxzg`L@U9k z!I#3$SP%A z^GaEacBJr{{>eK( zacK>9rs0@l*ZX`3bIS|0~K*caXUWF5W* zYszfVX}_B5ppn^*br{p_kFy98zI|8?ZmryvnI&}1DtUwc2 z@JdRi_O;@g9%LRDJpcmNljIzFW2O!y-_CUCBr@E$i) z8j$Pd>At-72kXz58wcyutS+j>rWm}Ta46i-I2Fq3=t!*-lCzh?gXQsdJHYwGX(xEe zBHW-DAEMB2jVZR3t41jd;q@VY1o7Sm)wRykyG=9E*m^dK zKgEEt&|aheBj5BCjAUc3VXu&$JCaa!sn^+Fn20G?Cim#W#$&VG~o3@zQxw=~j%Q^CmN(D>vN^Y~!I<>|}g;n6;;f+rw zd@a`}z2^E!X3Jo8Ioc`kdcw!t=S_6lu6c^u5kjHbd5K8{ZGDD zOEZr^ci1blXly54%;K3}TAEOVi=yOaDQ4&6K(UY&TnL+%*3WB5d$gQpd9Mt%6mJ

@B0>0kvIB`a%sNColhySu)3u<+!Mwl6M;B-qSd=-oE(0b1N5LAkz|&YDBGb z|As3?k>+C#!{ap^ZMEyW`UwwUTu2(L?SQ5^he}F7vGE}tHS^Dc%^6Xwl1?8ica;xp z(r{a{OKXPCv0`(Kv(mFNusOP9Jnhr{p|`G4)MpStt@H`Usx$6bvG9R;l2;?(lt#qC zkiczZ>z+a7ZQ?gUk@?finE0LVO9qy0n7opMQt9I*djyDHV%=l>Bl(v7wc{yjrTZGm zyx`?p{E^?#>*N_Qo^?)Ayu+f2V#+p7Scx)X3Vji_zLRQdjhsDFGS`Jtk=c@k{l@w_MrohxzPEM! z`d(=iXSfA{yhcM*{wXkS>H&^=@_&tM6>wAnkS);#*-cg)ydg=e~TRSZiuaULa=D#HhTy|hEDh@PDs1=%9o6jW+vIV+c7(Swh@V4KHxV_UMz z!xF}lvHLx2Sokj%KmxhT@dM_x6&+Y z?M$(v%CFiq#04+&=?rS4T3tBU@z%=B^dj&6%)D61l+Q^=R;qkQ_f+)n$1KXHbq;nJ z*0zI@7!(J!sJq-32&br~2-^&k(Vq)WI;Z#+vGzfITkwrbd`T&xcXl$yQ?W9V>G*8u zsT%u5tUCzbS6SB{*M9Y(MOQkSdrY#Yb;9;S6ifJL<{3BXp~MG- zbLkx&sv&(QbW3)elo7|tZnFmx%LKJyysFsSl%(a6OMnLC(=uP;U>dxSy(51`dZUR& zPtnDJyc$Iw5vwip@!rox(OHQZ6dNWATd{E5m-_il+8Oh*mEx$R8xQ$bI4wUpb>9>A zHZksc_VH%PC>L$IxQku4(o{^LCxMl#wd0&#xG^6I-e1xqZ2FgR5t23rb$MHHK7s}2 ztaqIo@>el%z22v9crV@weS*^0I^rj@c>dc^D)xqGehp7kG*^Mh*yUfluQR=}7=(%V zy~rBbrLH*tC>+nmUbrs+FK$Iotn%9clW%d@?#<0VQ=*=nLR@NuYIL-7^94S>e`arR zF3vmF?WQtBouzX;@y%MYqG?*cQ6yx*K;;>!{ppz~DA8%uF~eki7r~%obC8-TwyckL z6@7(Hs6_ITrt09A(fb;{B9M9ooQm+DzP0rk@nC21htfYkQ$}Yn@v)^jkr0`x^9Bl_ z^Oalcc$+8h=p~A5JXZ%*PCxA2KTJ|HRv2CmB{MbuBZ*;>qeHlc%_Bhj|yjg!$f1hmr5_Yn4qljIHtjmuxxUjPuRv_C&#o&DeH|=?i;4L zC9|n6AKis3pt&Nk^EwY@-mFIb( zxA1j6S>$tHhk2dla%G*O`K|7|tW>-pWP2ji+Lv(mXypR_tJO^el9NGpP5^chuO|jo z=9t;!g-3~gu@TXR$*n2-B6Zr`GMJ+VGU$06IqC8b-Kn!v2~UnpYF(9z5&u|+AG8Ni z;yrV;DlV@whv%U;CJ>$>=*yf3Vv9A!&POR`)9-UQUY^~10DBggxE*SJzmzN4(HeCh zR(wiHFjJI&$jtuZUNg9HGlmb~q|n3{Xx>!fiJXpgQ6%_GsS@BIjcd=tJ*%vCkQ;pN z!iK}!JQHr}H|WCOtS$QEEY9VJsn(!R5v`6(qR@@=sj)V>`#|_13z?DImBZ6JWPcq( zrRw@RlyXgo6L$!x&wRt|tESPS7rPBg^m4Sat|(+>#4G#!?KzS5>bjmW&LYEk%GAPF zz&2tLV7-vzVrqOuP)`J?CT{pT^ii4ywBp?Y{on%a&qJCgoM?fz6YuG?xNqF2QLjyE zq@lsfBXaU+Xm`FFK4ft;TVN$#?f%S;Ib5(H+H9(~KQPP6e%s$)^)QnJX}3WiHY(bW zDqd(nxq$?!fGV{uAy?k!?#efp0LhRK<~!q&7wx<7L=;$acHY`K@+Zac{-Zm%NWsk7 zv!WIn{Zy{Y7YP^$DbC}yfAeVMwvy%puZ2gcIaC+jG!LvZH+k)BK;DC{CXB1cIC|KX zJ?7$NS~t1wsn$zCG7thY21$W?#7?Y2u+k;~QFRs&avF8JgA-+HHt5SX)bA&>)1h+x z!8J{;WX5Et!X*4t=?6h61!L>gLvdx#F$j&s26On>k9!SC7TK(J8^ZEM4tt1t0M({x zO=^N|sb~tqaEI5MsRl53UCMU}N{O3c1(Q|bxn+yApd_#7M)(CUr`Iy4W;1>>Z2h;x z6}R|0H{zlyHZ5qp;up2q-hq@!``pUQO3^B7lkPj}J`=7J8_QW&Ev+d(Uw>O zxbnO9v7u<06;jZz5`69@UXvC$R0C6ICgyWP(Rm%pNXLe#E0yazgxv0fK7!5Weda%iq;K1X|JG;z%2Eog0Yp*9 zjV&e_)WBdnKUfZZVy2+{rLP?{GmKoIV=DCr zi5W#A<*h+qhVYTc2<WJidi4^JJT?boS&Ae(4%GPT(DSo??J$N2t2Ho_*jYSpVo4yd@uMzQ zxOSjH@MVxvJ~d7FFd^Q20A}ihi}3&`#2=S}KGKdvhrvrd5zniqVF^4modFcv9qY%6 zEf0LG@7a&tpgLK6+f(WOD*-DGqiAS$QI7iWhg<4PH!wT*zgqd|c4-#VaGdf+jV;Nl z$EaWADR#W0w0R0(k1&O*-z7Q`wlk$$wN8H!p{aMVl+_7wKL8xrgr6Iz(iMVkJ{;sV zI~XG?W^AI$4NknNO{~(<&Z>ix?URF| zN^QmX#M;NQlRt<|#Zcl;SHHZbNspFG=r7XEmY8~HgrchQ{#050QWbSfko^X=AF3cN zs6GNWnZA~usw5e&Wu~;g54dz3-;L|Iwg%|9-WhA_D=+k8|MPA2oeV@Ky= zA5U&Rm)A-H&1dDZX1E|>bem2F)1&d&Rw1o{NYatfrxDR)C7-%4;d!DvqR3aj(^av* zWEn+_BOTpdd+zAZuZ&8Gi=Apy7!z+ieG&GB>q4-9fCp{c=y$^lduntGlUWPGl{ybP z$T>XQ&69~DPmSc_-`IY{kl@TN{;-}9O*WA)ly9p-vfCN4=+%X)@{A+|hK+%$g@ z%{x3+hmQ>d25NL!j$4WDiNUDF-Ze%&>}AUx5dR>F4nR;;16m=9tv=Z+U3+(AX>r;s z%JcU%jT)hFmDmi{&J>1}(_~{KZ3cN4_BxC$QfW>f8><=MhP-!g4DJf%#FIS?4}D3| zTEnrTP)C@&L0-C%Ip%Vu)@U%6_i}+Sf%5Ngo#-{N;^BHY?W;G=05y9Fv!E5ts2fL0yHjrK7pTn$zNiKZ*JEiBC^!&gg3{mru)UGz&?KeD1CE zeNup4SRDP%+Bws2V;=j~f=Xv~aiAsscwID?QZJK+E_h6>Y-5X{g@4KAwBTwU%b(FW zjL+LS91oW{h*<5dw0?2sYR1QA85C2dKFml=gp3OVOuJtX{T}S?PRH+e+~yGtLfZz7 zMKGo*8sr(v26{B;H@v6iDHbk$$qylxVA;A$@kedj^Qd)`iq_(4MaUxyqEwy-@v1x# z8n&Y#;_mr?a_o`i7ETzVm3~ZUhxK!--@*#`#;J?RT8zs&c*osTg>59F2K_BURaEEi zOQ`Hk+yMzhpQAZ#dl4Fwz~G(;8sv> zD^SUW!-gh9q1%W(NOMbN>u*{-v0n1yKKaVRK}C4Jefi#3)OlMNT@lM{U~9Yq`Ct@Z zFjXtPZW5czqc>+>IEeP&;u|7ecz5l;zz^^rV9x&&T?zj`pTe*n0%BoDsd{K0B)Nf# zO@4IRSRyHfNNg3r8Ximk@A7{krKAdu3OGt@&k}Sb*6Jp;rt!K>~F?QCo)DkjQO*0JrB7;EK)At`@ZQBrq!@ zoD!mqv$&1Am_|MiKr|xncU^)!SgQk*|2HZL2B3W4&LNdn&~XPwA()xDSMorz`wqBj z8H<~2I{=$o1?UQ#0@J)`=>u>q@R2_C9G)`JU|*_2j%+}A)sooUf&ml#_I;Bkq7RUR zpKZd&Uz+AY35Zt|TaRx3hhT+(S%f|OaA{>AdmnB^&|7exOoL7ya7(q&cMyXZyxqe& z{}(d+?*nxues@~TqVFEK0f3<_RSG9)KASr~qXB*_X$ib$L2%I!eXFxQvXl_`4T$!8 z4-X|k;dZ-u(Nh2f2f&9%$@u*O;9L^qLr)6+L1RhgSfX#G{fh;__A+1-X@%$PBCkN$ z&f+DB$w!TmK!50F2-!gh7F-d;cPKis0bR7L*f!rL6A?3tqg zNFqV}hVU3jHt)B09*VGR0z$D9%g_*K2Os%eSek6SG2D&i;%eQfL4KOK9E&^<6$M*w7oRBIs z4^UiB2-gQ7PJy2m>!QpE7qDp!0%}oDYCa4|Gs6hrp4K6V2zfG2x_CeZFf-gpp}J`g zk41i8$r@+HlBq~PtTCgQCB-D77mLz4fCO5O`Jz}(JoLAB8`p8KsK|8y2E{tgEDLT? z?PxQNr#%{)H#A>CY?0SOG-nbOVrqfn9HscY>j+LcmJQf`F7rA(ygUe+&KpV9B7uTi z_t6B3h7x7VQ2 z7K8pCq1ETVfeS@$y%EeAP#P{o|AE`&bEBg%UJD+#z*^mF;E>Y88B(w^>eGx0=bC`? zHb?dyiY^}k<>tv3vc#1?bo{mLOf_jJYyGi-UD_OwC3m)=GL4OeUC~M^T8Q2(3?(Q$ zp$naco2TQ&AzYiGM^aCZ7rPdV!7Jow{n#pnEg64yS2shex`y%h^n}xB$}6YV5m`p2Qq#mUBb-Rnziw%878d2RA=9Aj&?K_Ka$fiQmW{OT=-Kd_8@GI& zb*`_-G2CM6=z`+99MnNZhyBvLj>G3CitqguNa6%KIfgfBXv~OS@*c_~M<`TCsu;X1 zSfc&7)y#!^M4_csjnHi_L~b_00m7DNkccOQmk?tesVsUnxa;8`!^mpP8vg)vHJR(* zLCp+an!*ICND&H}t*;uPTl~X@hQq#pK+gq3bF2w0MT3H^Bhfw1tLtv2@mlNlWs;y; zRDW8S(EIRWFHX9W(@SkhhR)44T(;+kfiS#zvz<`0^stAPhvF4O6x$9Yq1hAMhy47w zU=f1Lp>#KK2(FbCeCZ&&EbdNuu7%s>^^;;qis8^l`$k$z za3BbA5qo|PDU@!bY~BaELVWYRGjK*H)>|{9W7X{4Lm(WXmAO-bg);_PPnf)!6zNLNmMNAw||2S69KS;XW@jSNdI+(`- zZcCQ-9~x#Ly;4sSJCNI$*+K%O&><|8LgrtX!0s|yJ4zDH*KDr8Jtd@qiT)z_uol@- ztp(C0aBEE#65wD>wu3Nx5!Mh^a;AB#&=+h)B5g!=;fa&xb*6^_d0ICqdecK znW5=r&dBq)K2z)Ejr?}RoBCirdCK$vX?p5!l~+HXOBMTS>{H`M;lP;|ws9iMX? zQqe3ZVq6|IW$C~`0ZLn_j`pCfb|}ilzraDB!4ox+Ku-7Khz_LApKK1wzjy&OjhH8) zz>Hc@C=gPYT>$5?_ZqY-@JHEFnL_l-kbn3uR_H2CX^bA-0ZYa|T3ZCaWG#l$wI-P@ z3LmcQ8Zw2!$NWEIoBkgSC>Fd(5d`a~6Q30gnUvwS*`4yR3JYOSua(3Wyetq*bB2`b;SCHm0gL?-~17o;#LEhvB+S=CuE)s&_ z_yig;5aLL{FMDM9?5g5fG-vLleJp=_7332B5O}|itfaN}`*L$+&apdz87kZi)F{>p zalrane1A{>g~N*v9*io>H|}q~m{?LZ%!9T-i(D339O!iFL30F5v`>8!bWe>C`0@%y z+U8kac6dJ?97J=#g4$&db=Z6D*MS8Z$ip3&X^zlav@5-@pey>`v=1b5g_xnLs_uMba;=G$M8dIYwnu5Gx85H21* zegsF{G`LLRk+(FFMHeNv%k6*(6xq`7|243`c+#zq8$d+_9Js&WCcvYPAzH?SpUPZS=kUdpVJTl z3h352o`Ud6KpWx^ZT5nobXF&HA#)0%SOH?7ec2_)kNQ+y4zn3t?yzfO`-wO*AA-y| zaiO*cB*>o7cEL&I(aeNflKS5#EMm5R>^5IJ0eXt3cnP$jE1x*B@3gxf1NNzL`!JQr z2Pmm9E~0&iJ^Huxcl132tP~d42zKm4R4VW5;*Dn)BGyy5mq0!iCzcVHf|Xj-1ly4j zji&GyP-}h%TOzz**BYdAM>CZ|tu3dfuHEJ?MJZ{v_b#@89tOKl)_+|??>(r=TsAzn z7CwPB_&sQ85ydiS+p_JA0=9oaZfx|m*uYqLfpC&SZV?!|pRA|kYtjFKTvJ=ZPGx7;g&+;J6I5W!IN<}tSs#${`vs_ZR)(I*tOHr7GV!ow)YFIw5mp=HOF zcRk44U}ET?THxu~R!CGlo~_2CK;1ASj&NyA4$K9t00=(>ISd6ESykq%ON989?F4p9 z)u^I$qO`In)p}jT_?sHR+QlHzidTYzBdr?FVYhOfK&fGn+FarO1dkP#vwa6)$xXM9 z@8EpJkc8G#wnr5atpkn_j+McXT4NZY6xaf-)G))?w#ZBaw733!8t(Pe%cThxkv4Se zaZn2<#FB<~pWjhIhd^rxn-L<8K9Df+5alb>|%5{qF zC*RFil!dRv797`gFm|Tj{eesr@z{W;H(VgDLeEC2;PNb&dNXB-KfYd6D2IM-zvBjC zIGE6iYG=4W2P@S1MHeI&SjY!A^#$<4+7;lGq+VdKuJcLy5^xHdArK$>f=aWzBe%|! z!#xY!>5&dYSb9YhQ)|9pf*^kj=NJ5Cd9QH^1mC(CGvL5e5+~>|!E!+3^3O~Y-#Di( zrWUZG)m)>RPT9PBk-Y~F2<=%-=qlXqA{*Rb5i7J;&o4{<38T=nb!WDq`0t%%FDIpz zQjA2-^jqMGtA;WGifs>gpmjK|`i&dRx831Fq}Ttt$_#5vp*H|;iwe)9xoQAj{$uei z|D!$x>4N^xhRFOUe~Q=k&!5CkLy9=f|5 zg@;l=Qo2i8kyb>JkgkU`=x&fyka&<#B&4NNK&11|t-tTNXN+_Ic*lFseb0TzIQ)ac z!`^G}wbop7e&%O>CZaO}g(fT}O#rt63Sh5l3|mx|?bgx=C^3wIZJT!}hu|JjQPIbc zX52{~gY(l$nFQ(wo}4&ELo^FmFolGV*S(PZUKg!{{PjbmN*CdI*J@WeQio}m(ND7~ z{c4~?SwBSF$~rJM`rtzd9L|8H>aLtU*!_*>dCT_(h~R+C-Ugsp%wr>jl&2)_GPxk9 zNbWII`pBC%Ex}OmDTH~MJHQ3#z<>8J^ol#UVPD7n-w|dU|4u#jf(L?(<_c7vHhhpz zu08}#@moG)03L#8H=Yrcq02LN2NY6#FH(Azjh5G>sXh<})n;Kw*? z0P;)fcf=k7R2rt)0~#h;(7A}wSbo0}97#Ca!PRs=5C%y3v}PmoIL}fGnccbm6cdAh z=LjDI5zB{@-AWm_(EIJ6Y!Z5z8BO;BDV#z?*WvGNAzpJo1X|mAH8?xS!-6xs0(5MM zYLB0s!Z+f6N(Xv62yNJw5>zzu4xl#essy6QY#js~a70!RsNN>+^Y8~$TqdW{9J$3p zE?42QB0x?UoCX)x3v}DTg{lOn>HrRuVJNKDZc{~sqrriVIN1liHad8^5l43)fQrjN z&^>qlH`Ga)g7~#O2agMWbUm-x?sP+xf4X~3T-FVQ~B*9%4>DS z#|SmM^rf1VMCJ#21gE<7N^1qOxGX%sJ{Lf5uUOSrpzU#yhYj^G&85TUcD4Y2DOHB{ zpc!zs@%X|^=|vtc%4*!T$SDK*LocNz2whudu1eG_f`hq+lxBeXS&Rp;M*b24HDT!iFR{@3>a)tG$iaw^HS2c7f-5CgB77%ike z?H~q2)i{HI@#D$i2FnPUKDbK{x>Iecz=59>@J>E@7XpNg55`!4p%PY=Wa^5;v10gA zL*%Og-0Ij4^S&(Asc3bTLFdnGP@RUY0Oc7n-x&|5Xhd3+Dxm?0HuQ^X1+U3IX_lu8}oMA7>K84L@FL?IT=I(wd> z6U6KCC39cvUcUCI6)-+^2%XpY}nw+()t^R9f$V_l#;bSJsp>LQq}WiN&ely%3x z_YZ122iXDB-fmDJ+{q76DOXPy# zClq2cN;PRu_U>IO)zGLzxj&CpBpTSsKw; zYASwv@9vE;tJVr|hxGvNhs_c;(G-A`dm(`VNXPJ-wp`qjalXaA0U^jb!=$N+I=&P5 zJds`IW{C&wJ^&~xyYr7Y$^>;v`!Q(FYP}WqW0uxvEKl-O87Go5fMplUt`BjQ)?1kp z`t!RziX2z1N|GX7N{l-JM9m|$+K1*=%EbSvG86`Lyd-rU6xAgj@ zuHbd`^joM8h!ldQ@(KAgG-Vq(iNeh=b0J?OzG=F6zg~ozoj<0Dt_sq0F9(D?>YG%Z zPtFMLv+XGfQLJA%X@1hpIR_CiEQ^hKUk}ANxF30&=%yzwp5wgPn0KA11du1Ec7!Lg zcl5qeNQ#|iTgdGKE$%HUfqgHe2sN@B%3{Lz7&hDE4W?%2dZlR;p1xlJn|gB~*)uW* zt@EC}cGg`8v=B;HG1^@o7My<9{62p&6gpil7uq@@uN8li0!|Dl?LZSWc6Jk?-c7lu zMY@0N?EWFYRf;J+ImI1rV^MZWl{qRiRz5)RObRZ3gbTwPN6-;PFK zrL5!5d1-TB^HB_E=IL!Kx^C_J_0RhCIjhZ#2id%+Ikm~ct2EjpwuN=L_P9CnYcF$O zet%iHgT|5lp=kGs^#mc)LG@<;eZtFJa%2^Bq(*ow1Nrv_P;aMmm!IMUzmM3!R5KEd z5-eTeUT5f0oc-7q-I%%)gC}W0i5n(uFH?n8`K|#FiFQgo6}=~R0#8Y&s{r>%yN#86 z;Y7Om@#*K(9$oL}Tv;>MlCJYff_gN!Sl9FH8?ii+l21tb)6U`xONa)+Fy*Md6r+F>KhO_QZtbbNRD z9{xBkIzC@MD65QSELcVDBT;6-cOg$)I=oaR3zm~^joUQsRM!(PT(_t8iOic7A;(g? zydV7hdlW?;cQf%>iKWkr7;HBweR{(7dpo{Vm)$dWWvdUWU87+S&plxPy~I`GzU_S?5bt`J9B zMbxHCtnWUO7IRcAqL&b2bh~M(&}<>`qIj8r_^Z|F+=CG(1JTW835B|+e%zL|feF7S zmEJ!WW zeUka@2pw)eqe&lbbVi7#whxW2+8KMC$fsA9XGO_%r1a)kM884BUpTYbfW-CZ9jTb^ z$9U>4)6&xtkOMI%*a0R<`hsKXM|Z#!tp_d<^VCwU^~}j&67T^T!+9196s)L@x&`swjiQFomXty%01nU!g0FH!F@y~Uj3*~ zL#x?XZ%ahW)ZYrpaMbL9Ux+n=e&>xFhiMHMjQdcCdzY)f>-4m&JgDc;oe=6l*Zo9}C6~6Epuh$|ijRU1=+6gXN?30oYOcyMaG5%&IX#nT` zBE3r3x@xD?x(;j%qBAkf3khRjyUXM!SDsCyj{pC_{MZ6^b(BYO#3R8rWXeB1}X3B#75m_9A z-X6j(?F1kt7eEJ*sRj+F1dz0{edH1QyXsaF#~)5E>65l9tc%Ia+C!&bUGE)@wS-nN zUag1V%6#vJ#9{k)sV)Hm^&1n16K^aUrAq`UW7qm*NxLoT&xfQ}p4!cGWMH9t=l`6S zEcf?_Qvl#a$v61CP8bN=M9$G1)}eMOqZ(&w*q`_E+!2;J#p{$i5@I$|ws0=pC?r|+ z)h}_Ok6xD*pJwW8uoYW4+(7Fp0{=(hq*|!p6{Imz8zDsYB>(_i4Mnn%ko)J5qWl&J z+(bm+dkpeVCO1pI07w1}m;$AYtBKr|6#$)bo{MxjMj3tL^5+{I7rgZYsbLg_JmIvp zlB^v7^vgnqLV%6YoxD5AV{wzGKIw&!f%7Po$XgZGZJE@2KoLCB$_yNQMz#fFW4))x z53_+QAzO!1Ok#cdP+J}Y3elat=D?Z8yA#OWq%{Qnj{KfaT*BNl>XKPwuqc2Sx1 zd!1verT<2x`cN+q3E9Alex-)D2H6NwgTiYjlc2nj3qaLHs*6CCRXO`uszrk-{lj_` zr~0YW^AMxtB}h}O3s30}0#8T`5q}{1HZbC;wEo*Ka!y3uVgX7wi3;$uA0C7m=)Ctm zK2qXdg^GX)mykF;XT1AdWgjUT369!{jE8rsq63o49t_8J1O&H@5{-!`tX2)qDV_up z2#3v!cj1XZm!@aNA*HC~4WMr&5q<0^Iv(%So#x9ZykAv&1Y{fFS9vVP4%PzD^&2Gj zL)6@RA^FfGBUQd8935bse0;d-8?tKmekS&wG~i3_-%C?FlZfICmO~!hoXgI4WDw%= z76!dgq~(^_PpnQO5kInGzP@l>84)_f59E@-zColt`;AG=q0Y+!-PM}rC{(Bzy;olh z5qGL+>~&I?(vW?}(f1Fs*t^6I9-1d!)oor*Si-K1yf>N2^RZd@0eYbud` zK0+WgF!A-r;@rM82U>T#{n}B1bas5ags;yI13MiS&Oxo+w3owed(21AzXuE20eK36 zI(MY6O^$-@LrD=p9}~lYfr99#@w9ZDG-pkS--5kE1$@e0euc|a`#h`@&8E$!B&pig z!jwl`-~FP2V5Z355TkZ;o_hXbF-K-o+3k4Mi7N64X@VXn)=>GENn&#{yh@*1M)`&`~xoz^1*9p8DIETB*sMaNxxf)=?szhx_Q#$F&XtvYFC2-lAx|oB3C?{AuoEBjw zX-5T}H*AZp7a(@N*4`nNtu)ytC~M)8;lcQzE5U3FLJ6`w!W`cH;Wz6V`q2rtbSH4n zogc4~x#V9+Z{dx9y`DR6bC<9@A;rPJ@b`qQc2s0I6a^(xqY8|Zf&b??`Kv*KX;KBZ zc~;j&ctq%66Iy>wUpf8l)5ygVv!rWu47eHM?@tXT6_XUG)bpf=C(R}axnvoirEP4U zyraijLE}5S%qSFKVH0g#5MJz}wZ>p0ewc@0%T)PJv@L`&6CCtv?G!h(XYQZFpL?mq zZRut9}~IOf`x?go54_U3odG}>D*D?24bwVNb@E%Y-07&`F(IKk<9YGh1**_4zR4rARC3|{j7~vDEL-9ik`kgYuc})v;;akjbO-O# z*rS~bn)Ib+%noQ7(M!R7cz1*I)p&yu;sb^5bE!R((BgwgH#O!L@t@7tw}2^yv{TdC zq0rsC@Awd;R2`wB{?^is3^jB?qeSB2ea>vfMG@#|yjC{?@}is3Z8&|vV1@D`Ov^GU z&zeO;GcixDQu3`OYI>gE-ZDGYSC4cCz}23+VNZwN6+}cico4zso*_-p{kFsb6!Skv z;`%=sorF>SzY*I052J{Fh05=Saw9V2Id?S*4aC%f5CN%Dp(uFt^V6VQ_Fwk~AlVM1 ziX?!RC_K!rlnsmepXkvx+3g|jKPfJ!u%oTi|YZnoR0v5?1@)6uffw*KGa8qDm@-hduEee$b zmowp%rHeBpcF}4j(La_2jF{tHLZTrzhWy0u0B~D6k^M`8a$USV$Dqj`a|JT6o{%*6 z+?eNrHX&IgMkB=l1_MhEp@-eGV^s<4&j9UO1e^87iz-H>c=rfsDuLBUt^2wEBeuW| zI$Cay0aA(3Vu9I84#*_J(uC|UFf0pVhMJ)J_;AGoL}A9N6OkTPK89lxN%EUK`@p1& z9RF$n9|Fn+3e1oQzrkyDcP|prPq0nrz=(VALB@qR-`jT4OYtJ1k@X+J3FM@NzcD%c z80f!{fwKAfwprn)F(Af>90jP2BbSe~wN`k_(w)GU`;vSU5Ke?h`QH9sZGJBk!&79< zB=T6|EB}UE)dpamy^wzZ#7KPOiwtC&43Au)SzijI=#9&v|6e-P_90xJLToIeXPB@I ziWHY`@Q3*CLTcaC9n|x|PbBX5g}NUMdJMod?K$92;$9$qZ^i)KVCBJ!5c&dyr+uI- zmNxPa+qpnpHrGsIVfaNqHInm#uce;l7S;=g$VL`tGAv$OfCB#?&Cqa>X$!z=Enou! zAC~XH#m{jbSktf6R4ZWGj{p@1Z$r$sFQ-`r7TYyg_xWuK%@<{LC`2B0Y-a+5MfmE9 z+;dPiV|@=&JOEOSf}R>cv!bjAQ1gWFM?ojz7jTf<-J*ftO6mCF1mbsPXQm)9Hp1Aw z!g8Q^QjLlA=C9h<2TcGghe6n+OZa%FRf7HfG=Txawg8^H_z!i?Zu7G6s*2(mTvxO3x;ULmwpvfQx!Y$F%;=C@Ss5)0R;2RTv z<^Tu|Qh4mw3?Pa1{Cv^{^DJ+8j8Cev^y+Hdnh=0pCaG~4ETMaM0FkpL8W zTLc2NU7Y@-Ks9Ryp3|RHfwO`rO8=$^mR|-`(qtIYzzE*~_|&)&YL6}XPF!B#P2@TJ z0;nmZ*A4+F-G*1zl7eaaG0z%!{)3L}UhwfbZQX_l;&m6`G&4GS-)7lGlc94dj%@{7 z=rObAk+GlR4bdWK9c(!CNPUKYpGxt0F}L~i4uJcsS)k_*tYqr@7C%bS=PzwTDzvT1 zg|f`&Jcqo!^`Ha*QNC#-K%-Ss<}vIvvV;f%^ZDmMA=UoGmk`?$arJsA2?%SI!o~`@ zMlYIzx|U>I5j;VZt{j+>GmMj$Y!^U^6k)iBA5wyghLxc3?7Ug(mO0Z)5zo`*{E z?Jy{zAaP{i$b8`kM6wNOq5D|G0BA_?Ze9nclD~Xu3u#DMStYz$aQ$VKl`cc`P97zp z-u(O9aC(~X^)CQ-;#W7&cYHdyT4ilF@(3GAjjRtVK!E#pHU|N#qjzKn#9Yb1km3Du zkp^j)?3oO7-euTtW(~DK;TBzjEF`;W^4h@0z^#MKO)#vS{_a4hhNjF(T%W(3cK|*f ztR3>7BBeD*Wf8ob&oL}=HQlLgkKI&^LwM#Gq6UdXkje)p%f}qR|L6f(n^Q_@QZ0%W zHIUNAS3)1NI9*>@fn4`@*vw$Hu5=WIzoxtRtu>ysOFNQK#Ik=IRwMoBCB=BuW3Uro zPMTmPM$3m-z51T#eO^^ZK3*#*^@PgYMKDdd5dKH=G3)q)8F>t54gPEXDY$IzA1r`= z3j~+5K*$GD`mx3MO_*Pnx7v7oftC#>ST=V8;c#bcLyl|=rWoxpW!wgqq7u>}2zx~A z6Qq5J@jJVrP3#X?)A&nimP1^#Nx-H2_=BY;{lHZM0r=qnDBFr4A*?(AOEbL*#lK+Z z;PUs>zHy>&m}0>`VQz!Rnw7K!AxRA={lx9zARP?{o;$Fqz|8vki~`yV>fuf>K~!L6{XvP4@BSd#s7tuVFzKK1O@oZh4Z_Wkod&CL8#0Mqz_e%VbBqJYA~?R%(CJ!L z0P15H>1oYzfXg3-lB)yk3mTf2j8-}rwkTMCoT`*Ow{ia9;Pu{z|O|)obXQsPKe4ipx~5ORrY*xH1mO-61VQh82sH18n%ZVQ2~W!qHsCf zip{H;X<-RAxPqX7S=*J^DBa&t)=#pG=szqdJon|I$(JKJ#WERux?f#AQ$;^HiY9k? ztZu(8g4Wu_+7f`_whP42cW(|5f&#+^@j$N9PvCQKf6FOLfkgKMV0pDUKt;vXEl!Y@ zhULa(Of>cB4;bo^kSEjRIn*&As|$Z zDrchhd(cM8kp-CHK-f!~W>7NKEP6<7KoddlNaJiue^Zwb_gHfxs_CoExvb_WyrO;y z`VVwXu+Hx6Qyy_i9*A{=t+l=UyHcp(MA=R}klKVCp)JZ(rFLOG7zV-pV{>Apln!zW zJ>&1dZv&^(q@)@^Cxn$cq(z@D=*!{^xqzN=!@9jjCb>NjTTN?dWoJTuFI)!FPF$bK z=n(Q9P5Q6jU*K+$k#E6!1v#s*$frCH_XM8(>7J8z+L)kf{6Do1D3lp6B@?LlUylef`+NDXZ8tE2 zucC26ul#kl|37X0^B*D-pgkau_V2kPYQ=ZK{J?I3Dm1hjm!y@#6S5dV$Y2)VEzo<9 zl;ZvSpPSR7noHtA-Z0=2hJU`I|5a|S#<_=>v&j;l1CHG4pGC&@i z`7Exo@)NpzHUN%*v3&sa^sC5U`?C0{Nvnghfi+tWOim=7;vbd{@*BcNRruYvEEI47 zgCd~t%@r6Duo5CS1a^TkfT!?|p#8Kq^KFGV_BtSr+({Phb4OYv<(vAy1`@$Aq_!2O zeR1%?|hlm&ydzP3%d5m8~D#?@bv#=mf=?at!fSL z;J=PLj?BQn-*^8#BYy(@|DKWmUKfZV{7(Vg{ujsF|L?ciF_q^w<+VQVZKng)xaTwM z&Kjp<7;!Ub#@5JQxe-p)k!4oy$R?(}dO-gmRUES*k&Jp^Y4a2H&0^@2iY+~+H-ywQ z1RxAvS(NHkbv^@0*-MPCKeHEoFi3IO>P_xsXMK5rHEG*cc(}CT_rCW>x?`^`&#qM* z_39x`si0Zfs0UGIUa9WMt&v;NanLfmlx=EGs7mfi5UL=BaB&?aOsH zJ?dKh`}_ML3S_%qq4ehhRxgfEIVviC25IuU_wG%Ty?^vGK_wG<5-x&FGyxge5Qe5< ze{|K3|GuMR(cYuxAR^!n-V<)M;x(vplsdTv-bpCA&^kzOdnkn)c`f!bo#aFYW)+lr zs)$z$kqk{pNC2Ekflynxm|GAWX<#aWQsfShr=eHtvf0_OB4ZgfwMb{G+rmu9pW^I@ z;UJQp4<9}Rkm&%3(_5?K$Iqw^B+1?bz5*$?(v~o)2B_`_1yNC8St-PU7ePl&J<%S+ zLLX%fmH*@WW7}p$Wo2bmRaI}^ys57jXJ@yEl9Ga5ZgsM+pbH#9?gNoTOH0ez+8W5s z-d54c?+1rHIwnSkmDpNYu}1r8YTE$SI=0nHcC+%Id4j`VOJwo4Rz{&6jqYy#v_S8ID>qHynKNe~zU3o( z<-7MS73j5;*FO0e9Z~zT?yfZ1SAs0DAu^dyo=kN2y6vu;qbmS5jWk_ot$tKT#%mQm ztt1q#{_*3-9=D%Lo^LMd%()02xlVr5~;ZL*1s6{$TZNKa2MAfTmN6=_OKOH1cgF7yCUoOKyU7Aj*J z>_>&qjNUmS?m6cJ(I3n-C>!G7NaCzn;#3U(EHE87+ZFWN!*u&X$l-VU7&QnEbZQ>u ze>4imSw8$ktMT~p4l4uRM31k^ojY1z4yPLe@CfM{kxN`5IUs$~8cM<9v;mCf*eR%_ z8R+k~|6U{&dc0NHKu1px0FPcM(i*k4wzlgY3lo#->Iq^1;H+HK=>q#BJt1GscB1CZ z8>y2;)vYlBb)MV!WW4h9kQ~fxrIgEaTE~2jyNSVI&Lg)web)D^5gsN#Kfk%T8Pc=x zw#7ZS@`M5ZefUryZ>lxyvp=j(d_{C+#ryZ~)6;Kx=WfMj!o(61z6+JN3ikYwPUH&&mpa1{M2?0^co4p{Z8)W+^eN_K&f`mO~b1 z=JR-XPKWx)KyF^y5yDX4A`t5KwnOA3uWo7#kZ0 z9k<;<@Z%Wk>h~;3DMlQC(r=#+1s~o*VY`-nZn5`g#(}O zU_{;50i_%o6W5TOyZXlrx;{NVRkR4)<(?DlOiU3tP^uB%(V_Gx)vw{NophCQJ7e^E z|DXSapG1cHaR}mHofr16SVebVHdL2zGz%?VUCa z{b)o2R1+v^BSOZC;}JeC{9$u*6WICr1qEAT%Jgl#QP?zBzpqwhgLZ#bCC+xI1I3S^ zp!4pBGaSC8*QQzSDZW13Ec9iI@)mdsMEbkBx@5$}7W{wuQ>3OAy84~A$n6t${2}?r z2tIN6eIMC}>x&|XK|g*NHIqK`?#Ry07II&o=J5G-p>V& zfle2qId{M+oVS1q!NklQ6cWaeert8_pkSKZ=y(O#VVNLWB~Nli76KpkoD+5CQBO3aiqvwNL|w z0bY6P-xc}V_rjOfn~*730WGkYEBgTw2T}=T+%!_#pq1~u2Gt4*D>0fy{?m{Eh>MBA zzVj;*?{rN!W`?POmSvs&gbUJoZ*XR5@w_Z!zh zC^jl}oRI#r7H}la{)mpg<}T)QP_?iAG9fXM$nsP_pPITlZ6Q=Ytg9|Uz~11oX>S&&jNI+pvokY)eS`e<`#35pDlnIekO#=(x6>!b53rT6H0C6Md6?bzn+DAOQ**Qa zduM1FRp#j8?5t;NKC-Fw1JrzC-2ud#_+|O!4*870GjmiITkT zD8z*<1xZ5O56E{M<(oLCkng-taV{d?znuQ-hy9=Yfd7>_hWo8}$&#Wyzm9Gq>-6<~r^}AMKO6;7E(+@*p`lwUnUrRJ zO6sOLtoKg77KcyZY~Y-9OwG(tuQQ;cq#WDT;MR$CrGNLx%^UgUJn88l;)UP`va;qi zwd4ut&|ENo-;?|I+Ll+I>{n!D&~NWMtj4f{$EB85x%lTH!l-e!jrkLmOVU?aqHb{L zg&*(68*!4Pz1-t{$KJad9tPeMyz8iwuGi;5;bCx7G8suO01Pau*_t?Lx8j&N(>`Dj zHIUbt=-m-PqsGk7zm>9xq}!pQiHL}3J+8g2t*xsoG%O5pXu-Z)bf=7B{<-WnmpnpW zR#339vic6~Po$+ALD`6?Dk3EZ)y>bLQjwt4DPS*aVUBf@*Gqc)Eqm(HTz9}FN^$~< zpInAP+N{J(^G9sY!uIe3-u*QeaL_}tFgBvPx*B4DwsH9*wXqXboquoGbn;N>LqtU6 zR7qEg7|VnLji!f3^>i*E!r0-)#zs)1xYrmzJq=JHbU*>Ii&M(V%3x1orxEQ-3Gl=r zPZzuL3xvDVdchLq=H^~!*UQ?tpqZ;7JpCYr84^pgO9OHaql;VyTa&>rLPE|NcwjvP zqa*!RPV~un?@rU<6dE=dOcvO3N=O_-0c320e3I;nO7EX#LP zvL`1^+;cas|C~XaI{oT|LZ>a?<2i4Iv$^A*g-5|0wRg}=Oy4nkJc63fLOnQ$>FMd68e@M~Prw=bb30VWI{{^vWMpJOvP%rAJRUlN{K(a-SDkN432<=S zsjhbxg^bt22ETwn!1L$%dhgePNpJ}d&mE48ncga=DF|^m9vH(R$xGI!>3D2ZIyl|* zi?UF}@uoF4vQ70}?VVdQv-H3L82$K+YpT^VNlm0IIr|vsiqq567b!)*dvn6l0>;wa zus(^q0sl5MoTIN{KGD(9y<-|x7NtTwJl{4o3kMY2V{npUW9gOKrl-vwu9~>V96*n4 zJW}%2n7ut-Y}ESdCZ&U*uekBi!ItJNi5;WSH!@>WJ#S)GafQ_zN=mo|1O`m+zFmjY zr(t*D(xrg{eMK~Sq3G{MEc#G)TDUE{t~4+(u&=Lg@fYN#*{qdE%^riT2TcWTj1s)S z#X%4nAi91%6*^!`NEm)SncQVuSu;k*suy2m^tAQ#j5yTy(SLqlr(8CWY?C_3PVFsRt+;8rY!# zmcv;@{|t5q5}Kou5)!H*LLC~?eOOW!4D^N98ywWs)RD|}tx;Nq1*4UP69?|A>a!dT zc_NQF-TRnV)yM9L+7uok@?|ah1kXnAp!Z@{Zw?(~4ST*NK!&gpkJE|zH>chA1|i|p z5cy|Mzdf%ZaH8~UAFD>L#dDcPAKmhVrt5E$8vKVO$BO?&R@Dg;9> zuhPzTr>;&tniN+!nKSy+z|ig4@tm(8Ep4~>uGz--;ujN56pw1sYe(*>ac}q@3z%;% z^2e18p0F>iZ<^4CyaqT&2B6@!yu6&3$4VN};-I552+3gvpZy?Ps(-ED1;nq|PzJXa zqWGU@KF{Xl3{&~)8LH8=esy<0HP`W#fuU09n@zcbp_cF>><7>RQp^-%W6RITn1zdh zTge@tl9G~`xTOEl?T|ex*2l&s=g%p=?T0fGFlfjB?kfoeMg9m?6!zNn>vN;1)s;Q{ z+kfJLFJ}&aHX13bx>eS9&n@xu@!gV@EyJkP)cjrLC=>KJ{fR#N%KQ16>567=nkLqY z#WenPqEW($_S?k71jb(zu4*30y1dpuvQqGO`8>lJnOktJ{{H=YY;0^sMn+d*B(_AB zxP5&r|KC19l|{Ky_6ufivPOFQM5}xM4&W=aCdyl}oSDOsYwj z-Od~MvAxd9nVaNdN&i&zHMdLcg~q&OmsI}V^Ww^h6$Y52^m9u#*u9&CW(l8+bl$p# z@`lrWQz&_b_!$j<{fr{kd&r$`a)PfQiiaUEAN4Fsrj9ZXEb|jd%FZyvc1%o6C}d*I zbfnKB!Q>S|+z;Lc5D!(?#5jlb?mrgkK%z5y16cEoR=wXm;7>Fgn4hUG)t`*b z%;B&`u!@R825|=5dMi7-kl^6pkdRvM{YT#3hrnA2x&7|6(I&PyIgkDVoyhyW0D`{W zM6H1Wd*V#b>j;bysh~O+}VR+O;Snli(!%X&QPh zLT&xh%ReiyuC;p`XP~!NzWXjd0RchJw{Ph;SiL2LD8;?1PMZdPa$f987NO{mu&T5j zD7bFu^$V#^UNStccK>ZrGs-@7zrqe8rtnkPp7QeYMKhtDpANoD^#`CTD*-~jp3O7S zdx;y?_zdIYXL`r0%(%u%M&4WR?UjUCtI5{KtbNZ{xIN9Y%4r1g8n7q_x5=5_iZg2e zLBPhQy77y!X2K9M06aLH$Z7Yz2pmB`6j?!62bh0tx7C8c^Y7Eou%5_&uzpbbmo_8kt zGXnsnrBjQ7G-&A{$Zi;; z+j>0p04WR8{v&shmIezB`wKwFx9{FDC?}v=p_VP~cA2cz?gOoS-M;J3Fhc~}KZ=Gs z`iMGbhbxE`OS3D|KW2qi@{_QH`MwSdy8Ja@>D^gb`t);W0v=!A!2RHJpq&c|p&9k;`SBX{c-*4EVYUD$&t)JV&xPdf$b8X9!j<()++Wecook7SCFOGfS~z5Dlv zdwOVInGf&|X!Q38+uPeeqNuR}oP!I1!W@8%@{5WbTS7<`3~Al_YGiB+>YZo4ZM$-_ zXHq;$E>SP^nb)P3vai<*ktH&!%U+bE)$lJsFjo-hck(%a<)54|jKWbMtgB z`vUe2hy$Ua8;$Z2|6DGG(VtD|5hk&ELbEbv-AOL1X`%`!KLPh875yLGDntNiDiw2c zbMaXD8DfD4kK{(PZ*ZgUc6WC-IL`$2oWn{C?i0+<_jdSS-6e3N=-OCP+3qC3Yu@^_ z97wsaomeWI+$#2=p5tj~NXP-8o2Sl6kTai&wuvdrHV=~^l zhIs1*FC|tt6o=sn*pJM=D^@Xs6x!h#r*HTJ4iC~r(qqhB`yXa(@mDq0wT#ZOA_J@Y44_qeyTZb`0_|cG z06V}iumQ>!;pcY}EeH7Oty{O?r~ALce3LMkL1U)C8nrnH9a4bbWn*IlKKa9k<*nqT zaV6k%T3cI-E1)?%fU^XrhuQ?tNugJmYAeD5D;?A`Fko+(gL3fn4XH)_nxFdVcD5CQ zD`PmzCJ*dw3KQJ2!^5wj^T)!ZfY=)1CG*Chm7VJ7j_;njHERuJjvg#;LWtjf>Nhko zFe8RRvU2@CJ*nv9HHg|O9}HV?l2~*lxkDYx=3s-f4Xo)NB9QU5vFs^i77_6TT$CUk z^$xNU3Z_D|v@$JpAMr^zCGpdG!2?6tr)Op=5;}u$<;rI|p(5g2T~jVxs@?4gd7kVLjj6y4^9iYl;RM91dGQ zoGOc2%U8y>335@2xyOGI1&3evabiUg!3Y%vs<|lwtNX#t{UeOWTVGzrrzJUv zHzitLxPN0QKlb*0TNg*G8^gAWOks-AbU2lyMe1s5Aj|k=tn%!7x!=<2N+>>(MtWi} z*R4boXbUF|fr0}-ZXn?$KBV)LW%`@_DzjBhCmAN1QbLsDk$lC_00pOOS@F7_{-AYD zd9w&k?k!Q_4;v2Y$0P1I(b>kg9MJgk z@;<(-48AiyL}X+(#o8Mlb#qnJHai^-56an6ef2y-4+=Yl3GNQpiVJab_gL|Ii1rDI zi~E3F3V0YcHbKF`e{G-ELiGZ*q=tqD#D5TUE)E9;1wjN>RK$74hi2lUV&l z&WE4mBDWlOQ4d|omkGzBLj+=dBKg4_>z(3NYUHN25>cJg#6dqD95OpQ%Wh@_K*wmq zxj%=Lfh^9-Wz?r3y9&?tEbjL_3tCQN667~-fc5R^?M-t{P>O|%nmVu{Lzrhf{lkYw zR8&+@unLaLCe0$Ha4WKF*Lrt@d-^Vt!yDqp2!{-EOJ!iqdN`0lJZXHVvmXW<1p9%& zKK(|Xpn9(D?+18w_zVyAdYrGn&HiZgWoh%$rAs}d8dSEZ=DvU%*gMfw#x9YDwCwDm z$_>aMPm>{DV6o<2HGylNAoID!rmWu90|nkqpRrZ3h$@J4-Wk}lrByYXsJ5n8P22GK zvmm3r@)-BSVYsYbxlFF><#NGc4+OoLzh9;D2Z8>-6VLw-IfY|z{*RBVC`@0#;Ljp% a_$i#~@~{UlZyNpaR?)XqWDBH?{Qd{m@Q%#@ literal 0 HcmV?d00001 diff --git a/gui/src/components/codex-set/PromptLayerRow.tsx b/gui/src/components/codex-set/PromptLayerRow.tsx index eb2fd6c68d..4dd54a8bd0 100644 --- a/gui/src/components/codex-set/PromptLayerRow.tsx +++ b/gui/src/components/codex-set/PromptLayerRow.tsx @@ -1,7 +1,7 @@ import { useT } from "../../i18n/shared"; import { navigateHash } from "../../hash-routing"; import type { LayerDescriptorDto, ToggleStateDto } from "../../pages/codex-set-prompt"; -import { LAYER_LABEL_KEYS } from "./prompt-layer-copy"; +import { LAYER_CONDITION_KEYS, LAYER_LABEL_KEYS } from "./prompt-layer-copy"; /** * One row of the prompt-layer list. @@ -47,6 +47,10 @@ export default function PromptLayerRow({ // An id this build has no copy for is shown verbatim rather than blank: a newer // runtime listing a layer we do not know about is information, not an error. const label = labelKey ? t(labelKey) : descriptor.id; + // A layer that only appears under a condition has one; the rest do not (the map is + // deliberately partial). Read here as well as in the dialog so a conditional row + // never claims to be unconditional. + const conditionKey = LAYER_CONDITION_KEYS[descriptor.id]; const checked = toggle?.defaultedUserValue ?? descriptor.default ?? true; return ( @@ -123,8 +127,19 @@ export default function PromptLayerRow({ "Always on" is false for a transition notice: it is not on, it fires. Reusing the locked label would tell the user this text is in every prompt when it appears only at a change. + + It is equally false for a layer with a CONDITION. `plugins` is emitted + when a plugin is selected or advertises a capability, and + `git-attribution` follows the account's attribution policy - neither is + unconditionally present, and the dialog has always said so while the row + said "Always on". The row now prefers the condition when one exists, so + the two surfaces cannot disagree about the same layer. */} - {transitionOnly ? t("codexSet.row.onChange") : t("codexSet.row.alwaysOn")} + {transitionOnly + ? t("codexSet.row.onChange") + : conditionKey + ? t(conditionKey) + : t("codexSet.row.alwaysOn")} )} diff --git a/gui/src/components/codex-set/prompt-layer-copy.ts b/gui/src/components/codex-set/prompt-layer-copy.ts index e0136770fd..dec1998745 100644 --- a/gui/src/components/codex-set/prompt-layer-copy.ts +++ b/gui/src/components/codex-set/prompt-layer-copy.ts @@ -24,7 +24,8 @@ export type LayerId = | "plugins" | "tools" | "skills" - | "multi-agent-mode"; + | "multi-agent-mode" + | "git-attribution"; /** * Layer id -> i18n key, written out rather than built by string concatenation. @@ -49,6 +50,7 @@ export const LAYER_LABEL_KEYS: Record = { tools: "codexSet.layer.tools", skills: "codexSet.layer.skills", "multi-agent-mode": "codexSet.layer.multi-agent-mode", + "git-attribution": "codexSet.layer.git-attribution", }; export const LAYER_ABOUT_KEYS: Record = { @@ -67,6 +69,7 @@ export const LAYER_ABOUT_KEYS: Record = { tools: "codexSet.about.tools", skills: "codexSet.about.skills", "multi-agent-mode": "codexSet.about.multi-agent-mode", + "git-attribution": "codexSet.about.git-attribution", }; /** @@ -80,6 +83,10 @@ export const LAYER_CONDITION_KEYS: Partial> = { realtime: "codexSet.condition.realtime", "agents-md": "codexSet.condition.agents-md", plugins: "codexSet.condition.plugins", + // Mandatory for this row, not optional: without it the renderer falls through to + // "always on", and that is false - the account can turn attribution off, in which + // case Codex sends the opposite instruction rather than sending nothing. + "git-attribution": "codexSet.condition.git-attribution", }; export const CLASS_LABEL_KEYS: Record = { diff --git a/gui/src/i18n/de.ts b/gui/src/i18n/de.ts index e3984972dd..8a2852c436 100644 --- a/gui/src/i18n/de.ts +++ b/gui/src/i18n/de.ts @@ -959,6 +959,7 @@ export const de: Record = { "codexSet.layer.plugins": "Plugins", "codexSet.layer.tools": "Tools", "codexSet.layer.multi-agent-mode": "Multi-Agenten-Modus", + "codexSet.layer.git-attribution": "Commit-Attribution", "codexSet.about.base-instructions": "Codex-eigene Anweisungen. Sie werden mit der Anfrage selbst gesendet und können nicht deaktiviert werden.", "codexSet.about.model-switch": "Wird hinzugefügt, wenn das Modell während einer Unterhaltung gewechselt wird.", "codexSet.about.personality": "Vorgaben für Ton und Ausdruck, gesteuert durch ein Feature-Flag.", @@ -974,10 +975,12 @@ export const de: Record = { "codexSet.about.tools": "Verzögert geladene Tool-Beschreibungen, gesteuert durch ein Feature-Flag.", "codexSet.about.skills": "Liste der verfügbaren Skills.", "codexSet.about.multi-agent-mode": "Anweisungen für Subagenten, gesteuert durch ein Feature-Flag.", + "codexSet.about.git-attribution": "Lässt das Modell einen Co-authored-by: Codex-Trailer in Commits schreiben, die es erstellt, und eine Zeile Generated with Codex. in Pull Requests, die es öffnet. Codex liest das aus deinem Konto, deshalb ist es weder hier noch unter [features] einstellbar. Ist es im Konto aus, sendet Codex die umgekehrte Anweisung statt gar keine.", "codexSet.condition.model-switch": "Wird nur nach einem Modellwechsel während der Sitzung ausgegeben.", "codexSet.condition.realtime": "Wird nur in einer Echtzeitsitzung ausgegeben.", "codexSet.condition.agents-md": "Wird ausgegeben, wenn für das Arbeitsverzeichnis eine Projektdokumentation gefunden wird.", "codexSet.condition.plugins": "Wird ausgegeben, wenn ein Plugin ausgewählt ist oder ein Plugin eine Funktion bereitstellt.", + "codexSet.condition.git-attribution": "Wird durch die Attributionsrichtlinie deines Kontos bestimmt.", "nav.api": "API", "nav.integrations": "Integrationen", "nav.openMenu": "Menü öffnen", diff --git a/gui/src/i18n/en.ts b/gui/src/i18n/en.ts index 6624ea15da..5daf8085be 100644 --- a/gui/src/i18n/en.ts +++ b/gui/src/i18n/en.ts @@ -1453,6 +1453,7 @@ export const en = { "codexSet.layer.plugins": "Plugins", "codexSet.layer.tools": "Tools", "codexSet.layer.multi-agent-mode": "Multi-agent mode", + "codexSet.layer.git-attribution": "Commit attribution", "codexSet.about.base-instructions": "Codex's own instructions. They travel with the request itself and cannot be turned off.", "codexSet.about.model-switch": "Added when the session changes model mid-conversation.", "codexSet.about.personality": "Tone and voice guidance, governed by a feature flag.", @@ -1468,10 +1469,12 @@ export const en = { "codexSet.about.tools": "Deferred tool descriptions, governed by a feature flag.", "codexSet.about.skills": "The list of available skills.", "codexSet.about.multi-agent-mode": "Subagent instructions, governed by a feature flag.", + "codexSet.about.git-attribution": "Tells the model to add a Co-authored-by: Codex trailer to commits it writes, and a Generated with Codex. line to pull requests it opens. Codex resolves this from your account, so there is no setting for it here or under [features]. When your account has it off, Codex sends the opposite instruction rather than sending nothing.", "codexSet.condition.model-switch": "Emitted only after a mid-session model change.", "codexSet.condition.realtime": "Emitted only in a realtime session.", "codexSet.condition.agents-md": "Emitted when a project doc is found for the working directory.", "codexSet.condition.plugins": "Emitted when a plugin is selected or any plugin advertises a capability.", + "codexSet.condition.git-attribution": "Set by your account's attribution policy.", "nav.api": "API", "nav.integrations": "Integrations", "nav.openMenu": "Open menu", diff --git a/gui/src/i18n/fr.ts b/gui/src/i18n/fr.ts index 12678eaee3..e3682aafcc 100644 --- a/gui/src/i18n/fr.ts +++ b/gui/src/i18n/fr.ts @@ -1426,6 +1426,7 @@ export const fr: Record = { "codexSet.layer.plugins": "Plugins", "codexSet.layer.tools": "Outils", "codexSet.layer.multi-agent-mode": "Mode multi-agents", + "codexSet.layer.git-attribution": "Attribution des commits", "codexSet.about.base-instructions": "Instructions propres à Codex. Elles accompagnent la requête elle-même et ne peuvent pas être désactivées.", "codexSet.about.model-switch": "Ajouté lorsque le modèle change en cours de conversation.", "codexSet.about.personality": "Consignes de ton et de style, régies par un indicateur de fonctionnalité.", @@ -1441,10 +1442,12 @@ export const fr: Record = { "codexSet.about.tools": "Descriptions différées des outils, régies par un indicateur de fonctionnalité.", "codexSet.about.skills": "Liste des compétences disponibles.", "codexSet.about.multi-agent-mode": "Instructions pour les sous-agents, régies par un indicateur de fonctionnalité.", + "codexSet.about.git-attribution": "Demande au modèle d’ajouter un trailer Co-authored-by: Codex aux commits qu’il écrit, et une ligne Generated with Codex. aux pull requests qu’il ouvre. Codex lit ce réglage depuis votre compte : il n’est modifiable ni ici ni dans [features]. Si votre compte le désactive, Codex envoie l’instruction inverse au lieu de ne rien envoyer.", "codexSet.condition.model-switch": "Émis uniquement après un changement de modèle en cours de session.", "codexSet.condition.realtime": "Émis uniquement dans une session en temps réel.", "codexSet.condition.agents-md": "Émis lorsqu’un document de projet est trouvé pour le répertoire de travail.", "codexSet.condition.plugins": "Émis lorsqu’un plugin est sélectionné ou qu’un plugin déclare une capacité.", + "codexSet.condition.git-attribution": "Défini par la politique d’attribution de votre compte.", "nav.api": "API", "nav.integrations": "Intégrations", "nav.openMenu": "Ouvrir le menu", diff --git a/gui/src/i18n/ja.ts b/gui/src/i18n/ja.ts index 0d78de4c8f..4adb6f2941 100644 --- a/gui/src/i18n/ja.ts +++ b/gui/src/i18n/ja.ts @@ -1386,6 +1386,7 @@ export const ja: Record = { "codexSet.layer.plugins": "プラグイン", "codexSet.layer.tools": "ツール", "codexSet.layer.multi-agent-mode": "マルチエージェントモード", + "codexSet.layer.git-attribution": "コミットの帰属表示", "codexSet.about.base-instructions": "Codex 自体の指示です。リクエストに含まれ、無効にはできません。", "codexSet.about.model-switch": "会話の途中でセッションのモデルが変わると追加されます。", "codexSet.about.personality": "機能フラグで制御されるトーンと語調のガイダンスです。", @@ -1401,10 +1402,12 @@ export const ja: Record = { "codexSet.about.tools": "機能フラグで制御される遅延読み込みツールの説明です。", "codexSet.about.skills": "利用可能なスキルの一覧です。", "codexSet.about.multi-agent-mode": "機能フラグで制御されるサブエージェント向けの指示です。", + "codexSet.about.git-attribution": "モデルが書いたコミットに Co-authored-by: Codex トレーラーを、開いたプルリクエストに Generated with Codex. の行を追加させます。Codex がアカウントから取得するため、ここでも [features] でも変更できません。アカウント側で無効にすると、何も送らないのではなく逆の指示を送ります。", "codexSet.condition.model-switch": "セッション中にモデルが変わった後のみ含まれます。", "codexSet.condition.realtime": "リアルタイムセッションのみ含まれます。", "codexSet.condition.agents-md": "作業ディレクトリ用のプロジェクト文書が見つかると含まれます。", "codexSet.condition.plugins": "プラグインが選択されているか、プラグインが機能を提供すると含まれます。", + "codexSet.condition.git-attribution": "アカウントの帰属表示ポリシーで決まります。", "nav.api": "API", "nav.integrations": "連携", "nav.openMenu": "メニューを開く", diff --git a/gui/src/i18n/ko.ts b/gui/src/i18n/ko.ts index a4fd1c92db..af59d75dfd 100644 --- a/gui/src/i18n/ko.ts +++ b/gui/src/i18n/ko.ts @@ -985,6 +985,7 @@ export const ko: Record = { "codexSet.layer.plugins": "플러그인", "codexSet.layer.tools": "도구", "codexSet.layer.multi-agent-mode": "멀티 에이전트 모드", + "codexSet.layer.git-attribution": "커밋 어트리뷰션", "codexSet.about.base-instructions": "Codex 자체 지침입니다. 요청에 포함되며 끌 수 없습니다.", "codexSet.about.model-switch": "대화 도중 세션 모델이 바뀌면 추가됩니다.", "codexSet.about.personality": "기능 플래그로 제어되는 어조와 말투 지침입니다.", @@ -1000,10 +1001,12 @@ export const ko: Record = { "codexSet.about.tools": "기능 플래그로 제어되는 지연 로드 도구 설명입니다.", "codexSet.about.skills": "사용 가능한 스킬 목록입니다.", "codexSet.about.multi-agent-mode": "기능 플래그로 제어되는 서브에이전트 지침입니다.", + "codexSet.about.git-attribution": "모델이 작성한 커밋에 Co-authored-by: Codex 트레일러를, 새로 여는 풀 리퀘스트에 Generated with Codex. 한 줄을 붙이게 합니다. Codex가 계정에서 이 값을 가져오기 때문에 여기서도 [features]에서도 바꿀 수 없습니다. 계정에서 꺼두면 아무것도 보내지 않는 대신 반대 지시를 보냅니다.", "codexSet.condition.model-switch": "세션 도중 모델이 바뀐 뒤에만 포함됩니다.", "codexSet.condition.realtime": "실시간 세션에만 포함됩니다.", "codexSet.condition.agents-md": "작업 디렉터리에서 프로젝트 문서를 찾으면 포함됩니다.", "codexSet.condition.plugins": "플러그인을 선택했거나 플러그인이 기능을 제공하면 포함됩니다.", + "codexSet.condition.git-attribution": "계정의 어트리뷰션 정책이 결정합니다.", "nav.openMenu": "메뉴 열기", "nav.closeMenu": "메뉴 닫기", "integrations.subtitle": "클라이언트를 opencodex에 연결하고 자격 증명과 설정 복원을 관리합니다.", diff --git a/gui/src/i18n/ru.ts b/gui/src/i18n/ru.ts index 61eddd3aec..8868552928 100644 --- a/gui/src/i18n/ru.ts +++ b/gui/src/i18n/ru.ts @@ -1437,6 +1437,7 @@ export const ru: Record = { "codexSet.layer.plugins": "Плагины", "codexSet.layer.tools": "Инструменты", "codexSet.layer.multi-agent-mode": "Мультиагентный режим", + "codexSet.layer.git-attribution": "Атрибуция коммитов", "codexSet.about.base-instructions": "Собственные инструкции Codex. Они передаются вместе с запросом, и отключить их нельзя.", "codexSet.about.model-switch": "Добавляется при смене модели во время диалога.", "codexSet.about.personality": "Указания по тону и стилю, управляемые флагом функции.", @@ -1452,10 +1453,12 @@ export const ru: Record = { "codexSet.about.tools": "Описания отложенных инструментов, управляемые флагом функции.", "codexSet.about.skills": "Список доступных навыков.", "codexSet.about.multi-agent-mode": "Инструкции для подагентов, управляемые флагом функции.", + "codexSet.about.git-attribution": "Просит модель добавлять трейлер Co-authored-by: Codex в коммиты, которые она пишет, и строку Generated with Codex. в пул-реквесты, которые она открывает. Codex берёт это из вашей учётной записи, поэтому настройки нет ни здесь, ни в [features]. Если в учётной записи атрибуция отключена, Codex отправляет обратную инструкцию, а не молчит.", "codexSet.condition.model-switch": "Добавляется только после смены модели во время сеанса.", "codexSet.condition.realtime": "Добавляется только в сеансе реального времени.", "codexSet.condition.agents-md": "Добавляется, если для рабочего каталога найден документ проекта.", "codexSet.condition.plugins": "Добавляется, если выбран плагин или какой-либо плагин объявляет возможность.", + "codexSet.condition.git-attribution": "Определяется политикой атрибуции вашей учётной записи.", "nav.api": "API", "nav.integrations": "Интеграции", "nav.openMenu": "Открыть меню", diff --git a/gui/src/i18n/tr.ts b/gui/src/i18n/tr.ts index d1bb12bf00..e289716c8c 100644 --- a/gui/src/i18n/tr.ts +++ b/gui/src/i18n/tr.ts @@ -1444,6 +1444,7 @@ export const tr: Record = { "codexSet.layer.plugins": "Eklentiler", "codexSet.layer.tools": "Araçlar", "codexSet.layer.multi-agent-mode": "Çoklu ajan modu", + "codexSet.layer.git-attribution": "Commit atıfları", "codexSet.about.base-instructions": "Codex'in kendi talimatlarıdır. İstekle birlikte gönderilir ve kapatılamaz.", "codexSet.about.model-switch": "Oturum sırasında model değiştiğinde eklenir.", "codexSet.about.personality": "Bir özellik bayrağının yönettiği ton ve anlatım yönlendirmesi.", @@ -1459,10 +1460,12 @@ export const tr: Record = { "codexSet.about.tools": "Bir özellik bayrağının yönettiği ertelenmiş araç açıklamaları.", "codexSet.about.skills": "Kullanılabilir becerilerin listesi.", "codexSet.about.multi-agent-mode": "Bir özellik bayrağının yönettiği alt ajan talimatları.", + "codexSet.about.git-attribution": "Modelin yazdığı commit’lere Co-authored-by: Codex trailer’ını, açtığı pull request’lere de Generated with Codex. satırını eklemesini söyler. Codex bunu hesabınızdan okur; ne burada ne de [features] altında değiştirilebilir. Hesabınız kapattığında Codex hiçbir şey göndermek yerine tersi yönde talimat gönderir.", "codexSet.condition.model-switch": "Yalnızca oturum sırasında model değiştikten sonra eklenir.", "codexSet.condition.realtime": "Yalnızca gerçek zamanlı oturumlarda eklenir.", "codexSet.condition.agents-md": "Çalışma dizini için bir proje belgesi bulunduğunda eklenir.", "codexSet.condition.plugins": "Bir eklenti seçildiğinde veya herhangi bir eklenti bir yetenek bildirdiğinde eklenir.", + "codexSet.condition.git-attribution": "Hesabınızın atıf politikası belirler.", "nav.api": "API", "nav.integrations": "Entegrasyonlar", "nav.openMenu": "Menüyü aç", diff --git a/gui/src/i18n/zh-TW.ts b/gui/src/i18n/zh-TW.ts index 27118c4eb1..ed80ea0c83 100644 --- a/gui/src/i18n/zh-TW.ts +++ b/gui/src/i18n/zh-TW.ts @@ -1219,6 +1219,7 @@ export const zhTW: Record = { "codexSet.layer.plugins": "外掛程式", "codexSet.layer.tools": "工具", "codexSet.layer.multi-agent-mode": "多代理模式", + "codexSet.layer.git-attribution": "提交署名", "codexSet.about.base-instructions": "Codex 自身的指令。它們會隨請求一同傳送,無法關閉。", "codexSet.about.model-switch": "工作階段中途切換模型時新增。", "codexSet.about.personality": "語氣和表達風格指引,由功能開關控制。", @@ -1234,10 +1235,12 @@ export const zhTW: Record = { "codexSet.about.tools": "延後載入的工具說明,由功能開關控制。", "codexSet.about.skills": "可用技能清單。", "codexSet.about.multi-agent-mode": "子代理指令,由功能開關控制。", + "codexSet.about.git-attribution": "讓模型在它寫的提交加上 Co-authored-by: Codex 尾註,並在它開的拉取請求加上 Generated with Codex. 這一行。Codex 從你的帳號讀取此項,所以這裡和 [features] 都改不了。帳號關閉時,Codex 會送出相反的指令,而不是什麼都不送。", "codexSet.condition.model-switch": "僅在工作階段中途切換模型後插入。", "codexSet.condition.realtime": "僅在即時工作階段中插入。", "codexSet.condition.agents-md": "找到適用於目前工作目錄的專案文件時插入。", "codexSet.condition.plugins": "選取外掛程式或任一外掛程式宣告功能時插入。", + "codexSet.condition.git-attribution": "由你帳號的署名政策決定。", "nav.api": "API", "nav.openMenu": "開啟選單", "nav.closeMenu": "關閉選單", diff --git a/gui/src/i18n/zh.ts b/gui/src/i18n/zh.ts index 98567b595d..fa3e98d23a 100644 --- a/gui/src/i18n/zh.ts +++ b/gui/src/i18n/zh.ts @@ -978,6 +978,7 @@ export const zh: Record = { "codexSet.layer.plugins": "插件", "codexSet.layer.tools": "工具", "codexSet.layer.multi-agent-mode": "多代理模式", + "codexSet.layer.git-attribution": "提交署名", "codexSet.about.base-instructions": "Codex 自身的指令。它们随请求一同发送,无法关闭。", "codexSet.about.model-switch": "会话中途切换模型时添加。", "codexSet.about.personality": "语气和表达风格指引,由功能开关控制。", @@ -993,10 +994,12 @@ export const zh: Record = { "codexSet.about.tools": "延迟加载的工具说明,由功能开关控制。", "codexSet.about.skills": "可用技能列表。", "codexSet.about.multi-agent-mode": "子代理指令,由功能开关控制。", + "codexSet.about.git-attribution": "让模型在它写的提交里加上 Co-authored-by: Codex 尾注,并在它开的拉取请求里加上 Generated with Codex. 这一行。Codex 从你的账号读取此项,所以这里和 [features] 都改不了。账号关闭时,Codex 会发送相反的指令,而不是什么都不发。", "codexSet.condition.model-switch": "仅在会话中途切换模型后注入。", "codexSet.condition.realtime": "仅在实时会话中注入。", "codexSet.condition.agents-md": "找到适用于当前工作目录的项目文档时注入。", "codexSet.condition.plugins": "选中插件或任一插件声明功能时注入。", + "codexSet.condition.git-attribution": "由你账号的署名策略决定。", "nav.openMenu": "打开菜单", "nav.closeMenu": "关闭菜单", "integrations.subtitle": "将客户端连接到 opencodex,管理凭据并恢复客户端配置。", diff --git a/gui/src/pages/codex-set-prompt.tsx b/gui/src/pages/codex-set-prompt.tsx index d282d66fc0..4082b0f247 100644 --- a/gui/src/pages/codex-set-prompt.tsx +++ b/gui/src/pages/codex-set-prompt.tsx @@ -319,9 +319,15 @@ export default function CodexSetPrompt({ apiBase }: { apiBase: string }) { }; // Assembly order, so the list reads the way the prompt is actually built. // Every class renders; the row decides what each one gets. + // + // A null order means the position is registration-order dependent rather than fixed + // in world_state.rs - an extension-contributed section. Those sort AFTER every known + // position instead of collapsing to 0, which would have put them at the very top and + // claimed they are assembled first. The stable fallback keeps two such layers in + // inventory order relative to each other rather than swapping unpredictably. const rows = [...(snapshot?.inventory ?? [])] .filter(d => d.class !== "extension-unknown") - .sort((a, b) => (a.order ?? 0) - (b.order ?? 0)); + .sort((a, b) => (a.order ?? Number.MAX_SAFE_INTEGER) - (b.order ?? Number.MAX_SAFE_INTEGER)); /** * Two kinds of layer, split by what they ARE rather than by a scope flag. diff --git a/gui/tests/codex-set-prompt-layers.test.tsx b/gui/tests/codex-set-prompt-layers.test.tsx index b110a19c26..db1cb9ecb3 100644 --- a/gui/tests/codex-set-prompt-layers.test.tsx +++ b/gui/tests/codex-set-prompt-layers.test.tsx @@ -359,3 +359,82 @@ test("the layer-text rule outranks .api-code so long bodies wrap", () => { expect(rule![1]).toContain("overflow-wrap: anywhere"); expect(rule![1]).toContain("overflow-x: hidden"); }); + +/** + * The layer `ext/git-attribution` contributes. + * + * Three things have to be true at once, and each would be wrong on its own: it appears + * at all, it has NO switch, and it does not claim to be "always on". The last is the + * one a reader is most likely to get wrong - the account can turn attribution off, and + * when it does Codex sends the opposite instruction rather than sending nothing, so + * neither "always on" nor "sometimes absent" describes it. + */ +test("git-attribution renders as a conditional row with no switch", async () => { + stubRoutes(() => json(snapshot())); + const { container, root } = await mount(); + + const el = row(container, "git-attribution"); + expect(el).not.toBeNull(); + // No switch anywhere in the row: not a disabled one either, which would claim a + // capability Codex does not expose. + expect(el!.querySelector("[role=\"switch\"]")).toBeNull(); + // The locked note, not the feature-gated one - there is no [features] key to link to. + expect(el!.querySelector(".codex-set-prompt__note--locked")).not.toBeNull(); + // No [features] link INSIDE the note. Querying `.link-btn` across the whole row would + // always find one: the row's own name is a link-btn button that opens the dialog. + expect(el!.querySelector(".codex-set-prompt__note .link-btn")).toBeNull(); + // No key chip: the descriptor carries key: null because enablement is account-derived. + expect(el!.querySelector(".codex-set-prompt__key")).toBeNull(); + + // A registration-order layer sorts after every fixed position rather than to the top, + // and shows the neutral marker instead of inventing a number. + // + // Scoped to the STATE list: the transition notices render in their own list below, so + // "last in the document" would be a claim about the split rather than about ordering. + const stateList = container.querySelectorAll(".codex-set-prompt__rows")[0]!; + const stateIds = [...stateList.querySelectorAll("[data-layer-id]")].map(n => n.getAttribute("data-layer-id")); + expect(stateIds[stateIds.length - 1]).toBe("git-attribution"); + // And specifically NOT first, which is where a null order collapsing to 0 would put it. + expect(stateIds[0]).toBe("base-instructions"); + expect(el!.querySelector(".codex-set-prompt__pos")!.textContent).toBe("\u00b7"); + + // The dialog states the real condition. + await act(async () => { + (el!.querySelector("button") as HTMLButtonElement).click(); + }); + const dialog = document.querySelector("dialog.modal-overlay")!; + expect(dialog.textContent ?? "").toContain("attribution policy"); + await act(async () => { root.unmount(); }); +}); + +/** + * A conditional row must not claim to be unconditional. + * + * Caught by rendering the real page in a browser rather than by a unit test: the DOM + * showed `git-attribution` and `plugins` both labelled "Always on" while their dialogs + * described a condition. The condition map existed and only the dialog read it, so the + * two surfaces disagreed about the same layer. + * + * Table-driven over every layer that HAS a condition, so the next one added is covered + * without a new test - and the negative half proves the assertion is not vacuous. + */ +test("a row with a condition shows it instead of \"Always on\"", async () => { + stubRoutes(() => json(snapshot())); + const { container, root } = await mount(); + + // Conditions live on runtime-conditional layers; the transition notices are excluded + // because "it fires on a change" is their own distinct wording. + const conditional = ["plugins", "agents-md", "git-attribution"]; + for (const id of conditional) { + const note = row(container, id)!.querySelector(".codex-set-prompt__note--locked")!; + expect(note.textContent, id).not.toBe("Always on"); + expect((note.textContent ?? "").length, id).toBeGreaterThan(0); + } + + // base-instructions genuinely IS always on: no condition, no off-switch anywhere. If + // this drifted the test above would pass for the wrong reason. + const base = row(container, "base-instructions")!.querySelector(".codex-set-prompt__note--locked")!; + expect(base.textContent).toBe("Always on"); + + await act(async () => { root.unmount(); }); +}); diff --git a/src/codex/prompt-layers.ts b/src/codex/prompt-layers.ts index 301cb60b95..f33cc96426 100644 --- a/src/codex/prompt-layers.ts +++ b/src/codex/prompt-layers.ts @@ -100,6 +100,24 @@ export const LAYER_INVENTORY: readonly LayerDescriptor[] = Object.freeze([ { id: "tools", class: "feature-gated", key: "features.deferred_tool_world_state", default: false, order: 12 }, { id: "skills", class: "config-toggle", key: "skills.include_instructions", default: true, order: 13 }, { id: "multi-agent-mode", class: "feature-gated", key: "features.multi_agent_v2.enabled", default: false, order: 14 }, + /** + * Commit and pull-request attribution, contributed by `ext/git-attribution` rather + * than by a world_state.rs section — which is why it is absent from the order list + * above and carries `order: null`: it registers through + * `extensions.context_contributors()` (`core/src/session/world_state.rs:64-66`), + * whose position is registration-order dependent. + * + * `runtime-conditional`, NOT feature-gated. `ext/git-attribution/src/lib.rs:33-80` + * resolves enablement from the AUTH SERVER via `resolve_attribution_policy`, caches + * it on the thread store, and falls back to disabled when the lookup fails. + * `features/src/lib.rs:277` records the old config flag as removed, so there is no + * key for this GUI to write and nothing in [features] to point a user at. + * + * Both states emit text: enabled sends the `Co-authored-by: Codex` trailer plus the + * `Generated with Codex.` PR marker, disabled sends an explicit countermand. So the + * row's condition line must name the policy rather than claiming "always on". + */ + { id: "git-attribution", class: "runtime-conditional", key: null, default: null, order: null }, ] as const); /** diff --git a/src/codex/prompt-text-probe.ts b/src/codex/prompt-text-probe.ts index 99535a1b6b..6db8d1e49e 100644 --- a/src/codex/prompt-text-probe.ts +++ b/src/codex/prompt-text-probe.ts @@ -60,6 +60,13 @@ const UNMAPPED_LAYER_IDS = [ "personality", "realtime", "collaboration", + // The Rust source names a marker pair, but a world-state section is + // DIFF-rendered: it emits nothing on a turn where its state has not changed. Live + // `codex debug prompt-input` (codex-cli 0.145.0, 32978 bytes) showed no such block and + // no attribution text. Listing the id here reports "not exposed" honestly instead of + // claiming a tag this extractor has never actually matched - the same mistake the + // header above records for permissions. + "git-attribution", ] as const; export interface LayerText { diff --git a/tests/codex-prompt-layers.test.ts b/tests/codex-prompt-layers.test.ts index 63b06c14bf..686f75adbb 100644 --- a/tests/codex-prompt-layers.test.ts +++ b/tests/codex-prompt-layers.test.ts @@ -53,6 +53,25 @@ describe("inventory", () => { expect(base?.class).toBe("base"); expect(isToggleId("base-instructions")).toBe(false); }); + + test("git-attribution is runtime-conditional with no key and no fixed order", () => { + // The layer ext/git-attribution contributes. Its shape is the whole assertion: + // `runtime-conditional` because lib.rs:33-80 resolves enablement from the auth + // server rather than a config key (features/src/lib.rs:277 records the old flag as + // removed), and `order: null` because it registers through + // extensions.context_contributors(), whose position is registration-order dependent. + // + // Refusal at the route is NOT re-asserted here: codex-prompt-route.test.ts case 5 + // already drives the real endpoint table-driven over every non-config-toggle + // descriptor, so a second guard would duplicate coverage rather than add it. + const layer = LAYER_INVENTORY.find(d => d.id === "git-attribution"); + expect(layer).toBeDefined(); + expect(layer?.class).toBe("runtime-conditional"); + expect(layer?.key).toBeNull(); + expect(layer?.order).toBeNull(); + expect(layer?.default).toBeNull(); + expect(isToggleId("git-attribution")).toBe(false); + }); }); describe("normalization", () => {