From 7bc82093b32b0e4f22882e5dfa3cbe682d2dd1cb Mon Sep 17 00:00:00 2001 From: Dormon Zhou Date: Sun, 7 Jun 2026 11:48:39 +0800 Subject: [PATCH 1/3] feat: index the Salesforce stack (Apex, LWC, Aura, Visualforce) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add end-to-end indexing for Salesforce projects as one connected graph: - Apex (.cls/.trigger): vendored tree-sitter-apex.wasm (ABI 15) + declarative extractor — classes, interfaces, enums, methods, constructors, properties, triggers, inner classes; call/extends/implements edges; annotations. - Visualforce (.page/.component), Aura (.cmp/.app/.evt/.intf), and LWC HTML templates (lwc/*.html): custom markup extractors (one component node per file). - Cross-layer salesforce.ts resolver: LWC/Aura JS @salesforce/apex imports -> Apex method; VF controller=/extensions=/ -> Apex class/component; Aura cmp.get("c.x") -> Apex method. Apex stays its own language family so the framework gate keeps these cross-language edges. Validated: check-grammar PASS (ABI 15); verify-extraction PASS on ebikes-lwc, dreamhouse-lwc, apex-recipes; agent A/B (claude -p, Opus 4.8) shows the LWC->Apex flow answered by one codegraph_explore with 0 Read/0 Grep vs 4-9 Read without. 17 extraction tests; full suite 1257 passed / 0 failed. Docs: README supported-languages + coverage tables, CHANGELOG, coverage playbook entry, docs/design/salesforce-stack.md, agent-eval corpus. --- .claude/skills/agent-eval/corpus.json | 5 + CHANGELOG.md | 3 + README.md | 9 +- __tests__/extraction.test.ts | 325 ++++++++++++++++++ .../dynamic-dispatch-coverage-playbook.md | 2 + docs/design/salesforce-stack.md | 92 +++++ src/extraction/aura-extractor.ts | 129 +++++++ src/extraction/extraction-version.ts | 7 +- src/extraction/grammars.ts | 45 ++- src/extraction/languages/apex.ts | 80 +++++ src/extraction/languages/index.ts | 2 + src/extraction/lwc-template-extractor.ts | 113 ++++++ src/extraction/tree-sitter.ts | 69 ++++ src/extraction/visualforce-extractor.ts | 138 ++++++++ src/extraction/wasm/tree-sitter-apex.wasm | Bin 0 -> 1659024 bytes src/resolution/frameworks/index.ts | 4 + src/resolution/frameworks/salesforce.ts | 153 +++++++++ src/types.ts | 4 + 18 files changed, 1174 insertions(+), 6 deletions(-) create mode 100644 docs/design/salesforce-stack.md create mode 100644 src/extraction/aura-extractor.ts create mode 100644 src/extraction/languages/apex.ts create mode 100644 src/extraction/lwc-template-extractor.ts create mode 100644 src/extraction/visualforce-extractor.ts create mode 100755 src/extraction/wasm/tree-sitter-apex.wasm create mode 100644 src/resolution/frameworks/salesforce.ts diff --git a/.claude/skills/agent-eval/corpus.json b/.claude/skills/agent-eval/corpus.json index 2cfedac4f..d842b4617 100644 --- a/.claude/skills/agent-eval/corpus.json +++ b/.claude/skills/agent-eval/corpus.json @@ -94,5 +94,10 @@ { "name": "react-native-segmented-control", "repo": "https://github.com/react-native-segmented-control/segmented-control", "size": "Small", "files": "~25", "question": "How does JSX `` reach the native onChange handler on iOS/Android?" }, { "name": "react-native-screens", "repo": "https://github.com/software-mansion/react-native-screens", "size": "Medium", "files": "~1200", "question": "How does JSX `` reach the native RNSScreenStackView component?" }, { "name": "react-native-skia", "repo": "https://github.com/Shopify/react-native-skia", "size": "Large", "files": "~1000", "question": "How does a `` JSX usage reach the iOS / Android native renderer?" } + ], + "Salesforce (Apex + LWC + Aura + Visualforce)": [ + { "name": "dreamhouse-lwc", "repo": "https://github.com/trailheadapps/dreamhouse-lwc", "size": "Small", "files": "~176", "question": "How does the propertyTileList component reach the Apex that queries property records?" }, + { "name": "ebikes-lwc", "repo": "https://github.com/trailheadapps/ebikes-lwc", "size": "Small", "files": "~182", "question": "How does the orderBuilder LWC reach the Apex OrderController that updates order items?" }, + { "name": "apex-recipes", "repo": "https://github.com/trailheadapps/apex-recipes", "size": "Medium", "files": "~432", "question": "How does an LWC recipe invoke its Apex controller method, and what does that method call in turn?" } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 06de7752f..310c82dec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,9 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - ASP.NET Razor (`.cshtml`) and Blazor (`.razor`) markup are now parsed for code relationships. A `@model` / `@inherits` / `@inject` directive links the view to the C# view-model, base type, or service it names; a Blazor `` tag (plus `@typeof(...)` and generic `TItem="..."` arguments) links to the component class; and the C# inside `@code { }` / `@functions { }` / `@{ }` blocks is analyzed too, so services and types used in component logic are linked. A view-model, component, or service referenced only from markup is no longer reported as having no dependents, and editing it surfaces the views that use it. (ASP.NET, Blazor) - A Razor/Blazor type reference now resolves through the component's `@using` namespaces — including the folder's cascading `_Imports.razor` — so a simple name that exists in several namespaces lands on the right one. A `@model` / `` / `@code` reference to `CatalogBrand` resolves to the `@using`'d DTO (`BlazorShared.Models.CatalogBrand`) rather than a same-named domain entity. (ASP.NET, Blazor) - `codegraph status --json` now also reports the running CLI `version`, the index directory (`indexPath`), and a `lastIndexed` timestamp (ISO-8601, or null when nothing's indexed yet), so CI and scripts can pin the CLI version and check index freshness from a single command. A matching `CodeGraph.getLastIndexedAt()` library method exposes the same freshness check without shelling out. Thanks @12122J and @eddieran. (#329) +- CodeGraph now indexes **Salesforce Apex** (`.cls`, `.trigger`) — classes, interfaces, enums, methods, constructors, properties, triggers, and inner classes, with call edges, `extends`/`implements`, and `@AuraEnabled`/`@RemoteAction` annotations. A class that another class or a trigger calls now shows its callers, and impact/blast-radius work across Apex. +- CodeGraph now connects the **Salesforce front end to its Apex back end** as one graph. A Lightning Web Component that imports an Apex method (`import getX from '@salesforce/apex/MyController.getX'`) links to that method; a Visualforce page links to its `controller=` and `extensions=` Apex classes; and an Aura component's controller/helper links to the Apex it calls via `cmp.get("c.method")`. So editing an Apex method now surfaces every LWC, Aura, and Visualforce file that depends on it. (Apex, LWC, Aura, Visualforce) +- CodeGraph now indexes **Salesforce UI markup** — Visualforce pages and components (`.page`, `.component`), Aura components (`.cmp`, `.app`, `.evt`, `.intf`), and Lightning Web Component templates (`.html` inside an `lwc` bundle). Custom component usage (`` in Visualforce/Aura, `` in LWC) links each parent to the child component it renders, so the component tree is navigable. A Visualforce `standardController` is left unlinked because it names a Salesforce object, not an Apex class. (LWC, Aura, Visualforce) ### Fixes diff --git a/README.md b/README.md index 7c7b84a9e..9dc197837 100644 --- a/README.md +++ b/README.md @@ -225,7 +225,7 @@ CodeGraph cuts **tokens, tool calls, and wall-clock time on every repo** — acr | **Full-Text Search** | Find code by name instantly across your entire codebase, powered by FTS5 | | **Impact Analysis** | Trace callers, callees, and the full impact radius of any symbol before making changes | | **Always Fresh** | File watcher uses native OS events (FSEvents/inotify/ReadDirectoryChangesW) with debounced auto-sync — the graph stays current as you code, zero config | -| **20+ Languages** | TypeScript, JavaScript, Python, Go, Rust, Java, C#, PHP, Ruby, C, C++, Objective-C, Swift, Kotlin, Dart, Lua, Luau, Svelte, Liquid, Pascal/Delphi | +| **20+ Languages** | TypeScript, JavaScript, Python, Go, Rust, Java, C#, PHP, Ruby, C, C++, Objective-C, Swift, Kotlin, Dart, Lua, Luau, Svelte, Liquid, Pascal/Delphi, Apex, Visualforce, Aura, LWC | | **Framework-aware Routes** | Recognizes web-framework routing files and links URL patterns to their handlers across 14 frameworks | | **Mixed iOS / React Native / Expo** | Closes cross-language flows that static parsing misses: Swift ↔ ObjC bridging, React Native legacy bridge + TurboModules + Fabric view components, native → JS event emitters, Expo Modules | | **100% Local** | No data leaves your machine. No API keys. No external services. SQLite database only | @@ -638,6 +638,10 @@ is written): | Pascal / Delphi | `.pas`, `.dpr`, `.dpk`, `.lpr` | Full support (classes, records, interfaces, enums, DFM/FMX form files) | | Lua | `.lua` | Full support (functions, methods with receivers, local variables, `require` imports, call edges) | | Luau | `.luau` | Full support (everything in Lua, plus `type`/`export type` aliases, typed signatures, and Roblox instance-path `require`) | +| Apex | `.cls`, `.trigger` | Full support (classes, interfaces, enums, methods, constructors, properties, triggers, inner classes; call/extends/implements edges; `@AuraEnabled`/`@RemoteAction` annotations) | +| Visualforce | `.page`, `.component` | Markup support (page/component → `controller=`/`extensions=` Apex classes and `` components; `standardController` left unlinked) | +| Aura | `.cmp`, `.app`, `.evt`, `.intf` | Markup support (component → `` components and `{!c.handler}` controller actions; controller/helper JS handlers → Apex via `cmp.get("c.x")`) | +| Lightning Web Components | `.js` + `.html` | Full support (the `.js` via JavaScript; the template links `` components and the `@salesforce/apex/...` import links to the Apex method) | ## Measured cross-file coverage @@ -666,9 +670,12 @@ Impact and blast-radius queries are only as good as the dependency graph behind | Luau | dphfox/Fusion | 92.2% | | Liquid | Shopify/dawn | 73.8% | | Pascal / Delphi | PascalCoin | 75.7% | +| Apex (+ LWC / Aura / Visualforce → Apex) | trailheadapps/ebikes-lwc | 55.6% | Framework routing is validated the same way, on a canonical app per framework: Express 100%, FastAPI 98%, Flask 100%, NestJS 96.8%, Gin 96.5%, Axum 100%, Rocket 93.8%, Vapor 100%, Laravel 92%, Rails 89.6%, React Router 100% — and the convention/reflection-heavy ones at their honest static-analysis ceiling: ASP.NET 83.9%, Spring 83.3%, Drupal 78.9%, Django 74.1%. +The **Salesforce** number reflects a quirk of the platform, not the extractor: every non-test Apex class in ebikes-lwc that something depends on is covered — the residual is the mandatory `*Test` classes (the platform requires a test class per class, and nothing in code depends on a test) plus one class referenced only from metadata XML. The novel coverage here is *cross-layer*: a Lightning Web Component's `@salesforce/apex/...` import resolves to the Apex method, a Visualforce page's `controller=`/`extensions=` resolve to their Apex classes, and an Aura controller's `cmp.get("c.x")` resolves to the Apex method — so editing Apex surfaces the LWC/Aura/Visualforce that depend on it. + ## Troubleshooting **"CodeGraph not initialized"** — Run `codegraph init` in your project directory first. diff --git a/__tests__/extraction.test.ts b/__tests__/extraction.test.ts index f4a0ace03..9012006d3 100644 --- a/__tests__/extraction.test.ts +++ b/__tests__/extraction.test.ts @@ -6376,3 +6376,328 @@ describe('Swift property wrappers / attributes (blast-radius recall)', () => { } finally { cleanupTempDir(dir); } }); }); + +describe('Apex Extraction', () => { + it('extracts class/interface/enum/inner-class/static-method/trigger symbols', () => { + const code = `public class AccountService extends BaseService implements IService { + public static Integer COUNT = 0; + public String label { get; set; } + + public AccountService() { COUNT = 1; } + + @AuraEnabled + public static String greet(String who) { + Helper h = new Helper(); + return h.format(who); + } + + public enum Status { ACTIVE, CLOSED } + + public class Inner { + public Integer bump(Integer n) { return n + 1; } + } +}`; + const result = extractFromSource('AccountService.cls', code); + + const cls = result.nodes.find((n) => n.kind === 'class' && n.name === 'AccountService'); + expect(cls).toBeDefined(); + expect(cls?.visibility).toBe('public'); + + const inner = result.nodes.find((n) => n.kind === 'class' && n.name === 'Inner'); + expect(inner).toBeDefined(); + + const greet = result.nodes.find((n) => n.kind === 'method' && n.name === 'greet'); + expect(greet).toBeDefined(); + expect(greet?.isStatic).toBe(true); + + const status = result.nodes.find((n) => n.kind === 'enum' && n.name === 'Status'); + expect(status).toBeDefined(); + + // extends BaseService / implements IService + const extendsRefs = result.unresolvedReferences.filter((r) => r.referenceKind === 'extends'); + expect(extendsRefs.map((r) => r.referenceName)).toContain('BaseService'); + const implRefs = result.unresolvedReferences.filter((r) => r.referenceKind === 'implements'); + expect(implRefs.map((r) => r.referenceName)).toContain('IService'); + + // @AuraEnabled annotation captured as a `decorates` reference + const decorRefs = result.unresolvedReferences.filter((r) => r.referenceKind === 'decorates'); + expect(decorRefs.map((r) => r.referenceName)).toContain('AuraEnabled'); + + // cross-class call greet -> format (receiver kept until resolution) + const callRefs = result.unresolvedReferences.filter((r) => r.referenceKind === 'calls'); + expect(callRefs.some((r) => r.referenceName.endsWith('format'))).toBe(true); + }); + + it('extracts a trigger and its handler call', () => { + const code = `trigger AccountTrigger on Account (before insert, after update) { + AccountService.greet('world'); +}`; + const result = extractFromSource('AccountTrigger.trigger', code); + + const trigger = result.nodes.find((n) => n.name === 'AccountTrigger'); + expect(trigger).toBeDefined(); + expect(trigger?.signature).toContain('Account'); + + const callRefs = result.unresolvedReferences.filter((r) => r.referenceKind === 'calls'); + expect(callRefs.some((r) => r.referenceName.endsWith('greet'))).toBe(true); + }); + + it('resolves cross-file caller→callee edges across .cls and .trigger', async () => { + const dir = createTempDir(); + try { + const classes = path.join(dir, 'force-app/main/default/classes'); + const triggers = path.join(dir, 'force-app/main/default/triggers'); + fs.mkdirSync(classes, { recursive: true }); + fs.mkdirSync(triggers, { recursive: true }); + + fs.writeFileSync(path.join(classes, 'Helper.cls'), + `public class Helper {\n public String format(String who) { return 'Hi ' + who; }\n}\n`); + fs.writeFileSync(path.join(classes, 'AccountService.cls'), + `public class AccountService {\n public static String greet(String who) {\n Helper h = new Helper();\n return h.format(who);\n }\n}\n`); + fs.writeFileSync(path.join(triggers, 'AccountTrigger.trigger'), + `trigger AccountTrigger on Account (before insert) {\n AccountService.greet('world');\n}\n`); + + const cg = CodeGraph.initSync(dir, { + config: { include: ['**/*.cls', '**/*.trigger'], exclude: [] }, + }); + const indexResult = await cg.indexAll(); + cg.resolveReferences(); + + expect(indexResult.filesIndexed).toBe(3); + // AccountService.greet() calls Helper.format() → Helper.cls has AccountService.cls as a dependent + expect(cg.getFileDependents('force-app/main/default/classes/Helper.cls')) + .toContain('force-app/main/default/classes/AccountService.cls'); + // AccountTrigger calls AccountService.greet() → AccountService.cls has the trigger as a dependent + expect(cg.getFileDependents('force-app/main/default/classes/AccountService.cls')) + .toContain('force-app/main/default/triggers/AccountTrigger.trigger'); + cg.destroy(); + } finally { cleanupTempDir(dir); } + }); +}); + +describe('Salesforce LWC → Apex resolver', () => { + it('links an LWC @salesforce/apex import to the Apex method node', async () => { + const dir = createTempDir(); + try { + const classes = path.join(dir, 'force-app/main/default/classes'); + const lwc = path.join(dir, 'force-app/main/default/lwc/acctList'); + fs.mkdirSync(classes, { recursive: true }); + fs.mkdirSync(lwc, { recursive: true }); + + fs.writeFileSync(path.join(classes, 'AccountController.cls'), + `public with sharing class AccountController {\n @AuraEnabled(cacheable=true)\n public static List getAccounts() { return [SELECT Id FROM Account]; }\n}\n`); + fs.writeFileSync(path.join(lwc, 'acctList.js'), + `import { LightningElement, wire } from 'lwc';\n` + + `import getAccounts from '@salesforce/apex/AccountController.getAccounts';\n` + + `export default class AcctList extends LightningElement {\n` + + ` @wire(getAccounts) accounts;\n` + + ` refresh() { getAccounts({ limit: 10 }).then(r => { this.data = r; }); }\n` + + `}\n`); + + const cg = CodeGraph.initSync(dir, { + config: { include: ['**/*.cls', '**/*.js'], exclude: [] }, + }); + await cg.indexAll(); + cg.resolveReferences(); + + // The Apex method node exists with qualifiedName Class::method. + const apexMethod = cg.searchNodes('getAccounts', { limit: 20 }) + .map((r) => r.node) + .find((n) => n.kind === 'method' && n.qualifiedName === 'AccountController::getAccounts'); + expect(apexMethod).toBeDefined(); + + // Cross-layer edge is queryable: the LWC .js depends on the Apex .cls. + expect(cg.getFileDependents('force-app/main/default/classes/AccountController.cls')) + .toContain('force-app/main/default/lwc/acctList/acctList.js'); + + // getCallers on the Apex method surfaces the LWC call site. + const callers = cg.getCallers(apexMethod!.id).map((c: any) => (c.node ? c.node : c)); + expect(callers.some((c: any) => (c.filePath || '').includes('/lwc/'))).toBe(true); + cg.destroy(); + } finally { cleanupTempDir(dir); } + }); +}); + +describe('Visualforce extraction + resolver', () => { + it('emits a component node and Tier-1 references (single file)', () => { + const code = ` + + +`; + const result = extractFromSource('force-app/main/default/pages/AccountPage.page', code); + + const comp = result.nodes.find((n) => n.kind === 'component' && n.language === 'visualforce'); + expect(comp?.name).toBe('AccountPage'); + + const refs = result.unresolvedReferences.filter((r) => r.referenceKind === 'references').map((r) => r.referenceName); + expect(refs).toContain('AccountController'); // controller + expect(refs).toContain('ExtA'); // extensions, split + expect(refs).toContain('ExtB'); + expect(refs).toContain('AccountCard'); // + expect(refs).not.toContain('pageBlock'); // apex: standard tag skipped + }); + + it('skips standardController (SObject, not an Apex class)', () => { + const code = ``; + const result = extractFromSource('force-app/main/default/pages/StdPage.page', code); + const refs = result.unresolvedReferences.map((r) => r.referenceName); + expect(refs).not.toContain('Account'); + }); + + it('resolves VF page → Apex controller/extension/component across files', async () => { + const dir = createTempDir(); + try { + const classes = path.join(dir, 'force-app/main/default/classes'); + const pages = path.join(dir, 'force-app/main/default/pages'); + const components = path.join(dir, 'force-app/main/default/components'); + fs.mkdirSync(classes, { recursive: true }); + fs.mkdirSync(pages, { recursive: true }); + fs.mkdirSync(components, { recursive: true }); + + fs.writeFileSync(path.join(classes, 'AccountController.cls'), + `public with sharing class AccountController {\n public List getAccounts() { return null; }\n}\n`); + fs.writeFileSync(path.join(classes, 'AccountExt.cls'), + `public with sharing class AccountExt {\n public AccountExt(ApexPages.StandardController c) {}\n}\n`); + fs.writeFileSync(path.join(components, 'AccountCard.component'), + `\n`); + fs.writeFileSync(path.join(pages, 'AccountPage.page'), + `\n \n\n`); + + const cg = CodeGraph.initSync(dir, { + config: { include: ['**/*.cls', '**/*.page', '**/*.component'], exclude: [] }, + }); + await cg.indexAll(); + cg.resolveReferences(); + + const page = 'force-app/main/default/pages/AccountPage.page'; + expect(cg.getFileDependents('force-app/main/default/classes/AccountController.cls')).toContain(page); + expect(cg.getFileDependents('force-app/main/default/classes/AccountExt.cls')).toContain(page); + expect(cg.getFileDependents('force-app/main/default/components/AccountCard.component')).toContain(page); + cg.destroy(); + } finally { cleanupTempDir(dir); } + }); +}); + +describe('LWC template extraction + resolver', () => { + it('emits a component node and references, ignoring base components', () => { + const code = ``; + const result = extractFromSource('force-app/main/default/lwc/acctList/acctList.html', code); + + const comp = result.nodes.find((n) => n.kind === 'component' && n.language === 'lwc'); + expect(comp?.name).toBe('acctList'); + + const refs = result.unresolvedReferences.filter((r) => r.referenceKind === 'references').map((r) => r.referenceName); + expect(refs).toContain('AcctTile'); // pascalized + expect(refs).not.toContain('Button'); // lightning-button base component skipped + }); + + it('does not index generic (non-LWC) .html files', () => { + expect(detectLanguage('force-app/main/default/lwc/acctList/acctList.html')).toBe('lwc'); + expect(detectLanguage('public/index.html')).toBe('unknown'); + expect(isSourceFile('public/index.html')).toBe(false); + }); + + it('resolves an LWC template to the child component class', async () => { + const dir = createTempDir(); + try { + const base = path.join(dir, 'force-app/main/default/lwc'); + const parent = path.join(base, 'acctList'); + const child = path.join(base, 'acctTile'); + fs.mkdirSync(parent, { recursive: true }); + fs.mkdirSync(child, { recursive: true }); + + fs.writeFileSync(path.join(parent, 'acctList.js'), + `import { LightningElement } from 'lwc';\nexport default class AcctList extends LightningElement {}\n`); + fs.writeFileSync(path.join(parent, 'acctList.html'), + `\n`); + fs.writeFileSync(path.join(child, 'acctTile.js'), + `import { LightningElement, api } from 'lwc';\nexport default class AcctTile extends LightningElement { @api record; }\n`); + + const cg = CodeGraph.initSync(dir, { + config: { include: ['**/*.js', '**/*.html'], exclude: [] }, + }); + await cg.indexAll(); + cg.resolveReferences(); + + expect(cg.getFileDependents('force-app/main/default/lwc/acctTile/acctTile.js')) + .toContain('force-app/main/default/lwc/acctList/acctList.html'); + cg.destroy(); + } finally { cleanupTempDir(dir); } + }); +}); + +describe('Aura extraction + resolver', () => { + it('emits a component node, references, and {!c.handler} calls', () => { + const code = ` + + + +`; + const result = extractFromSource('force-app/main/default/aura/AccountList/AccountList.cmp', code); + + const comp = result.nodes.find((n) => n.kind === 'component' && n.language === 'aura'); + expect(comp?.name).toBe('AccountList'); + + const refNames = result.unresolvedReferences.filter((r) => r.referenceKind === 'references').map((r) => r.referenceName); + expect(refNames).toContain('accountTile'); // + const callNames = result.unresolvedReferences.filter((r) => r.referenceKind === 'calls').map((r) => r.referenceName); + expect(callNames).toContain('doInit'); // {!c.doInit} + }); + + it('extracts Aura controller handlers and cmp.get("c.x") → Apex calls', () => { + const code = `({ + doInit : function(cmp, event, helper) { + var action = cmp.get("c.getAccounts"); + helper.process(cmp, action); + } +})`; + const result = extractFromSource('force-app/main/default/aura/AccountList/AccountListController.js', code); + + const handler = result.nodes.find((n) => n.name === 'doInit'); + expect(handler).toBeDefined(); // object-literal handler is now a node + + const callNames = result.unresolvedReferences.filter((r) => r.referenceKind === 'calls').map((r) => r.referenceName); + expect(callNames).toContain('getAccounts'); // cmp.get("c.getAccounts") bare name + }); + + it('does NOT extract object-literal handlers from non-Aura JS', () => { + const code = `({ doInit : function(cmp) { return cmp; } })`; + const result = extractFromSource('src/random.js', code); + expect(result.nodes.find((n) => n.name === 'doInit')).toBeUndefined(); + }); + + it('resolves Aura JS cmp.get and markup across files', async () => { + const dir = createTempDir(); + try { + const classes = path.join(dir, 'force-app/main/default/classes'); + const parent = path.join(dir, 'force-app/main/default/aura/AccountList'); + const child = path.join(dir, 'force-app/main/default/aura/accountTile'); + fs.mkdirSync(classes, { recursive: true }); + fs.mkdirSync(parent, { recursive: true }); + fs.mkdirSync(child, { recursive: true }); + + fs.writeFileSync(path.join(classes, 'AccountController.cls'), + `public with sharing class AccountController {\n @AuraEnabled public static List getAccounts() { return null; }\n}\n`); + fs.writeFileSync(path.join(parent, 'AccountList.cmp'), + `\n \n\n`); + fs.writeFileSync(path.join(parent, 'AccountListController.js'), + `({\n doInit : function(cmp) { var a = cmp.get("c.getAccounts"); }\n})\n`); + fs.writeFileSync(path.join(child, 'accountTile.cmp'), + `\n`); + + const cg = CodeGraph.initSync(dir, { + config: { include: ['**/*.cls', '**/*.cmp', '**/*.js'], exclude: [] }, + }); + await cg.indexAll(); + cg.resolveReferences(); + + // Aura JS → Apex (cmp.get string ref) + expect(cg.getFileDependents('force-app/main/default/classes/AccountController.cls')) + .toContain('force-app/main/default/aura/AccountList/AccountListController.js'); + // Aura markup → child component () + expect(cg.getFileDependents('force-app/main/default/aura/accountTile/accountTile.cmp')) + .toContain('force-app/main/default/aura/AccountList/AccountList.cmp'); + cg.destroy(); + } finally { cleanupTempDir(dir); } + }); +}); diff --git a/docs/design/dynamic-dispatch-coverage-playbook.md b/docs/design/dynamic-dispatch-coverage-playbook.md index aa65398e4..86848f990 100644 --- a/docs/design/dynamic-dispatch-coverage-playbook.md +++ b/docs/design/dynamic-dispatch-coverage-playbook.md @@ -258,6 +258,8 @@ Status legend: ✅ done+validated · 🔬 hole identified · ⬜ not started. | JS × Swift/Kotlin | Expo Modules | JS `requireNativeModule('X').fn(...)` → Swift/Kotlin `Function("fn") { ... }` | R (extract → synthetic method nodes) | ✅ **expo-modules framework extractor** — parses Swift/Kotlin `Module { Name("X"); Function("y") { ... }; AsyncFunction("z") { ... }; Property("w") { ... } }` literals and synthesizes `method` nodes named after each declaration. JS callsites resolve via existing name-matcher (no separate `resolve()` needed). expo-haptics S **6 method nodes** (`notificationAsync`, `impactAsync`, `selectionAsync` × Swift + Kotlin), expo-camera M **41** (full SDK surface incl. `takePictureAsync`, `record`, `scanFromURLAsync`, view props `width`/`height`), expo SDK sweep L **134** (7 packages, 72 Swift + 62 Kotlin). Same-name JS wrappers in the package itself shadow the native names (`CameraView.tsx`'s `pausePreview` wraps native `pausePreview`); external consumer apps bridge through to native directly. 🔬 closure body extraction (the Function trailing closure isn't a body-range node yet) | | JS × native | React Native Fabric / Codegen + legacy Paper view components | JSX `` → Codegen spec → native class (or Paper `RCT_EXPORT_VIEW_PROPERTY` / `@ReactProp`) | R (extract) + S (native-impl) + JSX | ✅ **fabric-view extractor + fabric-native-impl synthesizer** — extractor parses **both** modern Codegen TS specs (`codegenNativeComponent('Name', ...)`) **and** legacy Paper view-manager macros (`RCT_EXPORT_VIEW_PROPERTY` on ObjC, `@ReactProp` on Java/Kotlin). Emits a `component` node per declaration + a `property` node per declared prop. Synthesizer links the component to its native impl class by RN's convention-based name+suffix (`exact`/`View`/`ComponentView`/`Manager`/`ViewManager`). Combined with `reactJsxChildEdges`, full consumer flow: JSX `` → fabric `component` → native class. Validated on RNSegmentedControl S **(legacy Paper) 1 component + 11 props + 4 bridges**, RNScreens M **(pure Codegen) 27 components + 272 props + 68 bridges** (was 0 before Phase 6), RNSkia L **(hybrid + monorepo) 5 + 14 + 15 across Codegen TS + Android Java + iOS ObjC**. **Monorepo detect** added: probes `packages//package.json` etc. via `listDirectories` when the root manifest is a workspace declaration (was the gating bug on RNSkia). 🔬 Fabric event-handler props (`onTap={cb}`) — JSX attribute extraction needed | +| Apex × LWC/Aura/Visualforce | Salesforce DX | UI → Apex `@AuraEnabled` method; page → controller; child component usage | X + R | ✅ **Apex grammar** (vendored `tree-sitter-apex.wasm`, ABI 15 — `check-grammar` PASS) extracts classes/interfaces/enums/methods/triggers/inner classes with call + extends/implements edges + `@AuraEnabled`/`@RemoteAction` annotations. **Markup extractors** (`visualforce-extractor.ts`, `aura-extractor.ts`, `lwc-template-extractor.ts`) emit one `component` node per file + reference/call refs (``/``, `{!c.handler}`). **Cross-layer `salesforce.ts` resolver**: LWC/Aura JS `import x from '@salesforce/apex/Class.method'` → Apex method (`imports`), VF `controller=`/`extensions=`/`` → Apex class/component (`references`), Aura `cmp.get("c.x")` → Apex method (`calls`, cross-language). Apex stays its own language family so `gateFrameworkLanguage` keeps these cross-layer edges (no LANGUAGE_FAMILY change needed). **Deterministic validation** (`verify-extraction` PASS, real repos): ebikes-lwc S (182 files, langs apex+aura+lwc+visualforce detected; cross-layer edges: 16 js→apex imports, 1 vf→apex, 17 lwc→child) · dreamhouse-lwc S (176 files) · apex-recipes M (432 files; 10 js→apex imports + 5 calls). Apex fair coverage 55.6% on ebikes — the residual is Salesforce's mandatory `*Test` classes (nothing in code depends on a test) + one metadata-only class; every non-test business class with a dependent is covered. **Agent A/B (headless `claude -p`, Opus 4.8, `--strict-mcp-config`):** ebikes-lwc (n=2, "how does orderBuilder LWC reach the Apex OrderController"): WITH = **0 Read / 0 Grep**, 1–2 `codegraph_explore` calls, 27–30s; WITHOUT = 5–9 Read + 10–16 Bash, 61–90s. apex-recipes (n=1, "how does an LWC recipe invoke its Apex controller"): WITH = **0 Read**, 1 explore, 33s, $0.31; WITHOUT = 4 Read + 6 Bash, 47s, 11 turns, $0.36. **Both repos: a single `codegraph_explore` on the LWC→Apex flow answers with zero file reads and ~30–50% less wall-clock** — the agent rides the cross-layer edges. Cost is mixed (WITH higher on the lean small-repo native baseline, lower on the medium repo where the without-arm thrashes). 🔬 `@salesforce/schema` → SObject (no SObject nodes yet), Apex `@AuraEnabled` not queryable from the persisted graph (no `extractModifiers`), managed-package namespaces (`ns__Class`), VF ``/composition + `{!ctrl.method}` merge bindings, Aura `` nodes | + (Verify the exact supported set against `src/extraction/languages/` and `src/resolution/frameworks/` before starting — this table is a starting point.) diff --git a/docs/design/salesforce-stack.md b/docs/design/salesforce-stack.md new file mode 100644 index 000000000..bad24cf3d --- /dev/null +++ b/docs/design/salesforce-stack.md @@ -0,0 +1,92 @@ +# Scope: Salesforce stack (Apex + LWC + Aura + Visualforce) + +Index the full Salesforce stack as one connected graph: the Apex back end, and +the three UI layers that reach into it. The novel value is **cross-layer edges** +— editing an Apex method surfaces every LWC, Aura, and Visualforce file that +depends on it. + +## Layers and how each is wired + +| Layer | Files | Mechanism | Why | +|---|---|---|---| +| Apex | `.cls`, `.trigger` | tree-sitter grammar + declarative `LanguageExtractor` (`languages/apex.ts`) | sfapex grammar exists (ABI 15), node types mirror Java | +| Visualforce | `.page`, `.component` | custom `VisualforceExtractor` | no grammar; `{!expr}` / `` are the semantics, not text | +| Aura | `.cmp`, `.app`, `.evt`, `.intf` | custom `AuraExtractor` + Aura-JS handler path | markup + bare `({...})` controller objects | +| LWC | `.js` (already indexed) + `.html` | `LwcTemplateExtractor` (template only) | the `.js` is plain ES modules; only the template + the Apex-import link are missing | + +The markup extractors follow the existing standalone pattern (`svelte-extractor.ts`, +`razor-extractor.ts`): a class taking `(filePath, source)`, dispatched in +`tree-sitter.ts`'s `extractFromSource`. Exactly **one `component` node per file**; +child/handler/controller links are `references`/`calls` EDGES, never per-tag nodes. + +## Cross-layer edges (the point) + +| From | To | EdgeKind | How | +|---|---|---|---| +| LWC `.js` `import x from '@salesforce/apex/C.m'` | Apex method `C::m` | `imports` + `calls` | `salesforce.ts` resolver maps the `@salesforce/apex/...` specifier to the Apex method's qualifiedName | +| Visualforce `controller=`/`extensions=` | Apex class | `references` | resolver, by class name | +| Visualforce / Aura `` | child component | `references` | resolver, by component name | +| LWC `.html` `` | child LWC class | `references` | resolver, kebab→PascalCase | +| Aura `cmp.get("c.x")` | Apex method | `calls` | extractor emits the bare method name; the generic name-matcher resolves it cross-language (`calls` aren't language-gated) | + +**Family-gate note (important):** Apex is deliberately left out of +`LANGUAGE_FAMILY` (`name-matcher.ts`). The framework gate (`gateFrameworkLanguage`) +only drops a `references`/`imports` edge between two *known* families; with Apex +unknown, every cross-layer edge survives the framework-resolver path. This is why +no LANGUAGE_FAMILY change was needed (unlike Razor, which shares `dotnet` with C#). + +## Invariants / risk mitigations + +- **`standardController="Account"` is skipped** — it names an SObject, not an + Apex class; linking it would mis-resolve to a same-named class. +- **`.html` is path-gated** to `lwc//*.html` (`isLwcTemplate`) so generic + HTML elsewhere stays unindexed (no HTML hijack). +- **Aura JS handler extraction is path-gated** to `aura/*Controller|Helper|Renderer.js` + — a new branch for the bare `({...})` object, not a change to the existing + `export const x = {...}` object-method gate (zero effect on other JS). +- Only the custom `c:`/`c-` namespace is captured; standard namespaces (`apex:`, + `lightning:`, `aura:`, `ui:`, `force:`) are framework built-ins → skipped. + +## Validation (deterministic, real repos) + +`scripts/add-lang/check-grammar.mjs apex` → ABI 15, PASS. `verify-extraction.mjs` +PASS on real repos with all four languages detected: + +| Repo | Tier | Files | Cross-layer edges observed | +|---|---|---|---| +| trailheadapps/ebikes-lwc | Small | 182 | 16 LWC.js→Apex `imports`, 1 VF→Apex, 17 LWC.html→child | +| trailheadapps/dreamhouse-lwc | Small | 176 | LWC→Apex + LWC.html→child | +| trailheadapps/apex-recipes | Medium | 432 | 10 LWC.js→Apex `imports` + 5 `calls`, 7 LWC.html→child | + +Apex fair coverage on ebikes-lwc is 55.6%; the residual is Salesforce's mandatory +`*Test` classes (the platform requires a test class per class; nothing in code +depends on a test) plus one metadata-referenced class — every non-test business +class with a dependent is covered. Unit/integration coverage lives in +`__tests__/extraction.test.ts` (Apex / Visualforce / LWC template / Aura blocks). + +**Agent A/B** (headless `claude -p`, Opus 4.8, `--strict-mcp-config`, codegraph +the only variable — `scripts/agent-eval/run-all.sh`): + +| Repo | n | Arm | Read | Grep/Bash | explore | duration | cost | +|---|---|---|---|---|---|---|---| +| ebikes-lwc | 2 | WITH | 0 | 0 | 1–2 | 27–30s | $0.34–0.53 | +| ebikes-lwc | 2 | WITHOUT | 5–9 | 10–16 | — | 61–90s | $0.22–0.28 | +| apex-recipes | 1 | WITH | 0 | 0 | 1 | 33s | $0.31 | +| apex-recipes | 1 | WITHOUT | 4 | 6 | — | 47s | $0.36 | + +Question per repo is the LWC→Apex flow (e.g. "how does orderBuilder reach the +Apex OrderController"). In every run a **single `codegraph_explore` answers with +zero file reads** and ~30–50% less wall-clock — the agent rides the cross-layer +edges this feature adds. Cost is mixed: higher on the small repo (Opus 4.8's +native Read/Grep baseline is lean there), lower on the medium repo (the +without-arm thrashes more). Corpus entries for `/agent-eval` are in +`.claude/skills/agent-eval/corpus.json` under "Salesforce". + +## Out of scope (follow-ups) + +- `@salesforce/schema/Object.Field` → SObject (no SObject nodes exist yet). +- Apex `@AuraEnabled` not queryable from the persisted graph (no `extractModifiers` + on the Apex extractor; annotations exist only as dangling `decorates` refs). +- Managed-package namespaces (`ns__Class`, `ns:comp`) — default `c` namespace only. +- Visualforce ``/`` page-to-page, + `{!ctrl.method}` merge-field bindings; Aura `` nodes. diff --git a/src/extraction/aura-extractor.ts b/src/extraction/aura-extractor.ts new file mode 100644 index 000000000..dd6c25f42 --- /dev/null +++ b/src/extraction/aura-extractor.ts @@ -0,0 +1,129 @@ +import { Node, Edge, ExtractionResult, ExtractionError, UnresolvedReference } from '../types'; +import { generateNodeId } from './tree-sitter-helpers'; + +/** + * AuraExtractor — extracts the component graph from Aura component markup + * (`.cmp`, `.app`, `.evt`, `.intf`). + * + * The bundle's `*Controller.js` / `*Helper.js` are indexed by the JavaScript + * extractor (with the Aura object-literal handler path in tree-sitter.ts). This + * markup extractor links the component to: + * + * - `` (custom `c:` namespace) → the child Aura/LWC component + * - `{!c.handleClick}` action expressions → the controller handler method + * + * Mirrors RazorExtractor/VisualforceExtractor: exactly ONE `component` node per + * file; child/handler links are EDGES, never nodes. Standard namespaces + * (`aura:`, `lightning:`, `ui:`, `force:`, `ltng:`) are framework built-ins and + * skipped. `{!v.attr}` value bindings are intra-component data flow — deferred. + * + * `` refs resolve through the Salesforce framework resolver + * (salesforce.ts); `{!c.handler}` refs are `calls` and resolve through the + * generic name-matcher (cross-language `calls` bridges aren't gated). + */ +export class AuraExtractor { + private filePath: string; + private source: string; + private nodes: Node[] = []; + private edges: Edge[] = []; + private unresolvedReferences: UnresolvedReference[] = []; + private errors: ExtractionError[] = []; + + constructor(filePath: string, source: string) { + this.filePath = filePath; + this.source = source; + } + + extract(): ExtractionResult { + const startTime = Date.now(); + try { + const componentId = this.createComponentNode().id; + this.extractChildComponentTags(componentId); + this.extractControllerActions(componentId); + } catch (error) { + this.errors.push({ + message: `Aura extraction error: ${error instanceof Error ? error.message : String(error)}`, + severity: 'error', + code: 'parse_error', + }); + } + return { + nodes: this.nodes, + edges: this.edges, + unresolvedReferences: this.unresolvedReferences, + errors: this.errors, + durationMs: Date.now() - startTime, + }; + } + + private createComponentNode(): Node { + const lines = this.source.split('\n'); + const fileName = this.filePath.split(/[/\\]/).pop() || this.filePath; + const componentName = fileName.replace(/\.(cmp|app|evt|intf)$/i, ''); + const node: Node = { + id: generateNodeId(this.filePath, 'component', componentName, 1), + kind: 'component', + name: componentName, + qualifiedName: `${this.filePath}::${componentName}`, + filePath: this.filePath, + language: 'aura', + startLine: 1, + endLine: lines.length, + startColumn: 0, + endColumn: lines[lines.length - 1]?.length || 0, + isExported: true, + updatedAt: Date.now(), + }; + this.nodes.push(node); + return node; + } + + private lineAt(index: number): number { + return (this.source.slice(0, index).match(/\n/g) || []).length + 1; + } + + /** + * Custom child components in the `c:` namespace (``). Closing + * tags (``) don't match (leading `/`); standard namespaces never match. + */ + private extractChildComponentTags(componentId: string): void { + const tagRe = /. +// v5: added LWC HTML template (lwc/*.html) extractor — template → component. +// v6: added Aura (.cmp/.app/.evt/.intf) extractor + Aura JS handlers + cmp.get("c.x") → Apex. +export const EXTRACTION_VERSION = 6; diff --git a/src/extraction/grammars.ts b/src/extraction/grammars.ts index f35e2afea..a10b13606 100644 --- a/src/extraction/grammars.ts +++ b/src/extraction/grammars.ts @@ -10,7 +10,7 @@ import * as path from 'path'; import { Parser, Language as WasmLanguage } from 'web-tree-sitter'; import { Language } from '../types'; -export type GrammarLanguage = Exclude; +export type GrammarLanguage = Exclude; /** * WASM filename map — maps each language to its .wasm grammar file @@ -33,6 +33,9 @@ const WASM_GRAMMAR_FILES: Record = { swift: 'tree-sitter-swift.wasm', kotlin: 'tree-sitter-kotlin.wasm', dart: 'tree-sitter-dart.wasm', + // Apex grammar isn't in tree-sitter-wasms — vendored from web-tree-sitter-sfapex + // (ABI 15, MIT). See the vendored-wasm branch in loadGrammarsForLanguages. + apex: 'tree-sitter-apex.wasm', pascal: 'tree-sitter-pascal.wasm', scala: 'tree-sitter-scala.wasm', lua: 'tree-sitter-lua.wasm', @@ -90,6 +93,20 @@ export const EXTENSION_MAP: Record = { '.kt': 'kotlin', '.kts': 'kotlin', '.dart': 'dart', + // Salesforce Apex: classes (.cls), triggers (.trigger), anonymous Apex (.apex) + '.cls': 'apex', + '.trigger': 'apex', + '.apex': 'apex', + // Visualforce pages (.page) and components (.component) — custom markup + // extractor links controller/extensions/ to Apex/components. + '.page': 'visualforce', + '.component': 'visualforce', + // Aura components (.cmp), apps (.app), events (.evt), interfaces (.intf) — + // custom markup extractor links /{!c.handler} to components/methods. + '.cmp': 'aura', + '.app': 'aura', + '.evt': 'aura', + '.intf': 'aura', '.liquid': 'liquid', '.svelte': 'svelte', '.vue': 'vue', @@ -122,6 +139,7 @@ export const EXTENSION_MAP: Record = { export function isSourceFile(filePath: string): boolean { if (isPlayRoutesFile(filePath)) return true; // Play `conf/routes` is extensionless if (isShopifyLiquidJson(filePath)) return true; // Shopify OS 2.0 JSON templates / section groups + if (isLwcTemplate(filePath)) return true; // LWC bundle .html template (path-gated, not all .html) const dot = filePath.lastIndexOf('.'); if (dot < 0) return false; return filePath.slice(dot).toLowerCase() in EXTENSION_MAP; @@ -138,6 +156,15 @@ export function isShopifyLiquidJson(filePath: string): boolean { return /(^|\/)(templates|sections)\/.+\.json$/i.test(filePath); } +/** + * Lightning Web Component HTML template: `.../lwc//.html`. + * Path-gated so only LWC bundle templates are indexed — generic `.html` files + * elsewhere are not in EXTENSION_MAP and stay unindexed (no HTML hijack). + */ +export function isLwcTemplate(filePath: string): boolean { + return /(?:^|\/)lwc\/[^/]+\/[^/]+\.html$/i.test(filePath); +} + /** * Play Framework routes file: the extensionless `conf/routes` (and included * `conf/*.routes`). No grammar — route extraction is done by the Play framework @@ -201,7 +228,7 @@ export async function loadGrammarsForLanguages(languages: Language[]): Promise.liquid`). if (isShopifyLiquidJson(filePath)) return 'liquid'; + // LWC bundle .html templates → custom LWC template extractor (path-gated so + // generic .html stays unindexed). + if (isLwcTemplate(filePath)) return 'lwc'; const lang = EXTENSION_MAP[ext] || 'unknown'; // .h files could be C, C++, or Objective-C — check source content @@ -298,6 +328,9 @@ export function isLanguageSupported(language: Language): boolean { if (language === 'vue') return true; // custom extractor (script block delegation) if (language === 'liquid') return true; // custom regex extractor if (language === 'razor') return true; // custom RazorExtractor (.cshtml/.razor markup) + if (language === 'visualforce') return true; // custom VisualforceExtractor (.page/.component markup) + if (language === 'lwc') return true; // custom LwcTemplateExtractor (lwc/*.html templates) + if (language === 'aura') return true; // custom AuraExtractor (.cmp/.app/.evt/.intf markup) if (language === 'yaml') return true; // file-level tracking only; Drupal routing extraction via framework resolver if (language === 'twig') return true; // file-level tracking only if (language === 'xml') return true; // MyBatis mapper extractor @@ -310,7 +343,7 @@ export function isLanguageSupported(language: Language): boolean { * Check if a grammar has been loaded and is ready for parsing. */ export function isGrammarLoaded(language: Language): boolean { - if (language === 'svelte' || language === 'vue' || language === 'liquid' || language === 'razor') return true; + if (language === 'svelte' || language === 'vue' || language === 'liquid' || language === 'razor' || language === 'visualforce' || language === 'lwc' || language === 'aura') return true; if (language === 'yaml' || language === 'twig') return true; // no WASM grammar needed if (language === 'xml' || language === 'properties') return true; // no WASM grammar needed return languageCache.has(language); @@ -333,7 +366,7 @@ export function isFileLevelOnlyLanguage(language: Language): boolean { * Get all supported languages (those with grammar definitions). */ export function getSupportedLanguages(): Language[] { - return [...(Object.keys(WASM_GRAMMAR_FILES) as GrammarLanguage[]), 'svelte', 'vue', 'liquid']; + return [...(Object.keys(WASM_GRAMMAR_FILES) as GrammarLanguage[]), 'svelte', 'vue', 'liquid', 'visualforce', 'lwc', 'aura']; } /** @@ -397,6 +430,10 @@ export function getLanguageDisplayName(language: Language): string { swift: 'Swift', kotlin: 'Kotlin', dart: 'Dart', + apex: 'Apex', + visualforce: 'Visualforce', + lwc: 'LWC', + aura: 'Aura', svelte: 'Svelte', vue: 'Vue', liquid: 'Liquid', diff --git a/src/extraction/languages/apex.ts b/src/extraction/languages/apex.ts new file mode 100644 index 000000000..f45cd2817 --- /dev/null +++ b/src/extraction/languages/apex.ts @@ -0,0 +1,80 @@ +import type { Node as SyntaxNode } from 'web-tree-sitter'; +import { getNodeText, getChildByField } from '../tree-sitter-helpers'; +import type { LanguageExtractor } from '../tree-sitter-types'; + +/** + * Salesforce Apex. + * + * The tree-sitter-sfapex grammar is modeled on tree-sitter-java, so the node + * types are nearly identical (class_declaration, method_declaration, superclass, + * interfaces, enum_constant, ...). This extractor mirrors java.ts; the only + * Apex-specific addition is `trigger_declaration` — a top-level executable that + * we treat as a function so its body's method_invocation calls (trigger → + * handler class) are captured as `calls` edges. + * + * Apex has no import/package statements (all classes are globally visible by + * name), so there's no importTypes/extractPackage. Annotations (@AuraEnabled, + * @RemoteAction, @InvocableMethod, @isTest) live in a `modifiers` node and are + * picked up generically as `decorates` references by the core extractor. + */ +export const apexExtractor: LanguageExtractor = { + // Triggers are top-level executables (not inside a class) → function nodes, + // body visited for handler calls. + functionTypes: ['trigger_declaration'], + classTypes: ['class_declaration'], + methodTypes: ['method_declaration', 'constructor_declaration'], + interfaceTypes: ['interface_declaration'], + structTypes: [], + enumTypes: ['enum_declaration'], + enumMemberTypes: ['enum_constant'], + typeAliasTypes: [], + importTypes: [], + callTypes: ['method_invocation'], + variableTypes: ['local_variable_declaration'], + // Apex properties are `field_declaration`s carrying an `accessor_list`; the + // grammar has no dedicated property node, so both fields and properties are + // extracted as fields. + fieldTypes: ['field_declaration'], + nameField: 'name', + bodyField: 'body', + paramsField: 'parameters', + returnField: 'type', + getSignature: (node, source) => { + // trigger AccountTrigger on Account (before insert, after update) + if (node.type === 'trigger_declaration') { + const object = getChildByField(node, 'object'); + const events = node.namedChildren + .filter((c: SyntaxNode) => c.type === 'trigger_event') + .map((c: SyntaxNode) => getNodeText(c, source).trim()); + const on = object ? `on ${getNodeText(object, source)}` : ''; + return events.length ? `${on} (${events.join(', ')})`.trim() : on || undefined; + } + const params = getChildByField(node, 'parameters'); + const returnType = getChildByField(node, 'type'); + if (!params) return undefined; + const paramsText = getNodeText(params, source); + return returnType ? getNodeText(returnType, source) + ' ' + paramsText : paramsText; + }, + getVisibility: (node) => { + for (let i = 0; i < node.childCount; i++) { + const child = node.child(i); + if (child?.type === 'modifiers') { + const text = child.text; + // `global` is broader than `public` (cross-namespace) but maps to it here. + if (text.includes('public') || text.includes('global')) return 'public'; + if (text.includes('private')) return 'private'; + if (text.includes('protected')) return 'protected'; + } + } + return undefined; + }, + isStatic: (node) => { + for (let i = 0; i < node.childCount; i++) { + const child = node.child(i); + if (child?.type === 'modifiers' && child.text.includes('static')) { + return true; + } + } + return false; + }, +}; diff --git a/src/extraction/languages/index.ts b/src/extraction/languages/index.ts index 543598b8e..292f277c6 100644 --- a/src/extraction/languages/index.ts +++ b/src/extraction/languages/index.ts @@ -21,6 +21,7 @@ import { rubyExtractor } from './ruby'; import { swiftExtractor } from './swift'; import { kotlinExtractor } from './kotlin'; import { dartExtractor } from './dart'; +import { apexExtractor } from './apex'; import { pascalExtractor } from './pascal'; import { scalaExtractor } from './scala'; import { luaExtractor } from './lua'; @@ -44,6 +45,7 @@ export const EXTRACTORS: Partial> = { swift: swiftExtractor, kotlin: kotlinExtractor, dart: dartExtractor, + apex: apexExtractor, pascal: pascalExtractor, scala: scalaExtractor, lua: luaExtractor, diff --git a/src/extraction/lwc-template-extractor.ts b/src/extraction/lwc-template-extractor.ts new file mode 100644 index 000000000..b21929105 --- /dev/null +++ b/src/extraction/lwc-template-extractor.ts @@ -0,0 +1,113 @@ +import { Node, Edge, ExtractionResult, ExtractionError, UnresolvedReference } from '../types'; +import { generateNodeId } from './tree-sitter-helpers'; + +/** + * LwcTemplateExtractor — extracts the component graph from a Lightning Web + * Component HTML template (`.../lwc//.html`). + * + * The component's `.js` is already indexed by the JavaScript extractor; the + * template adds the child-component usages that the JS never names: + * + * - `` (custom `c-` namespace) → the child LWC component class + * + * The kebab-case tag (`c-acct-tile`) maps to the child's PascalCase class + * (`AcctTile`) by Lightning's naming convention; resolution happens through the + * Salesforce framework resolver (salesforce.ts). + * + * Scope: only the `c-` namespace is captured. Base components (`lightning-*`, + * `lightning/*`) are framework built-ins not defined in-repo. Template member + * bindings (`{getter}`, `onclick={handler}`) are intra-bundle and lower value — + * deferred (the `.js` already carries those members). + */ +export class LwcTemplateExtractor { + private filePath: string; + private source: string; + private nodes: Node[] = []; + private edges: Edge[] = []; + private unresolvedReferences: UnresolvedReference[] = []; + private errors: ExtractionError[] = []; + + constructor(filePath: string, source: string) { + this.filePath = filePath; + this.source = source; + } + + extract(): ExtractionResult { + const startTime = Date.now(); + try { + const componentId = this.createComponentNode().id; + this.extractChildComponentTags(componentId); + } catch (error) { + this.errors.push({ + message: `LWC template extraction error: ${error instanceof Error ? error.message : String(error)}`, + severity: 'error', + code: 'parse_error', + }); + } + return { + nodes: this.nodes, + edges: this.edges, + unresolvedReferences: this.unresolvedReferences, + errors: this.errors, + durationMs: Date.now() - startTime, + }; + } + + private createComponentNode(): Node { + const lines = this.source.split('\n'); + const fileName = this.filePath.split(/[/\\]/).pop() || this.filePath; + const componentName = fileName.replace(/\.html$/i, ''); + const node: Node = { + id: generateNodeId(this.filePath, 'component', componentName, 1), + kind: 'component', + name: componentName, + qualifiedName: `${this.filePath}::${componentName}`, + filePath: this.filePath, + language: 'lwc', + startLine: 1, + endLine: lines.length, + startColumn: 0, + endColumn: lines[lines.length - 1]?.length || 0, + isExported: true, + updatedAt: Date.now(), + }; + this.nodes.push(node); + return node; + } + + /** `acct-tile` → `AcctTile` (Lightning kebab → PascalCase class convention). */ + private pascalize(kebab: string): string { + return kebab + .split('-') + .filter(Boolean) + .map((s) => s.charAt(0).toUpperCase() + s.slice(1)) + .join(''); + } + + private lineAt(index: number): number { + return (this.source.slice(0, index).match(/\n/g) || []).length + 1; + } + + /** + * Custom child components in the `c-` namespace (``). Closing tags + * (``) don't match because of the leading `/`. Base components + * (`lightning-…`) start with a different prefix and never match. + */ + private extractChildComponentTags(componentId: string): void { + const tagRe = / | null = null; // lookup key → node ID for Pascal defProc lookup + // Aura controller/helper/renderer JS: a bare `({ handler: function(){} })` + // object literal whose members are handlers. Path-gated so only aura/ bundle + // files get the object-literal handler treatment (no effect on other JS). + private isAuraComponentJs: boolean; constructor(filePath: string, source: string, language?: Language) { this.filePath = filePath; this.source = source; this.language = language || detectLanguage(filePath, source); this.extractor = EXTRACTORS[this.language] || null; + this.isAuraComponentJs = /(^|\/)aura\/[^/]+\/[^/]+(Controller|Helper|Renderer)\.js$/i.test(filePath); } /** @@ -360,6 +368,21 @@ export class TreeSitterExtractor { if (handled) return; } + // Aura controller/helper/renderer: a top-level `({ handler: function(){} })` + // expression statement. The generic object-method gate only covers + // `export const x = {...}`; Aura uses a bare parenthesized object, so handle + // it here and extract each member as a handler node (path-gated to aura/ + // bundle files — no effect on other JS). Returns to skip the default walk so + // handler-body calls attribute to the handler, not the file. + if (this.isAuraComponentJs && nodeType === 'expression_statement') { + const paren = node.namedChild(0); + const obj = paren?.type === 'parenthesized_expression' ? paren.namedChild(0) : null; + if (obj && (obj.type === 'object' || obj.type === 'object_expression')) { + this.extractObjectLiteralFunctions(obj); + return; + } + } + // Pascal-specific AST handling if (this.language === 'pascal') { skipChildren = this.visitPascalNode(node); @@ -2402,6 +2425,40 @@ export class TreeSitterExtractor { column: node.startPosition.column, }); } + + // Aura: `cmp.get("c.apexMethod")` invokes a server-side @AuraEnabled Apex + // method by string name. Emit an extra bare `calls` ref so the cross-language + // name-matcher links it to the Apex method (the `c.` namespace = Apex + // controller; `v.` = view attribute, skipped). + if (this.isAuraComponentJs) { + this.extractAuraApexCall(node, callerId); + } + } + + /** + * Detect `cmp.get("c.method")` / `component.get("c.method")` / + * `cmp.getReference("c.method")` and emit a `calls` reference to the bare Apex + * method name. Only the `c.` (Apex controller) namespace is linked. + */ + private extractAuraApexCall(node: SyntaxNode, callerId: string): void { + const func = getChildByField(node, 'function'); + if (!func || func.type !== 'member_expression') return; + const prop = getChildByField(func, 'property'); + const propName = prop ? getNodeText(prop, this.source) : ''; + if (propName !== 'get' && propName !== 'getReference') return; + const args = getChildByField(node, 'arguments'); + const firstArg = args?.namedChild(0); + if (!firstArg || firstArg.type !== 'string') return; + const literal = getNodeText(firstArg, this.source).replace(/^['"`]|['"`]$/g, ''); + const m = literal.match(/^c\.([A-Za-z_]\w*)$/); + if (!m || !m[1]) return; + this.unresolvedReferences.push({ + fromNodeId: callerId, + referenceName: m[1], + referenceKind: 'calls', + line: node.startPosition.row + 1, + column: node.startPosition.column, + }); } /** @@ -4121,6 +4178,18 @@ export function extractFromSource( // Use custom extractor for ASP.NET Razor (.cshtml) / Blazor (.razor) markup const extractor = new RazorExtractor(filePath, source); result = extractor.extract(); + } else if (detectedLanguage === 'visualforce') { + // Custom extractor for Visualforce (.page) / VF component (.component) markup + const extractor = new VisualforceExtractor(filePath, source); + result = extractor.extract(); + } else if (detectedLanguage === 'lwc') { + // Custom extractor for LWC HTML templates (lwc//*.html) + const extractor = new LwcTemplateExtractor(filePath, source); + result = extractor.extract(); + } else if (detectedLanguage === 'aura') { + // Custom extractor for Aura component markup (.cmp/.app/.evt/.intf) + const extractor = new AuraExtractor(filePath, source); + result = extractor.extract(); } else if (detectedLanguage === 'xml') { // Custom extractor for MyBatis mapper XML. Non-mapper XML returns just a // file node so the watcher tracks it without emitting symbols. diff --git a/src/extraction/visualforce-extractor.ts b/src/extraction/visualforce-extractor.ts new file mode 100644 index 000000000..1f3959105 --- /dev/null +++ b/src/extraction/visualforce-extractor.ts @@ -0,0 +1,138 @@ +import { Node, Edge, ExtractionResult, ExtractionError, UnresolvedReference } from '../types'; +import { generateNodeId } from './tree-sitter-helpers'; + +/** + * VisualforceExtractor — extracts code relationships from Salesforce Visualforce + * (`.page`) and Visualforce component (`.component`) markup. + * + * Visualforce markup references Apex backing classes and custom components that + * the engine otherwise never parses, so those Apex classes look like nothing + * depends on them. This extractor links the markup → the symbols it names, + * mirroring RazorExtractor (markup → C# type): + * + * - `` → the Apex controller class + * - `extensions="ExtA,ExtB"` → each Apex extension class + * - `` (custom-namespace component) → the Visualforce/LWC component + * + * Risk mitigations: + * - Exactly ONE `component` node per file; controller/extension/component refs + * become `references` EDGES, never nodes — no per-tag node explosion. + * - `standardController="Account"` is intentionally SKIPPED — it names an + * SObject, not an Apex class, and would mis-link to a same-named class. + * - Only the custom `c:` namespace is captured; standard namespaces (`apex:`, + * `lightning:`, `chatter:`, …) are framework built-ins not defined in-repo, + * so a ref would just dangle. + * - Refs resolve through the Salesforce framework resolver (salesforce.ts), + * which keeps the cross-language edge (Apex is its own language family, so the + * framework gate never drops it). + */ +export class VisualforceExtractor { + private filePath: string; + private source: string; + private nodes: Node[] = []; + private edges: Edge[] = []; + private unresolvedReferences: UnresolvedReference[] = []; + private errors: ExtractionError[] = []; + + constructor(filePath: string, source: string) { + this.filePath = filePath; + this.source = source; + } + + extract(): ExtractionResult { + const startTime = Date.now(); + try { + const componentId = this.createComponentNode().id; + this.extractControllerRefs(componentId); + this.extractCustomComponentTags(componentId); + } catch (error) { + this.errors.push({ + message: `Visualforce extraction error: ${error instanceof Error ? error.message : String(error)}`, + severity: 'error', + code: 'parse_error', + }); + } + return { + nodes: this.nodes, + edges: this.edges, + unresolvedReferences: this.unresolvedReferences, + errors: this.errors, + durationMs: Date.now() - startTime, + }; + } + + private createComponentNode(): Node { + const lines = this.source.split('\n'); + const fileName = this.filePath.split(/[/\\]/).pop() || this.filePath; + const componentName = fileName.replace(/\.(page|component)$/i, ''); + const node: Node = { + id: generateNodeId(this.filePath, 'component', componentName, 1), + kind: 'component', + name: componentName, + qualifiedName: `${this.filePath}::${componentName}`, + filePath: this.filePath, + language: 'visualforce', + startLine: 1, + endLine: lines.length, + startColumn: 0, + endColumn: lines[lines.length - 1]?.length || 0, + isExported: true, + updatedAt: Date.now(), + }; + this.nodes.push(node); + return node; + } + + /** 0-indexed source offset → 1-indexed line number. */ + private lineAt(index: number): number { + return (this.source.slice(0, index).match(/\n/g) || []).length + 1; + } + + private pushRef(componentId: string, name: string, line: number): void { + this.unresolvedReferences.push({ + fromNodeId: componentId, + referenceName: name, + referenceKind: 'references', + line, + column: 0, + filePath: this.filePath, + language: 'visualforce', + }); + } + + /** + * `controller="X"` (an Apex class) and `extensions="A,B"` (comma-separated Apex + * classes). `standardController` is deliberately not matched — `(?:^|\s)` before + * `controller` ensures the `Controller` inside `standardController` never matches. + */ + private extractControllerRefs(componentId: string): void { + const ctrl = this.source.match(/(?:^|\s)controller\s*=\s*"([^"]+)"/i); + if (ctrl && ctrl[1]) { + const name = ctrl[1].trim(); + if (name) this.pushRef(componentId, name, this.lineAt(ctrl.index ?? 0)); + } + const ext = this.source.match(/(?:^|\s)extensions\s*=\s*"([^"]+)"/i); + if (ext && ext[1]) { + const line = this.lineAt(ext.index ?? 0); + // Comma list; cap at 5 to bound pathological input. + for (const raw of ext[1].split(',').slice(0, 5)) { + const name = raw.trim(); + if (name) this.pushRef(componentId, name, line); + } + } + } + + /** + * Custom component tags in the default `c:` namespace (``). Standard + * namespaces (`apex:`, `lightning:`, etc.) are skipped. Closing tags (``) + * don't match because of the leading `/`. + */ + private extractCustomComponentTags(componentId: string): void { + const tagRe = /HVJn%l&1{d*kQ-9RJ5R{_z*T`mLMw z5&pN2zW(}8fBxg2{_2e%z4Q7%{L{~W^v+Lz@$=W;`QhKc^@j6ymdi(c@b%Y!{mu`6 z^t0FB{>4v!{>~e}@_z4d_>tFNN21sN{)fMQ!~1;}2m8E^v4myEJ&4zbul?b;oAvOWzs*XtPCT6TjPvF*P9o>fN8fzO%}TTpk_CTnr@uFk`y)U) z2&u^1hl4r^YA-sBP!~ZJ^8}Q`j^Sk0C65DDE+GY55XmE?qT<6aCZCYzDntqhxl@Bk zAtCJx4&wYp1m$eOLB#@b6F8!T{_em;H5Adl@d-d`38|Tg?lcmTw+)ddLP`YEOh~~& z9K%h)#Oqfg(m}|Q8HjWevUe3CU4-lrNY11r&xxrxCYO*QV)i^j#!SL7`GoANLZpC@ zyb44L30b}Zks?AaE=Hu7kefw_ln}D71d&oghL2! z8X}cxNL3nAorct;A+>2pT^drKhBTxhjcG_z8q%DGv=CAwGHoTKQ6O!EY!yg5A$tYV zLC9`_bP}>%AYFts2qb56vVS%UB$tp~0?8xffv8SCAw?6g76pW?7Ey(STo+MAgj^O# zF(EeuQbNdifs_)GBl@|FkV#_pazb{Abx}dcKoPZ^kV8UYB_ZnsQbkCWK&lBDD|)_$ zkTqgVEg?+;sUsv;%wA7Oq0rnw$Tg8^BO#Xr(nQDsvD-8ga#4(FA!KPW)}ob=Nn%VJ zA$!HzX(yyzjOid`jacuUgq&D_%w2?B7VAA{O0s{J3Z7g-W-P*}JVIIoPd*`2lKn%- z1c4M1a!y1Q5i({OG8YqaL^xkU$VIV>mJ+f^5w)l! zWUA0yMM#-ot|nx=7*j*YR54dAA)BUSUUh_=nu3){oDoPTA(t0o7F~pFO`gAsll`+`C637@ zWMZ%vlLRN~Xazd7gKCB>QpWs$_$Al&F8$Xwx1 z0UQloHaMyniR;szAyKxhu}O6@=6ZWH}*s zCZe87LK?&sY!xA6X5*M@LUzp)`wt<*mLpP|hSa4Y^@Jp!fiw`ZK;+&?Nb(s-6CufG zAkBm%pMkUxl6(fzO2{VRVH+XIry}iyB%g|O5Hev7=G95aR)KV-5aCbGjAZ|m%*Uu) zLY9d!d4$XqNIoI8BC3Fp3*rv3kdQ_ZRYXWd8O~Kq$Qgl@5OPJF9ZCsVD5_jWNP+0X zazb_po(e)rigB*xgiH}gB_U;{IHrn_QDRIrA;-j+8bZbuVN@+49a9jgBjlFgsVC%~ zP}o37lepVzBxICuwTX}$BGYCg_NE<*MTBxh!_f7%6-OUOcjmp}XvVW??D##@ydDovuNb;^fpOEBTe*q!MyZ%B#l6U<@ge33! ziwQ~I^_LKmyz4I|Bzf0gMo99mznqZdU4I23$-DmLge33!D+x*7^;Z#+yz8$fWQTC9 zhLFwTPP~?omEx+qj*x}P{fCexVqa|_WV`6_Mnbxh_g{nz7jrcek|VmVg^)X9=Wius zsHl4zA?w5{XeVU8sCx$?6U3NKLN1B9x(JykvdAe-_RnH5S1uuk#Y)K|WQNEzpOCR) zofZ&sS$J4T$W}3?h>%u+6cchsASHx!imQuKLJkO|jF8m=DJP^+AQglh6V5LuqF#-JB%c~J5t4jr z)J(`)QHvHriUe~jAx)wW+X!h}ihE`|A$!F6qJxkQ;YKGRMPfhfB4neea?b2z|4b9i zxrAI6j^zZ**}Dw5kA)t(k3+560$-t*AX&SMAZ{A zM&#Z=$YFsr5>h5+Zz5!^;Atl0q_`?*A*56Av=TBv_|rznVlk$jka@zN4nmHInsySh zSIpH#$i?LK^PFV=R0xH+glrIfm`BKcF(#jo!vZNFq(iK@LP8ou*A)>maxSidVnUXQ zxk?DB6PcD0vRY(XM#!{e{}56km@5dGBWk*wkTYUTB_VqRQbou(vG-OJGEyKlgxnMB ztCo=cVo#_eB-wTKgd{t&fsoCjTN(+uB6g%ELdJ+|<7PrSL|!d~OclhK%Z6oBC z=!AAcazzC@2w5+j?*L2xtNe5QHv5nh6<#Vkkg_%WrUQ7+{+1R6CG7S$SQGFu$++T0;wb<`COuk zkVT?i)r5=__d7L&hViW$Fl-CXjkU4hf`zkktZdB&2yguCFFS+BYN8Ovr!@ zh_nzgry7w~LI!L^q>YfBHHfqma!2rV5KCh`9;~IV6xmLWYT`B0`32MV?|pO2u3yglrc`DIpU@re%bz5t_>hX%I*S zA?t*m<%FyjJe7pxi@B-@IW8QlCS>{+)LcVIp_r?dkTYUT9U+whsV5{ybV36moua0V zgp3eTO@xdUW10zBFL+uA*(365CFG!RzKxKnBC4H`HjzaKA$!E^orE-t*}Dj75Ii~T zn^gEcq7pGzE+OZHo;*V437&jH=B!3n3kW$}g-9VG^Te1ULdL8W{X98*b1a{sAHA>vNFnvmP#s;P#M_2N#UmXOr~sUzfY@^dRfrq9IL8wj~BcBDo^ z9*8q_6CsO)=4L{YPlQ?s87CCB5^_l(ZG@Z_*Q@P>B(FC*2uWT`bP`f16m}7kypqY8 zpRD`#=IFhge1?EMT9hoEQ$%q6W7KigiIBhO9?q9 zn9B%Bo^#6yX%Ng6gj}75^;%9y@(f!^$R2UOQ$$? zPC{;rvw0UG$*ano1kj`RCx7{su8_h(PL z&%%HAb^B($Uy=#L)%;}3u2iI0BlPoDhvpZ;0jr=EW1*+2ip zC;NTs)1T@8+-IME;d7t=!i!&g=`UXX(kown^($Zf+G~k_^KZZYjc@+txBlv{|K{8O z?%)51@BGLA^ta#r&;RAWe(&%8+kgN5|M;J;|KNvz|Dzwj@elv&CqI4jXK(%E&wugu zFMsvxcmC<0|K&Ho{onuRcmMi-f1l$Fa0WVqoLpzHGsGF{MtIrE(P&H|_0 zS?DZs7CRNr5@)Hi%vtWNa8^32oJwc4v&LELR5|OM_09&T+S%xAayC0P&K75@v(2e> zwmUnVolc#z%h~Phaq6AD&OT?q)8HI%4myXNM(40|#5w9TImevi&Iza4Iq95oPCG5m z8Rx8X&S`bdI~SabPMdSdx$InV+MTP;HRrn1;oNX;I=7ro=eBdlx$AT}_niCA11HBF z;0|;Lxw-COcZfUG&2xvj!`%^XzB|$#<&Jg>+%fK0cbr@3j&~=x6WtP_>ednMisZ>BfPEA?i3bG*4;nK#dy z?=A4ky@lQ)Z?RY5E%BCm%e>{@3U8&i%B%ENduzP4UX{1bTkmb~s=bZgCU3J><8AS_ zdfU8OZ@ag{+v(MLyS&}r9+SRQdkx+J@1S?cYxE9#N4%q6lXuKJ?w#z{&;_aKhZDpC;5~8 zDSoj()t}~1_e=a4{!D+CU+T~H=lFB|GJl>w-(TRD`wRU={$jtvU*a$Im-);675++p zm0#(v_Sg7p{VIQ*zuw>ASNj|NP5x%T#^2&^^|$%8{&s(dztgYtclo>hJ$}8v*Wc&w z_Z$2J{z3nc-{>FqkN8LZCjXd!+&|$r`zQTV{%OC(KjWYE&-tzXdH;fc(QorF`Ir4G ze!G9wzvf@}JNz5|P5+kP>EHJ6_;>v-|DJ!}f8giD2E+!&2E}q?gJVNtLt}ZdVX@({ z5wZN($k?dZ=vYB)Ol)jyT&yrQJ~kmXF;*0t6q_8I5-W~PjZKS9kCnt`#Ae23#Y$td zV{>A2V`Z^9y<|hj-8C1ik*(N#LmRd#?HlBW9MTRVi#j=u}iVbu`99m*wxsz*!5UP z>_+Tn>{hHZb~|<_b~n})yBE73dl1Ws4~P$p4~pl;2girRhsN{b!{Wo^BjWk-k?~RS z(eZ-#nE2TExOicFe0)NDV!S9mDLy$qC0-n#8lM)Q9xsW{h|i4AikHS`$LGZ7#>?XK z;`8GR;^py$@kQ~)@rwA8_|o{Y`11IQ_{#XIcx8Nbd`*09yehsfzCOMoULD^U-xS{* zuZeGoZ;fw@*T%QUcf@zb>*BlOyW@M}_3^#&eewPAhWLT_!T6zgWBhRZNc?ELDSj+| zJbohH96uR96+azsiJys|jh~CR#?Qwu#4pC%;+Nu=<5%MC@vHG`@$2!9_>K6@_^o(n z{C50K{BFD}elLDM{ve){Js^8v_Mq(C?7`VXvWI5pWe>|9o;@NvKYL{MsO-_%1=(Y= z$7YYqF3cXEJt2Eyc2V}E?8(_vvWv5)W>3qWo?VhXBYS4{tnAY4+1Ycl=Vq5>&&!^l zy&$_hyCVBx_qD$6bL^Hf;r#L&k7TjC(PJLJaqY7(`(gGMb}w4VZdN^ZyUK4*E8RqU z)?cxqFf#TM+cNvOY#cxGRF?aixJfP;+Q@E_`(`Daciw#7$x1wU;Qf*hs&c=XoJO!Y z?*u~LOt?Hi+&O#1FGjoUrwl9IK3NZg>V9nY#J|4z0dHaU((Ejz7f<<#_u*9EPEN(= zO+3Q?`iKKs*@dM5ZAG-k}ktzkv=RYbK@XLZQSCdapjV6~o=oSWM>jL6F+MMM?Y0B>T$T z#It1I2PFH-Wc%vP>|TkdA_S>Tq#d(V zGO^T6JV_=#CYe|&n^>~Ks0SGtnTR1_CbH4o#L_eqKR7RYk@ip4yo{{GeUQauZY2b% zt%Q}%Pd+7*l_hRsQ|jdNxa4Jt>}9i=myC_P#E>vA*=X)%Nt%}*D$8Ej!=J1&?kN8g zvPp)Ynqsi(fv3k)(2>F6=`2-)ZL7X zDuN+l6=9=!MT(&!JX3Zt;C=IvIoZ9mIu2IPg+s|(}}q_1RkfoyfjY9p%|8Ci`XVOF!z-0FgER?q6K)$aqVOO31+w-Ib` z=2ki?$Mpk1;nAL1Fw>rO@)iZl*_4~o;`6j8d_rGkWXZ!{FXb8}}ec z?H=p^+`U}My zn!A@HxtAlK`uj`n<;d>UR~fm-$jChm33HE)=I-Tmb8mWY-FpPwE3t78g4FK8qUP>( zIjLt>T~6ZDv~r)9-0O1W$0zHI++$?qUIm1NxyMFx_qrVZ$cpdqc#S%(x9)ua+?#IW z9t5e~gGJ5V>y+HZ{!{$Blj>Q%sn=myVu#xy{Wx*?}OmpG#mFI zNbMdhYVKZ#52BY3%WaJ)(gt^B?bNAZ2xi_V^?mY(X72CK6L2CD4 zQFHg&B=_26_r5H-*CxAHQElWNBO~`PB+NZFn!DH5&ArLJb?-yq-V_`6AV}>VENbpv ztK?p*lju(?_p6e7t+IOs8;#s!WaJ)(gt^B?bN5=ixi_h|?)?$CH`&HL2vWNTi<-OF zBDvQhySI@Yq|b?3Wc%99>|<***Cto_I(8Gn_y!f1gY(VbpQN$@VqK z_O+YY$Jod|3<bhEFpxAr{&_Kml(4}#S8!Mf)5)l2r(%l6gF_SMVwRc|rs zKE_7&VMv&LY&5s8zMFmHdTZZD!M;Kp`yfbdAFOL`U!7!Mog+P`+ArHzC)-!B)yO`^ zM)qMyn0;(Cx38|7ePerT-^akdaW?irklH?2*WA8Z$-Y|ohV7tiU#)Ck&Nd_a7#rD# zAz}8h(cHe;ZuX7ot$lw2_Kmf%4}#S8!Mf)5)kyZ$$cy)|Y+sFRU%Q!ojE(HWkTCn$ zXl`FkH~R{DYu}S#-xwSFAV_T=tZQyxwPatlBYp7HB->Xl+gDv{)P0PN?8A^S``Bo1 zUv)S8M)%gfkAr;$Hugb~+CEs<+`cNwzAD+i6S93(vV9fXjqGD=WFLlv*~dn6`>MLx zH>$Vx{VCWt+QvQzQridXn%h??*;gr_I!?*@c#Av5|ck5@sJ8&F!n~X5Yx( z+V^K*-zXdVAV_T=tZQ!Ha>>5svVCV{`>Fug9|WoGgLTdAtB~xgaHQ`yw958X$oA#b8QI6!$UY1SvyYAD_EmJVZ$xkHdkXB! zx3Ld`)b_!;=Ju6K_La*|TrSG?mCN=uo7u?@P)yDZyRCfirN%c%Pp8`*~;VfL}n+`h7I_6_T;eb0b>!)@$?Ahmt4 zuDN}sl6|GJeOG1sN@e>>b{pBp*vLK%3A2xl=Ju6#voEi=_B{*s4YRQig4FiGy5{zk zNcNS;AF_4G_La!?1N;1-rD!)U|*h%eGsI!57sreuUN9L zSpKBrmTX_KY+t>ZeT%eMOReMe^dk zBimOb+gDL<)P0PN?8A^S``Bo1Ur{&v2KUy!PlA0zZ0v&|wSBOzxqXF_eTDLM-#yvB zLfO88y+-yiHnI;x!t7(CxqXG*?91(~ef_|`!8Z0mklH?2*WA7W$-V;Fz8w5982pi< z0@=QteMa^%HnI;x!t7(CxqSuQ>>Jcu`#uHs<=WT>L2CP8U32^LCHwN_%jQ9{efhF| z?Pm5dHnI;x!t7(CxqbQF>>Joy`#uf!4YIKhg4FiGy5{!fN%rN*_6?Ek%aiS^-*41? zjE(HWkTCn$Xl`F#H~R+k*1pexeFJUmgCMniu&%j%xsrXkvVFs3`*LObDjJOJV{Bv} zhJ@M2MsxdeyV;l1Tl@NheFJRlgCMniu&%j%Ig))j@+WQivVA$SeFX=M>|<i| zBf^aP4H);EpmFzlYuxi-+8mW*pQGw$t_aTpP1+}mK> z+d<>*_SU%1fpJ|n#zBzUI9SEpxVKWqy(N8jd5Ub@Tas}VjYb{!R?0Yx2s7?2Fz&6O zad&!a+~>i#yEeu_klHv{#oV}`q>THC^d*dGvT;9=j4L>7WZX|u#$iO5aX$g$eiAh9 zc5jXQ0vLD4#yAL48wabH8~5XsaX*%fn;{$bW68K?Gvj`oG7clcjQcSd_v4^(oxL^g zMKJERjd2j9HV#%XH|_^1<9?8Mn!YevDjW9$$+(ImMjiKqlyMjlX50_JxE}yPVMLg5-v#5o8#Jz?x5m8;#@(H~WaGXg8CPv)+;>vOVMLg5-vQ&k6EyC6Z;ksB7}sHA90aM2 zW2@MG4S$|D@f5xADA5Y9HR^L+I{JL-=#KQGucnUP#W$A7v0q6YJ)M5^tEr>crK6;4 zcNQPO-{J&sN4gAu{RX^*BC!HrfdG^B>a7*8fW3?-^B-=8Aho@))_GrkJJpxpmils; z+?U^$`ZDL3(Sl|#c}l*N3M0b$^4rjt-wyWW)!z2ym%+GeHpW4a+BjJ2+_-P0jQdvN zV|4CaDI51K$+&7W2E)p_ar-UV^A{>EldblJVZ4x^H+Zhs# zxN}H{alVbXS20{SA2UTY-*B9-O**QWPdXf!kKwxcn3t;gj$#5AQ%3`aFx+QR2y8RVmKcJrmfR@-X1M1VUgW>ZGEE*q#6U-@58t^BV`Ki{@mUin{_ zR({TLqb>96sg;irVJrXZu=2kiT=}hR`uP0t_HguW(A_nY;AC9Bn)&O$>M)cy~gQ;IKw7R2ZlQso45nR#ToZ7_9>e}S3zk_ z$o=>==*QMnKL+}n;W|EOeclo5tyCWSA6NC7^mMaI?ugf(%A!|0Hk)L&k=&uX8^Vruzi%-{A$YPR}&wiQ|<=Y z=2xXjD^3_KyjN2;V?>zEuY%3525mmmTbs9`&1Y?#gCMnYuok#;FQ=S)Iq@htw@G&H zWy!f_Gv{7TIfoHp&bbJA{*_*Cj@(F^(mlbOge&q*!eM+7r3mQ7tL?U<3yes&SHTJv+vcZJ3DsfXX>~&D@x_GfsE(F3 zA7v`h?nK&C(oyLgzX55bqqyS=F$~vD$0`;w-O1F^03pM5gmNXHOWD$Z`kVEEvSXi3 z1$~;d9Qs>D!PL<~t?8l?hQTcLuyL1>X%QAiK^EQb9^MREI7jvKdOV*ya5Nm0e zt{>&be<8J=wqqk7k@SBqb+np}>S&=a#kMEW?!dsq673gKwCkm#WGYNci|z9`8W!7L z8m?0TU6ZcjHnu{eezTD4Cdu!@z(e{#*)X9si(N!*M5zaP-jo>-Q)a?m$ZQ`C*JZ{W z#A~w`Q&$)-N{>Uf$X6IIN>>;;%|_Q|FQ%?AFe2;<<3+f_crkc|(Gb^Z2jBVC(F-Z< zFG$*JW$iCW+N;g9zmU?75nS6>sU91MAOPYBA>e{6bWHnF)-bX9z^nsch zh`^l^t@JE@E$U%Mb%|&!Y)3si)U?x(7LHmOd>RdA1Ug;JLX}TlsB61)R7!UW>Vl(I zx>`^dBhcw$6$;T+D;S6>sU2+3R4S5Cq+QxNR&3qPTW(2yKtD1itGh+LYNuFucb{pcgQGHdv>M)r3}$BK?h-se<7>s=A1(*kGM1D7f$nAEV-> z_$7?2=Bj#}M!cJy4c1Kq#Z^qR8h=H}hCuRLf;U)amv*R1t6>!KS=fugtaYrN-c*cB$MC$y2rc(IPh_-3ROOGV^b zjI7c}f_aL_E$Ho9eI!eSnqF?N>zL;nqxPDGAG)x?Iy+g`%4s@qn$$#X$hFojW zkU~8dcxAMBCm`22Jr_&gP*)Xljn#9p^bNVzA=el^7faueYZ7u5=($+>hFn*$j-&Nl zEPX?+R^%F`=VIv_ar}So(%s7m#a&o{Ob#$aN99hU>Xl`i5L> z$TdvQ#nLzAx`bSLdM=i}A=hQ(8mi}F=^Jv*L9QWsE|$I_*IeWptmk6s8*-H)SFWCm zrEkbJ54i^ExmfxV*QVed<0<)$aRu%Z12KS|Y%=}M!~(p>X9T*F5A)AZ%t{n9z* zieUsgF{}WRn9V_FPRq^=K&~8XF$;-6Cx%tfP|QFq`Gc4?F;PKrTNRerAmqBQ=Mn`l z;L61u@9DXOe+FEmu=-tkE|$KbUx!fFT|E~|-;irAa^2B$vGfhO%8=`}o{Ob#$TbhS zI`v#EeM7GK$aPE4#nP9!!oEaTgIqTQ0o#Ks?Yz9w=3_$!1HwKmSr7=Y*tAxWMBUP4 z6*5eB3AXKxK)}{ux@YBd^8*2)*Y`#r^@ycKKV4w{$q&=4%OARmf1Rj*>gz=P6Hm~W zt#`^_C+h!H7X36p&Pk)MLiJC5od_eszE0F1zE0FX_;sS|Fv0nh0qiVT)~os)wmeBF6p^g`i41f!CkaX&&AR=2J6gaUKtuvgXf~7dM@UbA=e}{_lTa0d1c5o z6S)p!KxoIk%Xb<~g3e|rmr;E;qs@(aE>;0UYbK*LhxA;m0)|{0vF{G*xkLpF*25Ik zbwJO>(l^vqhg=Ojz;v@=gLQ>sUKvg-J{{e!=VD$Na_vEL_hpg<8>~x$8EZK4addC5 zo(qgM>Rj>hXT6?_d1a`p9(C=}bAeYzy7r^FyY*ZweM4P)QP(a#7faueYaepe>A6_? zhFk|R$DMjEmcAiZBXaG~bFuUdxej8E+x1*5eM7E8$W^Q7V(A-lH6qtGJr_&gkgE`P z?5%n(mcAiZ6YAQc=VIv_a&;nC4F-hnj_>k`kx9^PRjdMr=}g6RHtV@q1q`_^V2f|k zbFm5-aus3uH|n`W1q@D%qfl41o{Ob#s7r8d-~py5MmAViDCU*n#G^5Z^?EMml_A$; zGKvGfgfjYY0CdM=i}A=fzMTCL||=^JttB3GrJ zi=}VKH6FQE>A6_?hFnF+wNlT;(l_KP#Z6^}o{Ob#$Tb_emg~7#`Vv>z$0zHMYZ(TF zF5q`-?-tMhnFQUIz$##v&R9%mX&|63_}sfqe(s%*H5LIZ|4cuzze@x<^-y#E;m@$zC^hFm8w$9Wj=o@_4SaU+wUTb`@}hUtvPbjkt& zVefFN!o49FurFB1YjPpy;#G(UcrOiO5_E>KHZwHrJoeIDJr`>;L#{UDnxp3uZ6@}Y zu=R2gxn}FRf+Y*%>cXZd)pN1*4RgGKT(k6CEPX?+Vc2^!^;|4{L#}DaHABzE(l_KP zL9P-#7fWB_3j5%2A^J64&&AR=T*jl``*fHDT{^4@4AaTOANm~015D2uY_M)()-i?? zpTlc{d_9-w7_l9Owb)+d8u8xOgh|j@BRa+)ooo1_f#G^CC>Nb|!mMdSYli8$SOpAA z){b0xdM;4`gB=_mFFdo{Ob#$aNpN2J5+4`i5K&kSkZu#nP9!!hV0q zJ=}H%>A6_?hFqJmjspV$^}*9;yL|dwM*+I#W_}q?ehg1}1N4b7zYMwVqplo17xT-I zYcO&>@U;s#=vP>=9w66!Jr_&gP}frAx~J!2=^Jv5#Zz&Yo{Ob#$d!W)c~{TH(l_K9 zhq~_Qxmfy!T;q}Jww{ZnZ^$(fxjOY+EPX?+fyi}B&&AR=WrxmfxV*WTbM|Ehe-Ux>@^d?4U(FyOWv za2+RS0lLC7zYHfY!^v9%0b!G0!pT{HZgOU@;pB^O@^gWJu*o}cau%SQoK?hd^2Ip$ z*+4+pW|ld}Nbcs2lW<3{6-;nDLa-Gm~vGfhOZXwrkJr_&g zkn1{f9n*8M^bNUgAXk%~i=}VKbq%?W>bY3@hFk;jn(2t1i=}VKm5W@5^;|4{L#_eH z)u`uU=^Jw0L%$B`xmfy!Tn~`zpq`7RZ^+e!TnF@AEPX?+J;>Fd=VIv_at+6QV!xh? zrEkbpiF@Hb3}Dx+nSM5Nln8X2JoC>`%m_?uuRby6pCQ*ObY3@hFnvTYm1(XrEkbJ4Y_LcTr7Pcou1$I_ zmcAj^4CLCV=VIv_a?M1pYCRWA-;iq-a&6FavGfhO#^D-TujgXv8*&vQ*E&5HOJCv& z`=wtakgEybXP(404=;C0p^{myAi!m5f!u z)EfNUZ8;AxeMHL!>n3L9GMu;`&#}wM$4sxa@8JHx2y|jty$!`wpqQn4E>UlT2Dycf zF41#=+4RISY(Z^BT@`vR;h%x7(b%|)^;|4{L%#};YmuIdrEkc!8*^O9157)R4b~N% zd1W~90i3v8&&9kl7GYQN#>cD(lW%I1XdM;KjL#_kJHBHYY$|ZU@tnV6-YpR|L zyrSJOjB5+_O0k}crEi$yFxhFn9CYqFk;rEkc!4Rf5N=VIv_at%dYMS3ol zz9CmF>YAwMV(A-l<)N+#dM=i}A=h@)HD1rf(l_MVfn0@pE|$I_*G}Xbr{`kn8*()v z*H|84x~Z_ix=n?7WjOH>oOq0$i+N?pbsV`0^jypV(A-lok6Yt8m{MJ=^Jtl$Bkf^o{Ob#$aM$L zym>spbdj*Zx<$ggk|qv&-QyxmVyK>rd1c783(XyZ0ilV!%U458g3cONF2i(2VmgEM zTu?4rr(re=u3SF3X?@vXT@tKZhDl7vBnIiZM7hM(P*@T(kZYixi+N?JYbJ6H&~t%T zM&`~!t{goVOW#meDRMpVwBEDy4Y_6`*L^(~OW%-d4szYobFuU#u7kn5shjfM)KKK= z@*p6zA>ZY7$|UGooK-+d=TI=6TXH(5@FM-Lo{Lq$kn1{bhj;W`tO62OV^CM8tZOzt zFu48R+sq{BY!*!*R)5$x;C7?Uoq8@-0m+&$uKmb$OV7nBV92!(xo+yYLBZ^mU7#hox-5BUbEbJr7G+mzShR{9^M{dLEXt0gw1i$0zkXEM)_p$+#0W z>v>qp20T-c=Y*bzrEI_>e)a5eJr7ISfM+`DIi}}fDI4&Jx;N>0Sjq-GVqZL}=V2)u z@a)0;^@yH_rEI`675zD^=V2)u@U)?xMm-Np*?^}Bc@F7$Sjq-G$B^fso(EFqFJ$YR zdLdii#MAUbwg&lyY<;B{vK5>%`fWUYQ!ix0h_Dy3^@SI*^$os|t-;e>3p1O=dE)>5 zS82q%v>Nozvf{mG>ckga_v_WMmPp>K!>Iwz6rcP{xF}=SXo-efH@Y4j{vG zS({yoI)>+|y*!FH)sv~FdNNU+MO}4B?y4uHu4*>xswY!jg%M$0^(1uFlfka4_be|l zoL91H*kVaEQK|;(a1`z@;0t$J%D6p`ucO4=Sl_Hib8~WXvdGLCSON&@>pqvYh5P(U z)*e1P`Ul;YV2ZXdte;!UJpZ!ep6}*9)u|B)>4O|ahD$nwP&{=fu?MdVLpcT*VG@eJTcp&9K z6~cMQy|1L)yN~W|*SlAjq1upHYEyer;;ShQYw?Dh9o0F%Gfl%|R*vmRF$}m7z(%(cUD%2y{uTjV_5*>LiM>5^&Tii8ELUMxaXqIxVmX|EX2; zL$Nd9q2_-zbt;^M>8_B>kWSV|(~nB0(Sg!YE2~bRRcvydRnQ92q_|w2;yr9>`Dl8I zaI`lmG6G$S&?vo3u?Q=%EHp*=XnKlp)GEc}SVcylOK~MXWRqfgD=w8%OizLx)oFkx z3uyQ=t3?Nu4Dj@|;sLt?JWqx4(BhRmd4RpUSf4c*5}4)b&{=fuElI23Ggdqm8S<#I z9)!(auFo0_31t1OmD)vVYX97dXJH!8C#-lNkQ!q0c4bww4$VVlY&ZA50s7~Qbekh>uxlosMJWz-Xc*yNfr2Nc9Kd0)|g4NN? zQY`r?Id%aZV@GwFf|&sgpAB`4GL>ezh_g(QG<1n?1@Xs-gV6|fSSMmyTGepS1tw;gu1e+=lsT@qG8utRCKN2-=I2AJqLSH;GRI1* zTe=^ahKn1HT6ujMy=DZuB*v$CZJ2~4b1KRlW9{{Ml*tHmGND@nUVkCfYaI`iGXow~ z&8}k2Mq8(Q4%1}>I+;+gfXpw3rb{wEn>t0#!>WvuTI*}6qeJMZP6JfKMnn26BlVdU zr1jrRp_%H`f|&uee__SL?CN%r6V5}AnQQK9kL@Dkfx~7jwmOMh<}^RqE{Zc-M1qCwJQsv z`)Ne{dsh}j_tJ>?Q(Ft7t~4V45Z{96ZW>Xu9nqaMqLX$+x6_C&+Yxo95%C|VxA5pz z8d19)(akiX4m+Y7X+*cfiRdi*$Z{4E5Gv{pVUJrJ!$JC7S4Hw&Skx+MmwXrdnS4~%F4lu|IBY$z zVY*bH_pHhwr6OABoRo?zRy2upIAAoxb?R7CcH2Bmn?$m53-;n!jXGf^9JYFRvn`E3 ztQKq@UAEA1R<)4b7Wte>r5h%P4b#biu8B%cOE)k6^TDhDQK20XWStpNx37CQpN6k{AJKl@yIF7SX?`d$JO4>~3qMY!5tZ8!oy?R- zy7;Pri%GgzY!TO%aJ6^^zb}7`(`RZR1gY=S!P|g=J?5S1>`h#)2P#@u_tYI{yT6j(g3RhW$lqD(=>MI)7X`k2LF`@ z7HNQ0fi!v~$~28yeHuH{(%5g823QqHqrr}7dzzvii8A$Li{1~gDv$<$FR?{gx22`g zBT=SlY}Ti-HEs5Tc4>fB0Y47e5!IwA>X9f@KdSY9fK`Ds8tu~9l$J)1M46_sUZ2Ls zwAuOVaxJ$kd_92v7|*BU{xTEqjp5=(iHVbl&K%9^?ra=fi(CV zJ}vxMo0dk8M46_sN}tA>wAuOlFD=pls{(%TmxWpoRi-KGktkC?mh1fhs{(19uuEfQ zS{gkPWtzrPeHts$X6LV4wWtPI74U<6Ai8A$LvEC1`Dv-u0yEK-hrO_i% zrfDqHr%{nM`)Rv0z^Z^B{8hCUWnGk}s7Inq{g|)!1FQ<9!QYZ=kw$r18a)zannsyE zjRk45pS4Q^tP1$iBT=Sl%+aSYFD;F8c4>fBfi!v~$~28qeHwGq(%`?E#G3bsluTP|2$Ab}Juj6?FUdQu9@O3=X zT!Sy-iMQxX*LN5+pH*X|mwuYm7;@=5vGj1*sPvPtnh?-q>BmWf;Zw~XehX^iB>O29 zzNg?j{~Y{F;!c+MJO9K;ysL@{(6!TyOxuYPPxozVxNmTn!o!w~@C^cb^sNwm6YQ*+ zqVtV$>U?9%x!WglrW;YZZ^atl#8v}`jeHYZ4FvS)+eq|{4c6rd%PpccH6=VpIGjn2 z5YS_eVmoDnbveS)h$zR&njCN9z5$1gaxB8qKtPWG$T0yr-(YD(sm6Zo5%rXEWtUh+IjKP$K$m^E`FcH(RQNAg)ReU<@1>Myz!a6TJp@M{II zr{?2so^K-!g4EKWjJ=e$2&Ij%kp@9(X;AA7q%n)xQ-H@)PXQiJe2ks~9Fv~{JT5&2 zXf}Ha@ObJe07is81$Z2u0z4jk3NVa)3o6r|8qO_My94c(u{)2Z+<8=Tr&)IAQOTW> zu}05G9!>)^< zJuHddWGfPclt9uuS1Yp8SEd;66LIXsvwi(slwNVQ}YPHZ3(W@PgmlStw)IyM2Ei_5=YG>nmzip!y zg4AlENupOq*e<}6202ZsP?jrS_o3B zg(it!?H*Kn$wn;%sntT0M6Y%$s%^7T3qfkN&?M2T-G*u}+NgyfwOVMB=+%zEv%>`& zwGgCM3r!Ne+A*m1yp382Qmcg~iC*n#?1WYuwGgCM3r!Ne+Og>EIUBVQq*e<}6201S zsP?RlS_o3Bg(it!?F{UMGd5}=NUau{Bzm<6QEiKjS_o3Bg(it!?MzgA+D0t|sntT0 zM6dP`sy$_+7J}4jp-G}wI}6pGv{4H|YPHZL(W`AlwaqqaAxNzjnk0I)hf(bb8?_Lm zRtrrMz1kzF_PC8&2vVzsCb3hyIrv2MwERT$0;)Y`qZWeHYN1J@SKEqD?V4=VLXcW5 zG)eSo*P_~^HfkYAtrnUjdbPEv_K1yI2vVzsCW&6{4pe*CMlA%X)k2d*ueJ`=Hrl9# zAhlX(5<9hFue2JDSB!@o`HQSugPX`%c@t^FO@swx{^1z}sndh5${;=b%21!wmty)z zKR9$+{!&aI=}R%qW?zcwlloE&MudGSrVo56rcdxoF$cs?yvTF+^oq5E+)}kW(8U?J zBYi13toW<3RSyJ;zbjb$OLFm-Vewf&=Ea8~b$ZbD(Wkct(`&F%3qfkN(8U?3#a4YN z)v6Ckt$J2&)rX{ZDHvz;{jG;mt%?z0t@;qO>O;X+-DlCN`}M5~U7UeChOH`Iy|>S% zmJp<_B{XI9YPVwN?X^)0L29+ol+ml*hHC3=)IyM2Ei_5=YNz8FYmbdu2vVzsCW&5c z398*~qZWeHYN1K&)P{Xka1ieAyKK}#kXkJ?N%U&#v2W{a)IyM2Ei_5=Y8&xOsXJ}d zLXcW5G)eSokD%HeHfkYAtrnUjdbJac`)M}wgqE}mkd%_AEwGgCM z3r!Ne+70OKavQY}q*e<}6200j=*crSA zn`EOFg4AlENupQVifW5&)IyM2Ei_5=YQsjbq*e<}61`e+RWrdxEd;66LX+63 z4SU!9FuYC}Z=)81)M}wgqE~wo_k=n`Wjamp&tA!@9Q@ba)CtQ*DghpIt0|P$_xi1)SO%51@mq9Eb^B;wT zAa#1sRne!Hk7@_lsD&W4TIj0i)egmCj3Q8e}$h+w|I&FVEjc?|7wvdk5T6e?e(tZ`a27)JVvdRcUSaM z_hJkE9}B5GMlF>$SM*Z%q169vA(h9drSjg0Ug~v}`dj%m3}L^cp(Hsz^Rv%ywW;w| zde>6>4I|I=ZRF7`0U18qrIgk5d21 zLMo3@OXaO$C$&C!Ro5aXP;<8W~NZF&54 zyr}xMMQS`oof>bY=u;btsr||{wY!+wuPjpIG3wNK>qVbh9;Wt7)6}{!wO?AK#$(i} z@m7sKwPBdr+oq}A$JE}oNR7v+Q{$~_ms;4(-Xh$=eqkY%$Ec<9){9AE%ZNHNaZnVsk}9!mwFg`^(_mjJVq^*w?_0*Z({@e%t9)UQA_2m5xvyA zDD_PXsXRt4mA6LpQae!UPc5YK7`0U18qrI=iBf-JA(h9drSjH@Ug{uRR{zUFDvwc1 z<*gCD)WInAA1tKu7`0U18qrI=j}7pKg;XA+mdaZrdZ{_+>W?j?@))&L-Wt(M-HWdN z$U-WQQA_2m5xvw2cqR7t7E*bPS}Jdi=%pUT2Kb?cR34+2%3C9PspWVP_yY^6JVq^* zw?_0*#dqRfw~)$X)KYnCL@!l*A?|-#NaZnVsk}9!m%0Ue^?z7MVLJ6%45`0d22*3^$tq?FBVdHj9Myhjp(J`MXCSU zLMo3@OXaN*z0@w0`dtgDJVq^*w?_0*@1fMcwUEkV)KYnC*h$?Vd^CMsel#sU@BdF0 zQhAJ8DsPSGrC!0ifd6PAmB*;1^45r6>Q$8b9Sf;EMlF@MM)XqW;pNJIu#n1Q)KYnC zL@#w8O8xg1QhAJ8DsPSGrJlzf;NMwDe`O(+$Ec<9)`(u}EtL8#3#mLtEtR)M z^iua@1N^0hR34+2%3C9PsSPOgn-)@ej9Myhjp(HwK&jubkji7!Qh96GNo@#TS#`)) zR&!D6*Da*-7`0U18qrJLg_kS;)0y2HKLb#0;T?`g;XA+mdaZrda2@D!5_Df%45`0d22*3ReUS>NeihwMlF@MM)Xpf za9RC{g;XA+mdaZrda1`y>c=dk@))&L-Wt(MZ9%CYwUEkV)KYnCWGL0*y(0^qFFRY^ zK2KOk=P_#Oyj9+P>8nusM=YfC7`1fXI`6*p1t|T)7Sef)S~_o~cVGG)7aHb|Eu`}p zwRGM}@4ob-DE)B@={!a)oww4vFMSM3|04_OJVq^@x6->W{Vw+Uhb*M?7`1fXO7Fh( zO(^{_3+X&YEuFX0yD$AJHq4_I(s_(pI&YWeGtCI>jM_j zd5l^*Z>4u%dM-+T#6micQA_8ol!5fj-?`LBJ2h{Gz|@ynTlsv3S|*nNv!C1Nu>mz1dcmG!C5%|4K{#Dn2BFk;FO6MRBT@&^2Ds)!C_7%G|^ZxEU?RGr8K!Gy!z(Ym&OYU;+<8$n)6+0(9&#^PRbUuNNK4|s`*&Uz*5i}@n2uyzT+Pz z7zVH-+^m<`L@&Ah#b2Jz>YLTiec~~g0{-zz)))G^&pR(Yot3!b|INpeEPwd-9~}6D z1AlPf{~r$Y&HBJyKg)4FKNin^=zZ^hxX&XW_~4_Dedv!K|KksT`$Kj_@Dk+ z->05_=Gj00#3%cG>eHX;|J-Mvf8leV|H6x3eCaP<{?aR7e)TI~{n~4ZfAep@{*7<` z<+uLoum9%T|L))ahwuEy|Ma)t{m=j9zkcuU{@Z{5{{Q%&um9kOfB&N&zwrnA^b z^Jj1Uv#U?pa11Izy06;=Xd}5e}A9j3~&ZIgPdGvurtIN>f|}YoZ-$0 zC*K+AjB-Xh1MrJaArEQoKk1DGsl_h zlsWU9`OX5T+*#->auz!k&Jt&-v&>oUtZ-I3tDH(_wX?=q>r^@Gob}EIr`p-*Y;ra` zHO>}itFz6ib+$V@oSjacv&-4->~ZRyz0N*ozti9xa1J_$oJQxcbHq97G&#qd+vFZ|kGm(_X7{9f%02D2xM$q6?m4&BJ?~y{FS>2+ zCHJy>#cg-5y4T$6Zijorz3JX^JKfvv9rv!=<=%7eyARwPZ-6(@8|3ABgS{c%P%qCL z<_-5oc=_H)Zy=C5VZ-uwgTjf=HtGzYeTCd7m=dJfPc-7uU zZwt+(CV;qCP5yj|XIZ;w~+?e+F~`@IJ5fOpV4+ z9rsRn&E84xly}-|@y>W>y>nixciy|;UG&<#OWtMgir4O4^{#o>y$ie{w9C3U*m7_xBA=sT7SF0!{6!G`Mdnx z{vN;H-|O%5_xlb00so+X$Zzxy`$znvev^O9KklFKoBfmiDgU(J;-B%)`se&s|Ga;} zzv#F5m;B5A6~EoT>Rh0r>a+fe zU5)a~%0%oX_t`%Dl9l04Wx20C1J7F$)#DE5WWCv!U9`UQ=JQTg;=uzCE{^-teGxJ_ z?*szgOt^eFUPgLJY8>jm$yD%*X;krS;$PqVfOp5wiDlj4H(vY?UfTDk#~l6K{t5ZQ zzJEf#u6JI^g6mT@TOUTjuR)*7`XXG6e~o3vuEn42!}90ETtWYYeB<9g5qO;QVNP;e z9xVR`;r@xhFA)An+Fo` z_avPSR!Z+mc2?h1XZ1}yPL1_YvikkpzEWc~7n(FyU)Fb`u`od2SbbT`z2x@o)>!dd ztoiXz)-6p2cas@BnabeF#G{nK!>J6Olrkt7Z<4{2sSGecpTU!m!IRxGc;8LGEAS`l zrX~-ue0uEhXLwiLkh?0RQJzg3EdRQj{)uF}!X5CRi^0l9VXF$apeIr`KOr^B2U0da zA=zAEWb+d#n=wFd^Alk66Wwg?)8XGy{K@Ljm>pO5;l`zPAO^A{-Z^J1`aM%I<788<>0KK|~XI4P67z)7ykgG1c= zoEWT}G0?*D^XLAF!1LzMbCPy>M)`Nn^-o-q<$WP-u>33E`X>Uv@$E%1SSgQnPRfvw z9KXm(uE>K!I^-oWSUDqWGhAVhr&ieG(nj`JYK1*6t*~aJ74~>)g<*hxg*^@{?D1|Z z?1PutHHq#|)@98)3-o44TYZ@ub4hkF7uxE%B(-5|5`^;!&w3aweFZ+a67|1P16^;!$Xc zN4vGehc2><)$l)A7d4p$R!m5(`2**d`drYkK-=-_;yx*V`XrvEbN@$D{`8UjDKYY= zPs$$*(EHN|{OQB};pgvX6W%u;Y2{CH(=TONlVeHQlVML>(>^4fM?aR5{E#HM-AM97 zDajb1m;4Y&ekdUMoLaJJ<2OL9&dJL}{;ewg6MHopxXr-yF z%Tk+lNH-kFlSWatL0zDK`&lA9MO2YzmPQNW{hM<$0pn&xu5gfpgEC0d@$Z^y=Tn*&D1rReqyCA&OOMWi zj-whK%+ypiAr~s=faQpWg_)XS3F-b;U^%Q|VP2(JLYnG4urz8|nq-!crn&$uhvd;A zb6!l2R@Q>KYoxplSPsggL#~l7B}Xgggjz@)#J>fQSqHH?7^%JtIvO;7vpS?$LOSRQ zupFF4h^V9tkH{>;VH91=8V4w~myX`e#*{e~0K-LnnAMmeez0{{( z9v!l3`FEFKv{E^%MauIK2*lR?f*Pmzp!=2LBeY?AEvys9eZtrW06p zX;@e-Qd&Y-ZUal5JUYblJIT??`~#H>ne#5N?9?a^)FNcBDCpS4-sgQL;N?}MJ4+fSR zP0ea$7WwBa`zHcFW;p~{HfvZ|N2Iib>?uQmWs^KQq(XVg(aQV-bq?7LhXKn*jdG|Q zUSrGO!yOJm)tVq?W-8r~a*qI(4H_0^W{M@mhJ0XIFOQagcDH{b@T0pUlcSZUnOZ*z zSk`HjGc!}lLmoSg29_!f3%Dz77hA)&3uQLU*_4iu(`NzbSfkMqa5iK!8Urk=H7v}l zl$Ma?I2KqcH7v}l6idjh@Hk*uC65l7voJYY>Ec?MWm90QJ0)**mb0^v;!zeWWy`MmXN!T5@1=ZVF|b!avd`RSQcqmm|rO^A->E6mW3J?=2wa(5I9*GEW{I;(1y6=nz-t zB}Xe2vdX0thPW~xSjyzlAqx4A?7q||Fj{^oME^wK_gC|uVS~|1g{&)53Pbvt|8Vw8 zedcPa&$=ST^8a!7<^fg}NBeM{VeT@+HY}nbj>H9s83r>M2q6RsAtE8XCNUa~i7|>J zA|RlGOH@=`g2V+BaEVKdJMLRtaf$nmh=@8tf=CbvK|?0SnD6O6_e}LU_jKRxbMEMT zzdznOhWE}>)z#J2)z#JA25)hjM7dsr60!;d%Iy;6I+drvhVBS{9oznpRTymOPKokI zm8YSH?h1Y#%QMt-2HUz@qFk%d7W#s9Zjk&QiSh^a*9M;V2EUG#96iT84eh^AqFkeq zJk)cBa6n`_hjzMJgA(csL;L?EQLeI-{DI)tvF%4+aQh8&>w^;IN{!^9zA!`u4@s2Y zYfzwFmc=ky9+oIqXi%VCMlpD(MA$zu{_i3UZgM_DO|g}yei5NjGzH41`o(ryS+PYQyN*bM=& z7lU@6mM9l!P@peHG3ezPiE_RM1^QwXgCl-cqWn&S0(~)xK`+lql=&JI=!;PdvOF(Q z&eNbseJR#20%$kuhpt!-L(b#{DaUU$azIy%VwfmjlqlzFP@pSDF>EcpBvH=Mpg>oQ zV(6cjCCb?vlzA$OL6%n}%2^r|=!<1BOcbw5l)37!4U^Mr!LMU|s?@Gx6Qaby%_g8( zmfBzw%cUG=Xxa|VGKxWiuS=BEH7HWEN^3;=->o$vtr`NS6;h7>1&3@SrQ&C*tuc(( zHzdmE8WiY?bz&&MSSeBdt3iRT7{#F3Hzmqv8k9MfD61sOe>5o27t3N8ZEs1GPt{)= z{P^nN*Rd83?OO4CTcZ41BRRBdh4PL>Y0;oSyNqJ6i+3f;zceV&E~6Oq(kxN7X;4Di zHEfRjMWXyug93fAECw&MMxuP8L4m#)#ju6;o<#Xrg93dqiot)bl_*;^D9{(97;N;f z66GHn6zGdl41KgtqHNKiKwpevkmY@e@^=ji^u;KKU5E7&WwQoF>PzvhsFrnetx{DA zfXH{aAwW&s5JTAffo#Z!nub74jA95sHb|6>8WgCBQ4GW9ZxZEi8kCPz6vO`4Mv1aP zgR)6QF@((@N|X=OUmF&Mn}T1*x>abG+ix)Nk0i=^jpWcSqZlS9ah=c5PVZ|_pj}2W ztoFqPCqp}})1W}RjA9sU;#!iSo&Ksp32E0<4I@$3YEYmrmc@XwRieD7L4m#)#gKXY zSfZ@apg>=YVvyw%iSic>iqw}f`bABJ+vta`SPnz~{8P&Du0{^%ict(Y*(Oom(V#$A zjAF3ce@T?LH7L*(qZmeii$qzi{@O6&{vG@}cHB0rCVid!CHdms& zs{Y#0{=YVhGF6mnctbP@peHG5C-RB+6476zGdl49mC+CCZ;QD9{(981y3Uw;kH) zNev40#VCe8S|CxLP=9T(i-p0jV@E%<%RCM9`Nb0DagF5AE~6L{HkU}0$22I=E~6Oi zVv$5yra_U~RXmZX+;EGxLYg(Ka288B9?{4FT?N+?yk96p68lz5FFqZmx%GKun_2IWx|#n7pjOOyvRC{Pc}Vi+1%NR&TmP@peHG31YaFH!E- zpg>=YVwj|_lqmOUP@peHF-(|ONtAolUmM)i)xoc0hpE)AV$@=n&CRHxS(e%`rClTC zxLeb9XqHh7z4-@;a+d~0YF25@^UlFSNUH|7b*+@+4vif5h<{h)5Qhlev z21V*i=^t^Bz^#9zt`r1OuH}XRJ+VFvKI10Yk{dKFfu0z}F#2wmDA#LHpeIH#^zbbb zExm<$+T``Km;_j6wmuXP0v_!d2qFky$fxcK4gO|KtqAby%NPQ{2 zyu{SYK`^Nv^!Ss6U#x+LB3Vd-!XA()i!>-wk&2Mw%#fQYLWwMg!G%63<+xZQ2b9Pt zhSoeJQ5I@Ypesf(49|xp$^s1vbj2tJSMi8Mxk!U@iHc%q(W4UOLJbP^#j+SsmPwQg zG$_y)qZnHBm_#{Wg93dqib0mgCCcwKD9{(97=ryLB+7gZ3iQP&hMs;>qMWBefxfIz z{wz`EX;7dqMltB+DT(r14GQ$dD25h2Em6+Zpg>=YVvyw-iE@qx1^QwXgDlTVl(RJ` z&=;c^icX%BC}(L%9$Dz=!;Pd6T^!V7o!-w_bU?Rf58p-(ZV1V#gN&4Rib>ZL4m$l7K81+ zCQ<&YL4m%kP?k%S&on4fU&_2F&OEuzi_jIzVc1J~UCQyPMh>YfMGkSU$4w5YCj~*A zop(ckj<_X;%-ssvl7DGh@*fq&kav4SqHNQkKu;`-Aw{uLqWn{X@^2NzkmPw&qI{x3 zX;D!OV`r5_`B;MjeQ}Enp6M-#vQ>iueKCq*L9kk){6m8ReKCr`r-(=BaB-jpMe0kj zxK0Lxi;H{Tk?4O{WifckcY|NYrq-Z!Zjqse&`=YF)Ym9lPDi*P|y#dG@7{YLo0P`A3&=thrzF}m2&(|BZt(g zqP^#w<$#{7aU6A)>)7NU6E>)rkE{<7g1rOlWb@6%$|DFc^eYJlKYn=}y${G#Ix`=LGch=2c zBM7)GQ`^eeVFUfKp&9al8)QS?)ieZZViZFd@;8a{js^v4Vibc?H%gSZH7I{kQ4EgY zLy59lgVL;`81%A9qP(R+fxfs!2ABSkL|LUlk@`|>`E-*l$M!OG#c~)X?#)t;l^Qvq zD@HLaO#UuW-q4^xS5_!nB+3d63UtLNhRI93?m4v6>l&0d#lI_>71x?+#}D%}1W;Qg zzvUW!&@7`EmM|Ynl-D#U&@7`EWcfs*ysANgW*Nm0wER<|yrMyYW*Nm`;oBt2%Ni8u zi%|^z<6jcxB@GJn#V7{*Y>_B0YEYmrMlp<)e@m1XG$_y)qZs^$cqDpgr{^^&&=;c^ z?wR?IM0rkwBK4(Mxj4A1wend10bQ{ihF<mne^`zc#GD z&Io=TYZ6c_^E9A{hkl24dQ2nvpH&pYU=wfd4(+r|g97ccEC%yDOQJlgL4kG|#o!Rn zmMD*CP@vt=lp=0Ca~o{X70Y4BXr3eGct|4$bj2tJ&7Lb!9@L;fSBzqquzo919?+mb zS5_$VB+8#OC=aVB2KRoRM7dvs0)4S8hVXE{M7d9c0(~)x!3q6NqTH)NfxZ~UFiD&* zQSQ;8NPQ`;Ok7jtW^vFJ%V8Kl7f3no(#Qc_F^a*LT_{oR)Sy6DjAH1YizLb&8WiX% zZc(>D{?YB4Ke}6GZD_zkiE^6;1?u4j7>3Nn66ID6id2u%sp1+@w@!s>SPp}OzC_A# zi$)IUict&|e2XN?%^DQwict*l-C~JylLiI4Vibc*TOv_z)SxU?Q49ulsYJO!gCg~% z^v`R~{R3TbYYc<#GAYM(8abdVE0oJ6${#f-&=sQ?baI76xmJS$T``IwTK&C5`GW@K zdKJYW%as!48Vw5c#j+Ssu97HMYfzvsMlo32)e_|@4GQ$dCg1>q%Up8`Dv)81w!ReFOI{1T1ePzyKT(4jX< zl#4YePz$3NroEda%0dmwVim=(n{cy4S)f5#B>r7dq_{KBtt+4_ZjHe_Z;^6bsF6eJ zN|7V)DhAZVVi=UVRElxFMhvKlQ4Ae?t3>&o2IV3Z#SjVHCQ;^VP@pQ7#o(83mni3H zP%cnW4B_`35@ntSMe0lG9&y>Wo0&jY+!{me_MK9Wb2V~6SBzrtVs}ZDb2KPYS4wNd zizRNYk$O@P#PybL2)|WZVpu}oEn6~I(-P>3^c4U#N;v42u1eMEP8UB2}fRMBK6K zW+tbrau{^-fRy7ijU3Pwx5nV3ACxHn(V#$AjAB@WKO|8;)u2FEjA97!9+oKo)}Z`X zMKJ^-k4Tgj4GQ$dvKVS$9+fEn(x6CvDZMQ2X>{vl=!)eq1gy)X9RJkF0bMbQ!Db(m zD4%Fhpesf(Oo5L}l#ewi&=sQ?WO+iOY}KG_Q&9|d`=mtqhXzIJOX(l+w3J)_Kv&!v zLt*}(r5u0P$N^n3iedabB~dnOP@pSDG3exJiSm&KMe0h?$*U%vFh9fM`x(h^lZM|G zOR1lgC?9H2pjnp1FzTO^C>u2>&@7`EH2Azk`I`m>nq?G&XMRDVY|x-UUyNdC(Tfu0 z0}YDQm(rW!9NP@pnauwn4OCQ;UCP}Zp^2DiFgqWndJ0`;&g2BUjj zqBLtzq`s7{y4rc#gRWQ(gVC*!a=fFFL+VPABWEy~*jP`hNdf5S3IGjpI}B6i8?qg5 zY1;9w_;*DNaZ$P3;DLr%4ug%YlybbOk>hO@#SlQhDN$BxP*$rbhRTao66FmI3UtLS zGEBU0Nt6{DlvU#270rrA&)hT%U9lX75wlv#v0Nhubj2tJdw*M^yrw~ct{BDO1KyD+ zuWC@BD=U zLl3W$C{Jrpo>x%}ee=FVc}j!woQh%?KkFsRpEW4Z7q`d|{(T@(p46Z~UyNcn%CSMB zJfT5>z8J;eo&F|K9@n5iUyNe#`x_<7V;U6bi%|?q*$*YkG7Sp!6&I*&l7IB5=8vEr zW^Hf)A4!x)G$>L%%D@xPo4E}LL zPX46IVQ`2aOF8b=$N^okP7F!)PbA7+8WgE3r8VL$Nw*%BdQuR?BYJKK_oyu~*y=xJ zOK#V+1bSk97@W^GiE^6;1$tr>!!+|RiE^t3_aF#6vT8*?%8eQnsV~LiRy&VC=!)eqc%}bJ zIj+~p0bMbQ!QwubDA#FFq^^|KJmK6L=!xYp1bhFJa$KvC;|B5XiX7tAb+>U0J+T}H zFFmJHRH$G(-Nr` zMGo-0)OqSJiLy|GB6X#- zMmzxO)*9%E@>>lG zbj2tJBfn6hoU1{Zuc8BIP(0>|*Lwq^cA#s$HdkmRJgdPA`>G{3c!ssU$@T@oc1< zGEP&ZFf7k6lTw@%FU6?}hT%}qc#Ko<&q_lUIXC1tiVy~mafK9OcDxWLD;Nd? z{k_DP6^|iwq%>r{b3;y4gfO__E2R*}#S3wQf?=q3ze-{p8;>D$q%`DX=gDoBB81^c z<<(M%8Sz3KuV5I~^w&s?>G2rHDHw)<_6Lb^OgzT13WmWlu9X2Oxj}l{Q zJcdw{(kbhmJ7v0^5Z6f|j*b^X=tvPlJa6vibcBKwfODJyrYfy4bm{f76_esyF-5^J z%=0%$j3eVQj#e-Xa@;5}nv@?KZ0M%Kk7K8u$qI%cD7aZ-91$<{Q3{4(p?QnMm>7>S zNx?A4u~cFl9*-e(s#w8C&bHhX1`v;%yV>CpN-GTAcdKm0q4BMlXoqo|#Q0S_hER~A ziN($hIZP44(51IaA$}Pz#IM6bY<2Dqp&+Fdjjp}%E2R;Ju3$u$2dsA zFc{Z;662@w7zZjChLLu^#Mmz$<7WznAv6CciSd(oi~|%5LphthSZRf!M;?}~_+fl2gn|?y#B=0s zPJCZQ2*b4ch!o-n@k0C`F#1&ttf>30THE-j{F8C4!66B1)gJjOl>hG8Z8q{R4MJjPfB z!!R`eEHOsMW9+S97^*U!k{I8O#}H~#I^_=MP8p*JVVDb_mO|_mFU0p048y>9Mq-SN z#~7_(7_9tRiSeCyjPEKK24DA_#268eF-pNO80qs8O{M=#&>F#;|yd5ekOEI9`$%-;Brjwt`{kl$RyO(0GjD3WlLmUXd6>;xWFZ zU>G*aUzHe*@fgDt3`0%VYZBud@fhD!Fbv6xI+41K#o zV(b}@(Wqb;`sEFYF*qLM8w!S@Eh{BPeLO~kf?<&3O^Gom9^>l@hQS-Jk{EUI7<(!h zh5+_0iSe~~4522)d0gb|JcN!EfCrrc1}UvD%x$Y>D+b25qE5juc%Qc=#(;Q?ui0U| zBQg5NW9*?|7_9tViLrY;##a>#L%h%|F?Nf`7^q+v^zj#ov1>fW00qO)mNgP%mw1f+ z3Wg!)`<}%3N<7By3Wj0Cu9X=5;xTqpFbr25{8eJ?9FMW9f?<$joy4e($Jj-|Fa*Z$ zON^c3F}|W;7{<$biP1M6qo0Cd@EjjVj2+`Kc2+P9a%_+oec~~MniS`8kF)dGNfE-( zDSwkf><}+RUj@T3MQ)TB+s9+68V|owB_mgkjWgmO^xo7owMfVX&^hON?&u7~3fr206A!jGA~1p(8~Zmpdz? zha!Z*75_sD(Is98p(90z+nj|E3Q_>>bq1(WT4Auwt+Evz<6F@+EX1YGLUd7tFnFzx zr4Uu|LUdLz4BhdG#K^~EbW$)3GvhxcMlK$sqk>^@T-zi@HXfr|!7z-Ge@To?JVup* zVQ?5N5~DI6Bd=hrl6N3=#+$h!>(o-X5lPlI{99slh{q6WQY`dtXXD612%l+umk7S! z{Zxp6{}@;?Ow>L!e%G5J|Hr_Je77^^%$Y;@zd6*2G!`7WnB*>JA*CJ&T!+(MqP;^a zL;yF4_WFu=WcV?fyqgrDpZH1Fju2!1EeCnDtJiVvEeCa^<1!vq&}pExbOz`Mnx6Hj z3(c(bXghCACy#o09q@}2=_Hz&t)Lp}L&s%1Qa9>OJ*X#bN4;o!+JSo0j?|ZCXSz`b z>PkCPKiY+Mqur@L4WNPaEgDWEX)n5#meJERGt-B1v=e=WcBQY<9`rS;qd`@T2c1F>f=;DJK&R1TpvTaY zpwsDT&|~R2(BtVv&{?#9M~}YeT?P76?<9=b8Q$ffQ@w6o@O$sw8jp@^9mO3p9cZvO z#{0lKp;HH%=FRku^-k-Mr6Jxh?=bHO??i8t_i1%k`o6cfH`d$78|VGN8}I$lo8bMQ zx3Bjj@5kOxy#2i0G2(?Lz6W|BjRQRl?H6sG06LNO1wDd(4BABdfgVZwgHEEKfgT0z zh_)UKdNlnKbPD|nbSnKCbQ&;3TaN&pj^Bz_9t}E+u7FK^hpq%2N!NoOL^p#TORqo& z9=!&-54{dLKD9p1{eM6oZ%BQ-Sr&bq<*bhk#-aVJ(WBslOL^OwnH{CybNBNdTIHFT zO*3CKWz)?U8S?$xa9Hkktz&Xg#?=S2XIg^!FWC$xykYwr$8SlyeY-4n>+aXsP9~+Y zlgTOVgyr~h<4%X4$ErnP) zPR{qGoZEv&BdZSza{f&#=gdrvF=8KrD1CNjdwAJgO#I&{R{(n#OB4kTSGncYX zCZ^Cy+6W_!6dYAFVfITNRj>?SUSz|g+GgF@y<`NcW-jc;G;1?MzVF={vC|$FRw_K} zlFV*WKH*#K@)W+u9f6!n)aM5NMa}u>XNJEQ{L4R5`IqGLg1dKNtxqnK4NuG_^(W~@ zQCv@bEaz~s%8kz9|19*>zqCCyJJS_@Tc4d1nYmupk%q{~#Yw2QrGFPB{Et>byC`Ej zIa?LCgQJZ22qS4PrdwgLAF_!CZT*m+!?N{5;mATA`Tv#nBr;P`d-`9Yx4fJ_+uOxp zP0L_S+Z!Vfk>wRRULLVLZ%j%&=F*M&4EZChS!yK6VJylBeY->yVstFQsy^8q`ZRLg z0dJewyjzLfw;!GNZk!xnG zKCzL-*9v=j-zcmk{hc$`TA(evwQi4swzku1t91NuDtfkuj30{oRgCw&3M~`b%8=i4 zGi1*N_9f;5yP3fEJ-*(Pdmf$%Y+`X6%T6*6)YA6Qf=9c9Vow)z0DTp7APoksqpyPw zqHloK(-6?X^exZ^`Zj1IeFt<1eHU~jeGl|_`ab9^>WH1lsa{{u8Q%V&dG9LF>8%#I z6M9^X)SdAa{q+@m#SZV+@D)49gYf+tc8$M@@7J+!ycfQr7kABdDC|FvtPJ+Jdgt=e zMu#e+c1QeME@I8$5z-0r6pxUx&Ld=8!V%IodS8Wc|3&G2e2m^F#OS@Y%(k^JEX<=% z(9-E%v7H5@`OC1dwrQ!~r+$0Y5!Dtgwe3^(T{f%JZgR#gUe|FPCRV7?xye*LqFbZ> z7`D-cy61~$RxJIBn!FW4={V+Pr}Ksy=oR{<@Uu~pqf{e7vmi0_r+ z@|>ksBWxiy>vx+-+togJYzm*`;*))!R*u;~cm;RPX~yL*F&cy?_3MR#Rp`OaG4`Pe zV{F#?7rnNN8;$x5|6zsEIMFZ~OJ|k3%hhjjlogD}1F-T{^N%(;3Y!^Pg<`BozVw!9gWrTu1bBj zz6x8+93lfMdPYbSj8dCiOzAmPWMj6Iy^|}d8Rs2LKiA}EWX_1`lR3_PGB;tL#En<| z4$9eu@p^8m@oF=7vIm=(b)7GRcrGr_s2d?cHApZ+7Ba@99GZ=8$&v{%$fHU33b4> zH^tfZrpajDrp3|BF>}4rxusX<#F{w?*IN1m`rD(Wp#AAK&;fJ@=s>y;w2uA+I*1+w zt*3`U2h(Gq4fF(PBmEh42t5lrlAZ@e^*-n5s4{ zF?U{%ukhYC;w!SCci}5M_dWQEEa;>7iY(~U_zJ&$b88m#j%<(x9iJ0Eyldek&V*bJ z`A<#K?N%3PN_b6t^`E6-*&S)Z=3nc|VjD=SeuVH@Fub3ZGc+q^1q zo3r!|Y_5W~LteYt`)(+^z1mrh<^=wV`+AKtzqM`B?sd*`tWVYM4bJ>FCT=%tdy_NQ z&1K-a#hL5JW#GEanQKd8t{LQFL}cv8<`2uLJc!2^Wd>uc=_7KvwFmo~EAp;UZe3PB%$T zlKZubb6ac5(AMtGTzi&*YcFT6JCuQIA7`$8%fPkPnQOl?aNWh3>uzP>+TWS$z%p>% z!L*sn=#+ZD#Hea#BthHf zSaxmW982#|j%7zfj^zMn+d43@Z3Ve&yIRYi=lwdEU*vVw|27rOH8B~JV4rCea!%?w z!b6;OacE*)@aR6wnd`*FTur%`CTBS&<=u0|S@OsAG&#n98M@tPvg7EUl5ljV$(_!C z+_>=rbR-=QdOXbrokb_ZPfhhM0G;kV20Fv@bE?5^Rr(BS9=E3WccqjX-L*AT~ zDb8&@tqg6Qm|*qalzR1lx^r94EJIs|R=Vbr8Y`1#uqqMv`#bgLff4|%q>BHxP)>5(?4aAw4Xf20WG5I5CJgPy>cU6d5P}avH z)Q-B;JBhuUq}6xK^#bQ!zo-nhUR*t0%3se;?88ja&O+zbUy{n^7d!L2G_kg8>2hh| z*MatzRXPLcCj9q6x*fER?gSk~cZ1f`y`Y2X0ni3|2(*zN0Ubh*gN~#pL64`WKxffC za^~M4Bb@QrZX|C_d$}H zx-@;z?A!-y67~W2`&wt7>k{$|a$3c;KWSzOe+KaDhT?Ks>E{Hl8?yBs>z#GFq21~< zt`@7DIyKL;Y^NKYb-F2`PAd!fp}-SQaORvW=gV!~?96dX!nShtmrY&0&1sLGh>A@2 z-}$G3M0Gv4cdK)IKS|wQn^QfdYq!O@9&s05@%{o=ZU<+3!ZG9Pu`y$3r`bQ^d-2!qGjU3+)X7m4$OcLHkRc0onyVJAK_@Ceqh|Cu*qb727^_&slBfp3XMXHXh*nU!VsV zuXun75f9KgWLy62DPaqXj_Xnuw=G`-OA_8n%nQ1i$bUCMeX}EKksuC8;vf%^oeNL5Q0jb+gAd=hagOYC>d}pcNg4 z=Fk)soa3BhhVfNN{0n=uFDio-%zBGM-urw<-Cmf$dk37Cgg9U3$oYx{oE0rQ_v^li z`ZY&CmNvWsZEf}@A!g^j$7@=vu}kkg2J3B)x+SjbmJ2q#tqc&&LGqlS2 za42l z{hGd8K|=p#*5W%^%RhSb+3am-Nlu%6s0m4`-WywP8O?H-_1(V4`Tnud-+tQYkLT(& zj*-FITNWMU$Gx?6ux3V;#hpee#FW63XT1$bw5J4#=@P~xDUkNx8od= z&1n#u9Fln5qPSl<@8+Kg$zX@4+TBz+qAR#4c6ra0Qr3}+h(+WTp! zy_Y$)H(mUGhI9NrH$g6!eL{WFY#U!67~C|wr^Q(lqYpx#=<5;V_Og=P#Ki48+gYFI zrqbsZb9yMS(-%W_I?u^YljL<-uO~X%&B=-ErY(KCy25HZpB`ResXo19;g(gk0x_-% z|F}$r^wp(3zu41{R^ta}{7Rn@44)8CrTRJQ4EoSKc;uSca{~I4iSajd+spLDzH05i zXYIdXJs+*@O55XH-uDXcc>6DSkH!6RQ@!tY^JsQ!O+wr|-lgB|uB9|_$@!4aqYFVt z(gM)q>0;1XbfMfmeE@X2w*_>DS8m&GY`wuOTtA`Oc8(T7nhH7y5;S{@K{-3Lxivea zR?3K2sd(n`qn{+XA(j7SvHZv8?D@NAhT5WU#T)BWy)UM3^?oaud)^GqJxxw?Pm;Yc z-R@249HaU^t^3|hmX=6c-qKmUS@JT(@uG@w5!zikYdNy87F*yL!Dh&>@j3|-sC(`` zE%w|+m5MkYCDx3#`|f_^wikBgu8?gGR&T*+l7pRk*?oV4*Eu#7_crSs@sfpUog=cp z9Mv4)7}Xqzvrw*kfz0g!M{XCT;x;ksw$Iswlc%n2%g|NQZWh2d@J-EgoUF!u<dbA#>~Q$gO7rZdtk(V*z*lf{vg+ z!=tG;0Qr7KWcuPGSH8#BqrD-mjVBGF1a9XPN1r_{fzM`cqa3w5I+0dylpf|TIYU&3 zBJ*aaSZcMSKg^Pz^Cg%!?4!7aj(Re2p5(;2$(gf%zs$|jhNHL4xY+QN#5R1TV?SM; zVBTUIKG7HfM9(`X%Sth~EskybI91y=8`~C*ZnmV1Za#Hv+h?iTmUXo3d;;IY{npEo z+YYI?o$ko(%v9WJ9l7;O#jW0GlhN^(cK2Wx$F}X3s%?uMxm}uy+Zv};QnJ0^aD4yO z*!aG)A-?Zcrubgm(68SGVyg*uon|MfxlNug;)<{(*fF<>-2B>iQI*#I;{3%u)5rN) z@*{|)G9q3XiiIZ>Jb+y+yf4O-jYf-O;g^h_COZ4Ql5+Mt#BuB&nqcf_=yn+khqEP9 zocw_M9yiZ|%N=L<6{%+Um5$t2rQ){9k=y1}+$tQcr80rFaKH6&g5Q8nF6Q&qbMXhyI+zGsAq;G1&Mqo*B6RhB>xzc!D-Ew{4Cip(Vjc z2sAn*q*0qaA=c=m6dGOR7*8ZQ!xP-tdXJm~qxUg)#LOR^0f*ow=za73q@9$?iTZhF z&NBNi?fLtkru@Nrr<}<;M_b6y{c?s1_JM-Rew%$D?%6}ZwRCocM@nE#-wj!lP1PCm zywKU20ZqIu9$0(*7w}k(}k&1KGkG0uRc0 zBl?nnZr<3tEc3=A(tCeD^d{!ALgm5&r*(!~odb`KiCMco_1`|VtyADVMB#gx+aybF zle2v>E2rgVlWXR=;bfE^&{W444dZ2rBkY3C%DcBPw< z_Hb%fl8OtiL9)3;tBbVyXw_|C-!n0zsdw+jzqRfu9_(c&drVT}!M49BV?Vx=)sbcC zNjbi!gl3?pT5IRx??2;O5uwMC(i7UuR_trJjU$}wC0!lKM#sot6Yk8g%^~=&PgNH3 zu)%sPcn65jN*349s+9=Iv#+jMN%uHVm#??4(sj?)vz?scWGCsWSGGFZ$tTWs!tLtf z)UG6zP0VXi#$_HzmV?p93k#iE>Q?c=ZM@RSKc}l@c+SyIUPxgln;m&=Nx^H2lMd6> zOnmCZD@hGQmY$I-yXQei&@PB!)jBcXdqp#YqBc7kgQckwa~XH(YQ(Zmqby04hG|W( z+Nn3)>d8!eo19whR@0RwzeejtX+O~#EqnV(UZK^?sdY(eVKVfxj00Oj>sXt*aE|Hb zI%bjCXRmkkZ5vYfwiS-NR;J)p>(p=Q>UIR4%3~PX?7f6Yf_9ao7y(^PkScF@39UqaMEFtlR$Bq@3Wk^ zy5-5aZHG8pHR51-zGj!o;w-k)W#&IDl+ssS~r$1LF?3t7W>>untGPg zo!XbAx;bc{xL=;z*W_@5J56=Ta;JGaNtIlN-jMNekk<>&$RF&`LiZ{Q-)620>GXUD zj!9}Pe4f{bcwXkfGhKy+OH7omzG9|RE-XoXGyBk$PWG9uu5xIliw=`iR^Xm_ITpfu zo-@!!`#pNsx&_wdCMR8{tr~UFWs;iF481LN8D4kW$z(v}LQ*d!xdw8s7%3nxM3*l8(l_$y%(ha`B0E zcn`+q%njRMcf5|J?qUafjN-(9Ps=)`U`Kou^4<$^8_Lavn+?U88Rj&~z-e?DI7Kx$ z)JcPljvB0`ifVC7Qzy{=)CF_^)qoD9UZ8cf1Lz>?16oggK?hSm&<5HCw2^iL9YO;^ zN75dk$5S0BZg|3}t?6D(PTU1l4?4s9erRk}VvLC1%Hk`=R32Y3rn=)R##B#y#h9wa zSB$Ct_=?`?ofG}g75%Xz{!83F`7l*i2d`$`jDMTv&Ge4-wxb5faUcx=J&cBd9!}o| zok$}=kD%{@HqjW+BWWz?B>Dm9Q8WQ`GW`hjXxa~S3LOACl@0=(M!x_(hJFP)9a8xB z;_nH`YSH>iyx29^8{>W8)mP`~JGc|!So!MJ$@Cj&xAaY0IXVou6*Li=YxeTc8CMzY zl=W}5=$z|ba&$ZlZr!Zn5WkjL+)=J_emZpCF5o=YlJhtx&OD~ZIa=*_{NAQ2A*hFB zPHkO{(2JI$@A}hipabX*(1COxXdV3tbPzoVT2Bvy4yMOI8|VqpM*1`8kcjX6BYd?O zCD-FCM#+u%icxYGzG9TzgRdARkK!vv$=?q3z|(fz98d$hV>b-s;-=j2lM(~|Eh zttMJAHn`P}w&7hmo~OmF;^E!m;7n}ikQBb9hh>S{cxl=ETh7C8j|KL<4U(&`m+}5} zAW?U#(P);@eH^yr{r9;1yV+S<@gA4D%N|JCqu@nsJV*Iu&CA{w?;4brv}efQeL3>x zq`WrL<_f(Z)>+_31OM5Q@20VT;bmDT(bXKk0Z?prU7bfl5-aoHMhIR2U`fS&`u^Sj z#gcUkjfmozDXgpLcugW@{8$igW{4LDizTcHNvO`6<(EyTLA`YOSeuIaF<0A)zUS$` z&|9pVwv6AeKrC3^_Ja8>UP6yM31CyR!18fl*_;I6zZ;oCgIk^Q!);yN&26f2Zc{C#$pTM8)&)5q(2+C+ z^mv*EI*aa+b6*SSbnoX_o6qpVdDQY{hp%qUTB+G#wuu!^J(Z?b&!+Z^d#WYHIdbzI zxE$s9C%@9vI@;8Iahncwwm$ABn^RxRsV)U4oAX!9>D3hdw9(1-+|LTJ_H53!aGOqZ z)?SvTV_a9zQ`nto_SS)Ne)SRu&u(*qgXQG**__GXzq>j`pFQW)XX(ykL|4GUu1h!@ zrS5?V z_Q~{jW7|}HbKCkkw~fb@%|17C+AReqn<{MPbZH7s%}yiOy?VH9BBtdfBBt`~JafdP z?mV+i*wpfJPaT?~r`9_4RJz()7hjvEveu@OkhQlWg$J~$31d#HQgE`Vm|{+wQ*f%V zun6WZ+7SvoAbgfr-|z%hjna|lZ6N8e@~Hp>3aT`rJs_pFHbC- zfiYQX@D5*+JFM8p)H`rWcbaaE!zfR31}sZ{Z=EJb;cu`C}EN?`aV;*mF`!O{&QI+y4}&owrO*R z4vzx&8;>${j_kK^+iXSz-%RIr7AHsZB*ziRVKjS>fO2-YOKbIQkJt)xk?R!ol-%NO zu(0Cy9K-vB!A-(p&QHX09-Fh}JkEi0kRKcXo_t<$p5bMU`6=^*0mrX}I5rtLPD;%& zTp`3&I6X?Nz_@nG?LW!43A72Y) zmd`ivyD()xvhT6E2Zl%D4$dpH8oC`P73%0t&_VP7XahY2+DQLHYx!Ku@AH0b_Eq?b zI@xRR6}8#7;45mgZ^c*CX5Wvms2W^`ugIHUn-6NUTk^VEGf@>9u7vYfV625jR(1A) z4ZFVR%Y5cKojp0j*>b}=4Rq9!w;e0nELJf*CvdyYb!ykyj_s-?T~)zijMV;gDd+&Y z9CRRE16oJdf)1kVK0Z!_=^@bd^a$t& z^jo|$zu5Z(FZf*I1wQD0U_L|7(lUHE&?b7kx|04z8|g#(hz54c(ktF_?{)7DZ>9I9 z_dxab^a{O7uhDXPomS8rw36PWRrD6Ernl)GdY78%FSLfz?2aq+P( zaT43jIM@x>y$fxcc07}xQt9rn3QboVW`Fxay2>znKI!Vh?D@D?g|Qv9ZRRYl`s^$R zi*Tt_<2H?O;Lz5UXFP*{f;(kw)6IJC#T>Z})C2k+aTZU7xXH-QceMGkl4 zU+U>z(7~Z7;t~AIkcj_EA4?RU^QwZMiq=taU)$7_aUZNq+y~nn*4k<6$<`QR&$YRo zr3KkmHH_uU^MrMke$LUIX%y#C)l*!)j6DkTrMkM-&5`AoH10%W zyqrBl^ZJ(~ZSi@=cv*9Weh=#_$UN|B+U_)C)N{t2X7u~AtF!%=Gdm(q;>C}HZlQ5d z9D9ZJ)OI64m%qu!_E*$5xb|E0BzE+qpx8hgb`J}6f zw&#ow!=i^?x-M;Lr z_&$g@`{KSn%waBeuQsnNRDuS(vo^a|JR`f+f7Vi(J?^KlM)l|!(2?{U=<)Od=q&1o z6ZliTuYgYXUXZ8p!+YPsY5b&n-{LmO=-&4St>^Ny^b(|~rB^{mPWM;T##|AIcu9S=a06N<;aU0b8S&?qK-Mgr&jnQ54Bf3<|bH=IXBXUlW|_a$N5$ zWj^B78C$zZSN(6#XGV&%dv31)Heto3hT1;9;o81T;ck>?LVjW{W`CPGOH@d>y^_d%C0_R~Wl@2jO>&Ol9qEt4?V91x zE*o3oNV!yvg9rRN^aYqHFLKtF`XH zCV7orAA>#g&8Is-$8G6v;4-jmT-G~iEO~X^0*jNWd}_dL?Zz4#lhONu(J44lIm;Uij}pv;$~8^#L6m8Wp?XUxtu*Y-BM8L^h+;7|FN3Z?k_@MvfN0 z0(ZYE9;0!iVxvPJyH=r9hde>Jou%5-f^i)e?}%IP{c*3a4U22%a>Kf3MauI~-K}~% z-2SK!bnoYuykAEZ++y!*MXgO@J@hD8sPCE0R#|>I{R%4o278l~JwxN@%aPT8&q3T? zZ;~`u=<%?wg87T*ts0FD`#0D79HKFIw9<=vv1@2N+03j-tV+EPo=01>&Wok$7P9_g zFBjHPTiJcM%8R9|2}x%klax<$I?3{}HWc-XZnk8qK4YEmtoWRR_fJ!w6}547y%E#` z_>q6|>MWbA6YF4KtiWtevP93ZG&^X_y;7z<#S!CkY8){k7Z*pgugGUqDDoLuBJ$Z} zhzK^Pj0kvyt#z=MG}SitBh0ndrZN(t4z04!MA_sycucl0YZ@N1reU$x)V?Gh6Owpz zti)`Y6SMjiQB$^DD^;5_x@-aCoxE}-`MXlQlWso>lI}&dxFxh%lE<5Vs#XFFw7-EJJv-IZi}56lu|IK=C<(HGp}@1S8Tu(=hEGb3)hN6h7O z!#qf3v$bl2MRzJ2mjxELU$VyB?(JZWEi&Yi(%zC4oo(wKW?P#bJ@&O3`Wy1*W9d)G z&GL;yO_pzqPO`iqD|pwGwbx*3RZ#*Ro!E= z3hYh%HOrnB8enV4(uc5yTG|Xcf`)~vswU(+#?(}ax19IQ_m!)tBzq`94Uo?JWGq8pV;Ev_ASL-X-QV5!wj}KJhd(Qb!mCIrx?UrZub+~uNpG6 zMegW@xw+jGXwQvDbA>^Jm8muOvGleNg}m)N>$~LUORI2?AvPFh_l+r6xf$}?^jN4( zP1bFil(0=J4Q*PLx=sI-winoVaNpp;)~z}e6%Dri6ln0JkOt4U=5?Wy1_N#{hqzs4 z&Fu^AZM?u3 zf<4kqL!>$T|EXQe-l1&cjgV}8lL!0VSwu!mCY_PjmQ`%jI_ODcHi^Pds(bhey z#0sMLhWa7YP}LXhFSTMBN~5qg-iOB1aWs#DoB_A#6ockYOR2eFo$|ZTJbk{UEnMih zPRSB=6m{u81-E8z0VvlCE;O|Ak}`PLD-D)$b!yA-^BWh3w0N1N7O!yBB3s55Lz_NM z*(T=lse#L9W#f`H^nX63m2+Eq8My3FHZD^P`yJEDw%<`}XiLAcwPhCrm)*+7WwC+F zr75|Xyv}NaZ8s;b*)?%&GPHD3Vn1i%xX#eV^@-c4n+>W;y^?Dyb?_G#Ws?^t9If}XF3eU;Lg$RX_Mbl?2gP-MKqU|lQoJIUNc zsTk6axua(XvQ!TpqMf1h3VWjE{&@wvwk<-|rgX$VGSsGvalXgqZ$w?9O;t9JP41iZ z2EA=arMC<d13JB{w7+>LQe_1#=a3sFM*B*th@U_R{ zD}3$A_zDm8tJaeP(HvYJUN&5v*}mkBo^&Xdx4NKBUw7d#P)aYQPaxDNvyiCTE{+O1 zhxq$_7nUO0Yo(coTAYYHdSg^7G@=IBK zMj=kdo}uyjh82K%EoAU|&Z5$i}7oSh?E4RBk+jh>;gw6?lf-riJ&HD?9lIFG(dM}Zzs zM}y9ysi3pz7|;{wSkMpfzdYJZCxZT+8nLRuTTY-|Xc*|XX*lRe%3xok#=8b@Qcw3j z!dh{LcX(His=Q60Q@!RIk4|pgRi6RA;)SQ<@!f#8ojO!@z^hIxy|=s*ItA*{s$dU!p(9lVpgRbHmB2e5x+ZKdB^otq*@H3IFcpfE3Um2lF1+zjm{ zd4<=EQ>@pF;&uw#H6yP{HX7Con^LV8GLe{{y|8V@%|6@2?Qwb4+@=DT*QLzEt-32& zh1@uY)u`J^gj(t?b8Ts|Y@=bR9*vP>e{ay^X&=y8)7A1 zY`M1AuoCohZ8`b@cvsL%XjQYf4wUx<8^N!W_qNwL*DZF3m9rsB(VlJ?Yjz_j%=4Sb zDi-q`YsGV%HP3SU?APEw!#;a};m@p#4Uy9-0f2G*RdzdyU0uRm(O7=dadkzQDnELDt*zftbI{# z*_Rf@tmi7Sf3>W#XXqy}b~ME@A8hv`d0Bu^ZeibazM`l4vg(Orta|G)u;-UN z2Hq>OqlJoo2A5SolsCo|f?WKzBL(3{V_w5?%xnr%YZ2I#2+ciaV%^wu~e6y_j zDR?w1oS>yS=PQHQkI(2gx-YDcqy$C@(nIM>03ZSHbl8|MC4YiP&1GPUC+ z1CLiy@hEq!a!Sz}W0o>!t}pBU0r$a`@P#(Dc~>W{uU~G-VMSsND=j&!a^z4=hhSE$ zqr*TO=yc2>T#@y2*#%@Z4{w_`R9YTg{Vhk=K*!O=92zV+G$!US z%#y?K#2m(0-moy*@rH%=<&Vc0{Bccao>1q8__M+ywh(o2$!7<@k}_9_C(fbJp%NVFJ)|%t) z;+O~DR%%~C>~o)Gt!wU|5!Qb*GGYI8vF1?Y#G!rp&HW92vs=h-7Dv|c7FG`L*;U$~ zzaBG3*h4FAM^R&?i)Uj?+h)C!*5Y&@QcvfoE1V%H=L*I_A9MN;nfL8VXdWo^(&Ko?Pm*4p|w zp|(D?=I~iU4q0nU&nNUKy{tLx;KZS8AyO>8wsu`pZ^L~L{{9B%UfovLi>%jKNzdum zT5GkRlUCWfcd_QMTS5+ttvOuk#35IRa>KD}u&c#0Pxy8=(c@wzD)x}J*UUS?YBW0M zbd8Ct!`#znC%5G*3sxy4^j9mv{?TAV26q=rkGq?r$7M@dY{}u$#2gN>wv@aKVotUrCG z`Zee@Ivn&EIs$Y$-H&$eLl1x+Mh}4=PLF_2q-CH-(Bq&@^d#t!^c3hMdIt0;dJc3l zy#RVNy#zXiUICp-YkGL}z1A~#uR&iY({G4yO7#@)A6~~y2O8{+@jmcAt?o+S_xAS2 zdi!|eydQYuy&rlLy#Mp|^?v02*!zjMpO>ZAfmll`K}XOJkiFnagfXzWon$4Ex)aaZ z4^EHm4eKwxpC)!exCaigwC6(|?U^}D$=YVkr)6D6y~)=%Tl)Id);`a~Z4z{7GqW^V zd#B)inpM&oqVLn#S;G`-YX~ZQR)gD6Y6krP7UEa<1eHDSz_vxDPg_;^EWm9C?8TyX z9=-|8p&ta6KOywt!E*6bleHMcTB@^?W4HvJv3tCl66GBn=1nAQy3g6c{?y8LJjn)}f zL-kcj@1Y9!*MGji{^}N!9rw>##GSH8nkg5%Hll)Zslz!7ymVrFIFr_c8Bk!7d^J&baohf_7^MCuHB1l52xQ4i1~sTb%Z>J54n^#z?w zJA)ogyMRui-9e|)K+tLQHPByW1+nJ7rkg$yR)0&TDviMrY1|zG|AdC^`g=3PB&w;y5Wdri{)(jv14wD zIgGKc5*_Vy8jm@AYT1U*9NQ4=OZw;Kqx+IJ=jEq3tPHq4)v!AAtP<>jcXF!h$kIqT zhrKKFK>q~gGo@m#HuLnW9&FDRWN8$5)zbGsN6>BH#XJ1st^reS(dT5JS!B(%&Fhkx z!dZ&}Qg1>2Y%Z*>bj-4h?B7k}c8HVZHocK_#E7}c20v-twm5ffgYR~7Fhk#$_8abp z8J7KEUysH8@SNp5@q!$OrB@T;mRt3-^=3=_EeY|PE%DbR#9wQPzb+yEOP2VrIN|S9 zctc=!jAxvL1syYK?l&!K?l;Ipo8cz(0ZB(I+!MbHqvC!Av6tiBuxiBo@Rp1qATQW zi?@SL_f~<<@a{qj^4_WFFL77UFOa4J!g_2+CzGY!gUk2w*vb6p{g`GJBrs(R6ctPDs?Adup6pcz1h;sFQMtquweI1 zmCqlQU$m6^nkEp&ete4##p#@~<#U)<7b zljBTUfxg1hC#-bx39O&Z*816!NIx%G9lqP0pqauwx<_J0Zf+gV zqW0Y;Q$E+aMvV0&-ZHS!liQt^j4$p%w82k)SEL<&(wid1NgW&cli#suhoAI@#f{b@ zc~hc!O;p<2=qKsjhvMBB8+^CB?=p0`jNZfJ%>FJv+geN>2hUme!wZS}K~%=r=qdTF zcXs&6@4U0aPk!T_9lqOrcig|?4n-UNC%^g44nO(5Z+7@@x4yA{nyu}BO(OdjcV*b< zKj~d$Ypvy9mq>o`dX9`eOgy|%9}GWiQ}lFCL?w)an&c!`R98(y}zPX)Ex ze*JNA?RII~vcFM^$H_*t!X~e<$tfqv_~PDr8!frLoKr)+aCcK3?EpH6`hhmkE})I{ zeOMvCoLPzY?*#WOzM^g@kFTg3>W;72ed&p>s2i%qSJVyl$5-sVRHI_iuOAZo$2n0| ziJN@IUW}+lY{9>Y%2|IGXRxf0?M0oyzdv;W9Y8gp14ATS2A(ur9So&VH9(8~HX#?m0+6X$3wt&{rR?tBtDjMr)8|YyA6tsap18t`o}(V1aFE;=)`2T4c8%wZ#o=CJl4>F^jyhqX&d$HYiFx=2!vF2_~bMX%%W)|c%o zz>F@=3faW2$+CU*a=ln9XMYhZsqYtyNK?c?9_=aP?&4X1Us~c?p|MJx&>E}SueA<$ zk*nzAs%+1Dj>j)cR~U%djP>3&JI`T1UJuJDrBxwSopnnqBeC&NOAd|J925;%|INNh z^lv$;_H`IlnTU3H-l{S7gCFPES{u$=hSn#+daj|Wn_LfxHHsR8^C%Lh9QU+rcl%oF z4X@(0-mt3hTCXyqk2=d1*28MVJgnE3@H#?gx_)h_D&4PpT3fMV`Ih+#mv`SYbgkS8 zz9m#~VPEBB=SjE?qITA1UU8}5Y+p7xMzP7!5u0Q^hCd3k=xNYn=vmO|^xqnfzUkf6Q++Ana@^VJzl<=vW2u)B zg4=HV6E(|$*`HQ`4xp8w1L+;mI%)u#k$x@FL|T)(wNcn<;^7Hb8-GTxR0(q%_O5@ zXOiFswDu(FaE+w?ePr!P(lHuIeHm}X&9_UbeMCIhb&Ru9jqvVuw6za4bW0a+=R-G& z23il^f7$}=i?@=t;(nID(MI}^KB6}|X6O}fx%axa(tFc$f3JwOZ+|1z44gx7&HIVF zlWh9d<@8m1$iMfF+0)puXitN+e45{z^t>KW#=vR0G+JK$mkO)rC43ze*>Z zpDk5~(~=hvYO%h>4ztLobWv)Tf=Ujqbm<)8Y*QapN*=Ky$|>t;=GB7#kB~IHnif)a zx2gjQ>!loZOF2jyu3E}T3H>#ZkgP|cW=XB3($y)ITRu@`BJ}0gafrT*%G)zkQT64> zn2|DyI*vFAbA_G_>n5lv3-%uT+h5{r*stRd$o|c&?2WmSgDtG9vo*U{yTw(uiIrWh zkT+s!x`nK|xUMa%ll1o70{am5!qyvCnb*F2?kL6Qj*R%+e5~z6{ZC*+qGFA!G~=wJ zw3TIOTgLn?mM;7lFNyx>O$tmls}5*Z-N|p^u8ofj~~2lS8M^|y=pbL#=U=lRSbKe^*O1% zC{Nd*R<@3g4DIm#9u=ixFW@SC#a_Ujg$mQswR7PbP_-V)k9@f;S*y0>9ooX!ZFx^a zFDtosNF?{gxPzeB9>N|$?A=FT!SU!LLm9Qq$i*Fyh4Z@qzRUTzoYRW|*iSF`ii??OI{CSJB zuI#@=CQ$WX+;`orY`dp}Z8P>LE9}vUuvc2y#i~Shak`bMZqYg`>s*gtnPx!0{+4~r1}oH!iERFJD{OM;1D3nms((8r z!amFjdtxH&Emk`DIFY_o_KAa{lim2qOFw93HRgF9*uF3X*++^36h3cs}NA~%4n zqB#-^&f~U+^(CKK=6FKvq^a>l{QZVDS%G=z^U^xY&?F_^za#Ty zS=wlh$$VPBORJX%_ITAX$NjwkeusBSqG#%O?`jeJPTa0?G<&JOd$!HW-?t?4_h)0> zXe0Nz*1H%rp)8@A84UMJ(wrcBK(Q|u?8*h_zVpiYYCk{NIb<7tj?yeisjOrR-mWg* zZ5MYtbX4}|)*AZWlzuyjD;p?`?SL}d&1z(ZB@7y`KS*3Su z4RiaFG5#D(bwOXgcH%4Zb?uLP`%3tI;je`L!j(GVeaztejo(`)?$KV+OA~(g%I5Tq z`sS6{ZsIi)mCfE_OeYn>?_K#8{zXftKY63-OdWk+w1m2IH@+P4{S}O0{X17KrzwI{ zH$F!f8!lxh{Kggg7{5|ajRn-YfZ)uH+6$`R3+p5LnpE4^ad6^Bl_^e3<&?&J-o|7b zQNI$c(`dlF(SnL#oqsDnmDRrdfBZR{_9bKd37hsMWBl2g_9bKdshajBWBhrV91TE( zRzc4oQf~J4!HsyF*S)Xx#i#J8$>3g>A$T)tyO`L6SDlT8cc1o>cfatOVlLK)#W4&2 zou3O{MrT;xrx0$(0kQ2Eo71&pT*7uNwu-Yab%?V~dG>`?+%CbdO6xXDUq!#yQXS|B z`Xzdw>m0^d)H&>JS?AEBQ19bcx|wTy%D-X?->auzFHNzkbDHK*=Va=~)mE$CX8fvj zKlTjOQ++vFR&NH3>e!@*CM$cMWNFXSV8cP(PV}zX(sesiEbX~h;U1YW%bMr_#kZSKb(sU=-x&PoqHx&=}Bxv^VG=+6T0regHa{ zeh50mQPyFQS?s_L$5-UUM&K)QiX&Tdhr@CEqL7@W>>eXuu{7~I^KXYam2|o*Esx0i z3wiu=KrB^`{txZ1phFSMHhYso5$)PSWIi_6xpgNgx;y0I1=P|}wm8?`flkKUnW118 z{lxsPDeEl9%DlAt%4@mrmiKSgXkV5!9w(r~mem2bU81hp zCmz{uD+{&Ld@eg2Lj)u zVkGfx#h=B>BUNzQ(W%Nzrkgoxv=X(YEIR$G=?APsl!pNc-^Cc_!U$K_IbBtA_vxo2v ze4>}SNWT@{hvbpMeIwR#Hon{TOdcbP$`c!8+m&jDX2@RusqFQ`F`GBHo=2HdmMX&x z&6ON}7QW=DOL2H(HJSP1Ym7 zS7GFf+r3V0C#$gQIu^&ufo4}&wST2``!jTq99u`r(Hn5F&7Ig}VKas5_%H|C`*&paedhHF;YyU#}rNCBJ z=hDX6IvWwU&X{)HM#{U5%=5lD2i}2Jg>i zsDa)wmnl?#`~C(Ko?-)^mrbXgLb%ms(rE{3%Bu2C%$CPyv$Vd%+_5h8+|hx0hIG=s zOgbs2o$X&$E<4+=O0_fGeF>|sE7*BB&MIZQB8OT$w~8}1+i)vpFsFu3LNva@8I8P;{sFq_;ND!Q?5d3l9rQ~lO?PiJG$9GF!R4)a$1BzUmDidzH zgiQUvB*{d@kAKf)R4&|cDdqBgw6E{>aRSDl(Rukhbz<16Cq z3-J{m{x_}hb&#PR)mqKefht3BUqzYXz7F(pNS|BEq|XlYSqS&jGU1jpP90yi_0WXS zdZ?T-jw)L$Ju(zaXXr%aFS<}m2amS%0`IgaqdTRrB-0C4T^yV6xryj`i;*FF9Z@!W ztqI|FDI0D+gqtlJ?hYZ`US-4W7s9PA8}7sq?qOxaofcYiPbt%yy8~?w`I${+@-tc7 zrYUj+e$;U|VvkxP%LbiGU2bbVk zFLcyz2O1sn6{E`JD>~4jA>2dCgd6B%L`WZ(Y4vf1qdua2*=W_5L#_If_p>Khq3&zx z-+EHLT*DrXk$xae13ippfF4fAflj2^phwV2piOiN=#exBbP}BjdK8@vI+=b8dNj=k zokACYPNfB))94b=V`vHJbnGiu(1~;sxvgRMmUeJC5Nhd4&=IsA|HAX=m@>?xeM7d^ zr%blifzAx!o?bTG(V@M=F=g624C)21hL$VnDafwY3#Q+p4f?;FXD9Jmyp;A0DQ&=E zj&?lHb()>Fqg#RApKb>oKzD);r29eZ=mF3{^blx0JpwwI9tUlpCqWzODbOJlesw2! zJ?6T?DW4k(r+jWIobtIFU$Lsc7hkceUxu$()!)*3`lmPUOBS{D;vMaW@di@+l5T(8 zzNku9UC@-Tmv~+1+8lRVP;f_&$b^J4S4c2e0}Mhjkr@^$a;x%d(VcLVu0{N>2yp9b-FTzsi|7WAZ!tS?74zlu}r zy!evk3Vj#fJHfcr-v`va&EVWWyK_!^wX=w5c%H8mF=RVIJn(l3$C5}lFVhum?WV{5)vvT zgp8SoWDJ#g=Jz^lpL6zEXYX_F^W6K~&-;FV|Lj|P?fu$o+G~$zKWphVdY#^&H|Z^U zo7T}g^e(+e@6!kLA$>$2(xe>v;k>r`UYtm`WES~^gYtH zv>9nT`U&YC^b69xNWN(~7$@egU%!Kh;m%&(!(Vp>^8x<4C+uI~uR9KXg}?4v{0IDX z=kOne*5dBHp85Pz$Z}F&xK}L>kHQ|a=CHb_C8ZO)HsYj?&T`eSklMaAaDRc+*NOjX zud+^3yHP8|^HC7G-eDV&+i^eEUh2Qgo4uE2 z9xL=)3@%sh?OlJ(>07~nkvFXQa168SAlh%r;>dr8VL>R4**w*Mi#NF2;K{~f^-B|-&|HL4ok%tqh8FaS{!zaaOl1!P_;Ph7U59M za@_CT7gUkC&fFSdKdf5o&ABz?se_)APtWL$yBjllsWe4f#H@K!PG-%T*K_f8iT@2r zc>iNByl$55+Bik)1g~%9nAeLl+O3?N(Qc*IK-*Xi>{bp9d?z%pF-IC$D^Op_395fa z^B-0zttcP+8EvQ#>8?}_XlZo-Gk~N#mi&hLVq7l_fmg4U6K3vUh$=^9WzNSJNj=ye; z18b&$*anzG@UPv$-<~+xX%M>`?0#+Ht`GJK_I(Se9wcf`4Uu-D>1Zwdj&pS&xf00! zaB!LLMykCccMm7uDu>ViuSLybd3D=#Wm7!w=1CXkU3+fQ-g8k+!3uNZXgg9!Jzn2Qv1n>7He_ghscg9bl;G2KjU}T5Co9k?u$X zkhZ2cj)sA{S2_6VQY{^LK|GHI)R_HaEB23x!asWBdpDbZ9F~=T*!$9M)#9S@9(d|pPIp=@~AF6>SM>>iyfZ0TQxf4Jy>-w{;K-nd+}rP=&|2LK{h_Uk?v7>hTqU`K!|E$Qd463aAD9=Q#GyH<0SzwRk_a7krHU)Xa2} zgg+!!OG7i(d4c!Eor>Gh_w4O)dw3RcyG9OUYjjks;f;#X_*%g>+ThM|+u)*D8(fm54N~5lkN&KEcwxowJ0!)6&ttXmWybMH>-Otdw2fKnwgF|n zqH2j~yCZFnv^BLtx>wHESWU!EUOw%Cm>ykU`QyiK)hewwtSEos`w3j_eQNd0pkKyY|Uw-KBNfHuSbhcpdJ} zRvf$!pV@D79Dq9s8nZ(>ZdTVmot^D#2|H!8I}&d_dEYnbd{N!@{om}^n5T1J6-YjbTc~_RBhyb=S|}ao2-& zsTY6iTlsOecVQ;`Te{EY#m@iISvCiM8awCvJd$=-saEm1Z_2wx>|^HQ{;; zwaYF0mRQ+;D!1%^#$x_mZp?yM*^A08d)-*f`sK!K7>n7s+?a!6F$b3$^XOR2{^iEJ zCKmI$a%27*>r0d+X4P8f$(t%VzU>^V!#4j<%Pa4_XnCv0%3Cu_c{S#%u|D%!x#Lgs zSUy{1$!D6{TJ|#9RLkAh!sjNgLC-7K8nk7s{M%R{;w69=+r3 ze;v3N&V9-{^Ym|6SFN}uZ&d2Ib$+ZCFU&H=)De3}W!)mnF#j@c+dq+Ep+HGU3_kV|bg~=NBzYvvoKI$ggt$xOK z)1Gj2B4Yn?AYPM*cwNSbX;Sws{5_lAvD(b$j$Gpky=!|gJgby?Anidtk)G|vfU9de zv?vSXz$3G@f47_MIg3jW%D$b*cIQI;GznArs6fv`nl=^Ha9JkGwi95Pz z8?UJe%_ZGL&Qx>S?*}G&&`BBleJ&!1iXF#7<{n-I=~8JC30#M<4Nx#5vPj8PAy-_`lT4eIssea~!Cx=mexY(uqi0)5%EV-a*f{ z7wNt;w}$&`A8MXawK(gD)tt|n?sMxBt?+KfR?vvwB_eLh7}3Aec?#_0|B8a|JHzlD zws{v{-4Pj%uW*xRZf?xh{B}qujg9Tona;G6#>N?mk?n>I#zxI=ULsaH<0x4`k06#e zC#B!d@o)VtOz#B!9+r`Q{jZENS$C+uDSuttpP`k%C;pD#08(F`tKOKqQQ=g0q(3Um z%JHaBwPHp$5i_nAZ-7qE&)tsujfwNq%wJ>Dz2uI>D0FAWQAi^WE=Y%196{3 z#EuywCXH5~C-$8$Gr0Gpb^3K8*2Z%5!+#SIDPs+29;+wnv}QRF2PGm7E(c=EM8xgO zfmqhpXPL&c+>NWJg~ruAb3Cr*j?2?STpm?rxjZApx>A= zeO{%>{c2(idM)FqmOHu649Q(kr?U1swo*W*^l*-LidcQw+OAzo&NJors<`{h8Q% z{?54f)Dk;h*+>yRH`7wduTb1y9+t1%DOv2_Oed|2re(Fa(JgTu*d^n03hgtSVtr;y zRz8!vNPSi)V!fKCE?WjDOiSz&(3t#F)Ly_vQSEk3_-gIA{ipHtvyAQqaJGoErzTkMqepl=Zc1ze7 zJUF9$LH`S{%=ZP=o_+3j2i+IOS{pICIMGhEGqzLi;>Ee4cyVNo<3$}YlBlzjvTuas z;#P+HDrop-i0*qI$42Z=vx?Xnu~VW=J7;WDjo3U9u|>v+x$~0qLS8Z?$6li4{w&ru zpO@1%!xMK^M`p3B>hCnZ63gS-tawb?A$vb@Ciig$J7l@D{P`ivH>xzt9}@dQRj+Dg zeUq)H|9OGxU<>|A!!L+gtXKiZc0~+fI~= z{&q#kU;eFv{!*DEb1wYl|7NE+H+Ms||MiX?j}FUfJgRs+sLb)V0o?%aZbdgC-H~oa z+L~q|Z9}t>?n-lzwxzj9+tGbU_n`Sm+tUL`_o5wf3sJw@dX;x?`x@`w_I2L9?OXBJ zeQD)({B_@Jork~fJ?@40>)w>aJv3{#Yphe)Z#2d%|&ha=@74$Z@ zMy~ay<`;`YdV4Cz@lN-z9~0yI&l$(}iuW&dms`!Ja(#=tD)`A!*8Wv-y;bJPNG|&S zl8_&#ablIrd1zIzYm-7-|F5`REA#eQF6I-Jc>-H8{vLzJmC{nAy}WT}d-&aYWBpV9 zuR^MOqq7=|<@j6HIBPpus)Z3Ux?`(;@n`|&&K38i$~-mB1%JoFR{l-P%DjJ{bb_@m z!?8|}of{L!&hIkBOGoB!ZDMDa6V1LY~-H$4DVh>|MY2zy8f+&6vzjrmIE0MpXCj)frE&`e0?A zo#&ztt_=B5X^#6~K0OQcJo*tQvijS_vTkwOzKPV)(H$2WRA?SyKbI~44C;C8F_hx< z)?SqMzD)7Yb$Ta8p3J^VshEw`zQqe68_$M~bGdG*7=J2`y%gf_@ErSKRajSbw5*q- zbEWpNbEOU$&z1ZynA8s3|0aUEcNEm`BrPES=0tc$@PEUVdk@k5)y#^{t6qkumeQ+8 zyL;=g;Z}bwe>Bnaj5msF;OlJnE9_2@@33FX>N{+u@$g=2ZpKah9d>vG)wd+tdHT-w z-pq;6uK%s8ieGPq;=}bhj$eh|JV)xp-&yu&^YQN_+utpBccb0kIdc82;_|Nx$^U1L z<KBk;r9wlXe0P;Mc*Oakv1W1O+O=TL%$;3m3~Lsmi|QAj{Zfu2T_T8lAVWi zFX|&svOmMgwEF_k=lJXHj(>^2?h9mF@Yg-b{tOm+h*ax)<}CkjouPxT1(DeWE2t=_S9R^Fk}E{^R7lgrT$$~w=<EEnAVUw^E$N#~{f6Q7_$u0*vFQ;` ze|@8UwxzWPv?yl}Xk|s)J}b1UFb=miVn##ShdsmnwalvJ84almbJnfOai+cOki?Os zSG7!HnMTXS`EPWrYm>-f+y6(#y4r@{R)rB@XJZ5i*)mb@hh^y*ZLRUAO;+(o^R|Z- zZMUq@8uD+Ll+adHZmf%2MeUYokv*yN-Kqc&2j`rJiuIcw;HN_+^qY#T>U)Bx z%IM1#;pxyy;Yp7-QxeD2sTs{KD-x^vKtBHq%V_*8f2^vQZ}tUGxgTe;k6lNAkKD#j zZTE{4?LIjJyJs&?znsfcF*_d(eyUmw>JOf(S_~Rc1$jEYQf!yKPY(nix$UFb^Keqm zd8k;w8dL@SWpEYbX-K8;l)e89tz!N&4E*FiE@!Wo;gz75ip-Tpf}h;am9p2%s4AwH zF_og1itSIHT`4?eZ>w>YV5^F(XU+jXxu08CY`mHPo^l^=D#p`9@Ra*`VD|oVK^60# zNmWEI7w23rdTllZ`_txcF-|VY{I?i2*7U^Js;|$l?3)r(p{LyUEiK=b*1h~`&{d{4 zW3%rQSLfXJ+4FF1&UvWVcsCvVn`w9)#hGzR}ov?Q^jm`ZxzwY{Z&ja3&2nA=MxnhXCAB+TUCswhbl== z71_Ud7(7+AIl?2AqNnWVbB}_L-0mY+%zqxQB6@kEis|J^@RR$wMa68Teh1!u-{XIE zFXrh=(o;p^&kFFA`}mW6Uw@{G`Sf#@Vyo=+@_f$ql06SEMY(D#p_~@Ra-cMfSe*eDrrk78_PgU^Q&#IVS zJ_kR!kDuB5%a@g)mx|28zXm_Kp95sCmyMO6mx_$H-&GNR*;EO7sffR9sUrUJVeLb(-8S^*!o~irJXKT#gGQG=KG5Ok5ihLF0scjYU#oco5i`n-F z_m`}yQh#V)DYmKD9J4moeN}Ca*#UaWecY&+p7sGxRZUMFE5)C5eC?F3h8LMT<8_lB znDh6ik#r`FqR#2Mv_Bn7gXk0*OsCQiI*o?X=`@Vapy4!v&f<5Y-Pw%)efon|oQJZ; z>5O=9^3$nyw)}Ll;*@5MQ`;(6-K^z$!iw``);RlEaXMy=bFfuE-Llrt_EvscWzA1d zD?dH5=4YdopYO8fr@a-YL)JJW^KJe-DnDC)o?^wBnl;WeE6$Z!<9ue-&*xd|r?C~M zY1TN8T5%rF8fR-OPV=mBT3B&fW{uOw+Aj{xx?lWg<>%)N`6-|yFb);d(MUT{UJZxR zd4A;YS3AWo6J0=kYd64n;QszbZGM}ml#Zrl^dzmImGlffOV87b^b)P1m+2LHH8ge{ zYUQm@hP>%9=wU0)BU$6Lw&LuZHBK8VPTQ<;p10z>kTuRpR-8du5K&xEGXDwH$m7gwI^E1fG&q-PHlPi1Gw8~YSwOoCz zI7eiSGsLQ&!CC9)VCxv&BkM8xY^z-3vX<)}E6%-HtiCkj4Br|<02?$mkVV=1m&D^p@ipyjg0x=Jv<{^9y2G* zr#tiAmsU66ccWT3{tWYi2wxMk*7C&>gh}O+Y)S-Wa=B2Z1@q;pwX@Za_P(nFlq)NM zGCe@KHfxl8Z#9q-tAQH>#Ot$K4dl~pyta^Nw*+W2vqIB)njNv(ta90GZUkjcxlrzl zpv)^5$^#LU`Q<`c6hT>7E)=t8W`3_m+h|FIm&N7cWoZQEv2vk26+u~6E|irKl;!0@ zS!Eevp3OS;h5JxL5sy3JcRrF<=nd&b^vOb6gY;-}f3t8JtwlP6UPn5I-b8voy^VAk zy@T{gdJpMx`T*(kR2Ok!rqdMZ0_RAik2#khz03I)>2pr)nkea9jdX=`S}lj}cJ{_8 z#Y*S%x(>Y>ME=#a^T2Tl&iXzAW-)z&v=i+Ggx!KNM--=ned|8OwPN?I9sCk^Sf0!! z*&6LFaQY*C%()QhUCx_GpK}_s3=3F>7A(VJ`~u=ir@xS4y(fb!Ngka`6KF&2df096 zAIquQgFlZZqP$<{i;U~&e)UFi0d&?W(9Ua#+R<%&m2q47^bK325%i&Vgl59~U8|MC zN0!4AZmC@Zzsgt$ADRZ=nML=&YutSy_vG$7Oa1F3^>2)=uX)~-G0$~ly&%q$yRqdb zv*kZ#%eQ08U&xll1}e>C_UQ(O0`QMHr$R1y6S3tm9K7C7{p(-K;EJ?NRg0@wY$&p$DW zt3AKh@vCr)okyG{&d;#1+9gzbfIU7;tY-a$5OsCa(sTjV1B=WZjRi{kI8LZ%skj7pgNa!#WRy>da59yS_V~`(8e>MjlOe zesnhC@Ab}4A^(3W#M`n&-n6b)hUzR&tmBW8jlrcJWn0#fqil;h)k34JKf>zvrj+QI zKDi_*rt3O?hwA*9VI2y|^>2oC(xEzeiMl8ek^N-H!R$sw_U&Ow{8Ba2W^^Rt_$V)? zJFw~qryJ5Uozr2};m#DKM+H{B0oH8ieBO*@9wRr;R)z|v{kD_wK9yGNl%4M?{Ypw`kb>nY`WZ8k937I4SsdE(~jq+zlgbM zhdS;YzXa=;@Qg0p?^TaiHjdMi>i6Zh?mmecx~B{c#q+MX?wE-FXa&(bC8GDJAbRIS z^yeywUYdyR`dX4_mZkSDiRkXvN=fL2)D86=>VY&(haxSdE8*FH27Tq=I{ECoYNgk+ zPGPVHR-6-1AVPb!W-UPc_x#$P6}zkI^}(t-WuVfL3@*k8WG zd|;)spYWHHGW3^0i5mL03=Nev4=~r~;d#I_kU_4`{g|%j0X4|<#lhg&p&>|D(I3#s z6lW2T);O06kDP(kz4FKx@C$3&BU3aCH5UY{-Jx|#@Nf5?le>TF?rF`TdDzpM@11Qu zkDZMdp$C8GGOHp9`E040+_PU1W8!enQng5pgYJDS%%G5Vrk#%(f3$Oj&eE|xjO5IbhPt4(led6km|^GtvA1TjLZ8t({ezM~j??oo%tVqqKKg{WLw`Jm@TR9&&sh`$8sggLEv7K{}4c0kJdP z%-k(RI?8z$>1gL#{4(xv=RTxo2C?E^kH-V5`8@i#x1tVw8EI#F7U@`8g>)Rfo_3}F z8tEvf7j}L|JHH?u?)-*So}T#^mv+x^aQ#9=|Gx<^hCNC=}9yh z>B+oL(lOw1e7!>2&*|js?{sz!a7vv61KEjx@wXMy&eR&|SlSusI64fxz%ocjIS(Nn z?R3Um_)O;lq}o2Wc|86Q@K`H$E>y-W2>o5-n)5{8?#k9vAY(C2Mf!l%?o>`Z5n(Az_vd|w56%NMgNUk_JD_B^gN=2X?oi2liO|L#cK_uJi6 zR6t|kW8-K%oddtyQl!30E5S@;SDdhP#z@eed|hJd7H8FKs=fbobCk;kQrSJvBe}ly}V8J2d9xlFzZ=)8)_SSMLpF zw*ThK6^^Ob$HvqP(3(4z?qZFp*^Eu25$lu2rs^5Z+Z&0IUeDNNKgmqrH?m*UXTRvo zez7b2#qGi`-i`Q0if%zY9gk*a7>`CHzF-##X=fUXbS#ZWI*umtyxdCR|auK_(^Z3}ay3dD?>z>^>WJ(z)*(}I6Dwta>H{`SRtJ`Ax)yt^w_Nz`o zzxp#YS1F)7QFA`s#h$hnvHCCPHKczB?cY(Sx;F|Q&9i;?^x8ey_B~(ieZ}p1y#cJ} zoaWHua_4QNE1a`ofWW2Zxt3#((rRGUZ44j3~J z;4!mThB{ow{OrK|EM$IKF+Xpy4%Z1CF33vK_Zhh@BY(okQyF=Cmh@|Z{9qvILl#Mg zdykffh8KSwb?4=_K?n4h;<(s$9Wz8|yL<0nl^kY7rdp|0M4y1Guyz-!eiRqZ=v z?zyirFHM=3smx1f=4BQ0a-HDi@qicmURXRY1@s@%RsqzFMb7;4AKahW3;i8SOH3!szPnGWfH~ zLaY$oQB?0N_*ikHj2d5_4S3o*_(S!}A2@2_9ye+&)`M?(0Wd-|G_e z9XH$m0630!w(0JnjPOo4qdE%jg{d8)xLuOh;4^ZUB#NbXMrzTYkXY*bBXE>QpCIi{ z8$oU0%!ciTIdhOoeP4kxTHk$&e0`7OJ`=X#ddA$qn1k8Bm$H8^GyHp=z${MNFqI9% zm;)H|BgXtRgsE(JkHFkEzzoZ-FvGHc!LpBF*++(CSD4cT=15QW8X4{4WM}8Nou)pR z-O8P&sGY;ROA`&7d;tma=qse%>2}uNPCy*y?2J^}`E4O<*Fb+^Or^gt<}Hl*H(R4M zBZp(7+n=@Xbn!6b^`}mh)r~H7mun;<{fHpeJ?hOSbwA1XzHe2x5#>FLzP0_ipS#=Z zf4}fN&V0TFU-Rh^^y~iu>~BK-T8+8>Tv6Xu{Ju`D&`1^?nf(}9QJb-kV^B_{`7io;L+J-0R`+YTx zsr(|0S)DQOW6b+Qn5ti;1m;Nr=DF}78K-_?K7V08pTkM^`?9p+ET9OiEg^Y<%rR?Ub{?(UrCZ(fAIxLw9a zppg+yc$YECUwCKn6KGoM?>E-pAFRLcxUXK!z4Q{K($0Gbn+yv2e;8BA9LC(pn3EXu zq7bIC^X>xkWDirXaP_KoNc>~W3H3RU?>EW2qnBbn z;qQ({?V@)?Ausfx+jZ(jXVkjgT2u&3X~TTf&Z9!4-RW%ZSA%#Sa|%*v!;^%**9844 zjHzrG#vH?#Co$&9Axve%69wi=9;P2dpBFK-T3tOCjfL$m~xH(jKZ1@zb0RJ>G zs&_p$=(v4#V%$zs31pl_e?ykrgYlqNNESJ-u0`(MVQHf}K**zdNW0T1=m(g;q73G* zNTrR=7Wy0=^s_LgvQZdw5Myq|m|KT1m5t64m{$b-tP%3H-!(||yKrn%bMkO(%O>^~ zVfCQaKw->^#mj~srr$4-RUu&m-gX#>EWSysT%91U>8S^B^`n}c^FgaJB;}-WA+IrX5+P+T8wRq{Ey`k;;BiOSIn$J2J|L z6sD5K#QXvAs)2JMV_p=(R5Dc;n1^_nY1#$+%qJPUb_&@_#xCDa;&!GdU<@4Lgm@pXAsiAg1CK0u-l}*kaPFUYKmJO;XPUP#oM+(Snhm^bcJ&{?=bDgdx(oLU(kDY z9qOtZjb)*AX0(-zb||B{zvZ#gnFgLU+CCmy+S|ka8l#VvqGMfu?IQQB)81b9Hz=)l zxjV&_PEjfA$=7G+kdM1#nx1!*B~wS1=`xn-NtWqB-h*2sWa^TkhT1UNhm3X!qcvm= zy(`eVd1!hZKR6-!=u$m`QtrA>j@@O+xhr$_F>^MBIcve3eI_{TnW3ESs$;ox52MXz zH22pZRyvoUpJ-1wG=kO`UT6E(p$~XSQBB}XbJ{@r%bn->94;l!;ilkR);*ssOVV1* z+iT3*>CD?3Y|;IMq{2Q_50OBt;lqut498wJ`ChDG}Yw({>|W$u%^ahq3i zncf~SS8`e%sNp3y#Mv}+h`f98z@+JFqv_GYxN z80{uTJCxDt3$)`iMB9_m9%8f|8SMj>bc{e77(t8k%FIrOeXrELbX~CeGJ9!(w>PZD zA2qi4F>DxSChn=!@S;M@mWr`zbZ>IFw>Zl3`2AS!$5`&YS?--#i+c#UPx9o}oDNFx zQC(`MgifMNsJ6MV$fmb-0?33Gf$ZL43S%s6yn$y18tU+q^p>Q%;ci2}P{)>g@!GfKr4lJ&}oa>9P zaoxMS%c)=Oe2kI)w{p4{o*(I1`ZP@2d823N@2qy#SQlo1^_hqDxfQFX_x6H%UEv}~ zR6>^^y`L^cx{NME`Xr5pj5D3u@ahH50r2YQoK~0tEO(}2Twf7*Zw*pA@k+m$?7`c2 z-?e;~$I7S6T#-SUt76O4@Kz{_=Sb#=y(cf85lhS1xo}+zs%J1?-UyB2ZJebuYS)xEh<`DaD>bRXL8MABbp2L5_W#9zaA2gAMh zUzX`9mdX94=atUmqJJz1^csh7A0w=0gjw9fZWIU)1_QPQ1&_+A!kTwivD0ShdBk{sYyk#aa4>Oqu_xF%jI;#=ew0Axd@Sx_%<)0l__hugD zpL10A=3C{TX~pZ|Bi6%Y)HzFuj2I@ehg(A75%Yq$6)-4*Y_Ic zbP#j;0Q>$^Le{6tl=VMGSjh-~v8*2ngcW5XT*3&~F@pQs+bf+Hgtne36JatVY|97} zSc>BX56_i}uz?Y-WP}dP!=HkO=gUNRmJtqT1oszYS2~LX!V6_0T)_y(FhU+9>?Ndl zDL^pe(938G@dD{MdWqxEzeq&is9nGt$3!mI32>xC5W z1_-7t-e+65aSQKsu`Q|tZM5?ZQf-T_fi21#(f#>+eD9veQasL5OlK*M5PJAHkRr~S zn;2mpBV5XwbZ?62ap}_lLCx>WKeMmy?UIy#e6L$tr}qSY z^!5aPE-DJ`M7u8pcE>)WKf)bSP3>3rs%Dm|?#;r(bFCj)o}XEsXIP$}Sf0&7p8W%P zOpUma2y0$OxQY?-QFpYnMIaoVfZ&b_IA3Ih8H|u(gdYULNeKx5GJ<>BF^+C#gdbRn z9|b~_0731omVZ~(rpY|Cj#VP_a0m17C-d-=;9>iK2UC;ocQ_6eF~WU}P{ew8P9W@? zfZ*7n?qP%)jPSES=#+p^%m}p^VF4p-W+{FZ2t5-J>N0|RRy2+lGeQCL@Vh`b zHb98$rHfI1h0}(6>7Qz}5K*#WJ$FS_lJN}AUlHpWoIm$d-;%1`58KNHJ@KuFe7V4% zW2&8(6NF@k8FNg%@*5{se)?1(KH4o|E$qo!DB@`6t}%41YV2vDy4as9&(2&t4-YaA z+c6JMu_fHmSo6>{;KB6it=Suzvo}1&-mr!JN&0llz#G)v!Se45`Zg_VFU#NM&|mtc zy;~l~L)!3N2Y=63-|t9M3&^v8WXTc1?yxSYF)-f7wac=yn&X!)LCRNStf z*>a}R`M%ycv|3Sn#^v8F&bDp6OPKa<(VPPL!go$g`O>r_G%=rK$)Og_X3C9kXZ`v_ zrZxQ)pVnbnyI76UL*jR_3car$cZP(;q`q4?4>cM&Um_hB*u71?G`@axNA+G9=lyZL zZ9RROI45{NM*CN9Z`?nuntM*|zc(P~1~c(WVF`AJ+!HOi69fx^t5P}x7Rn2Lv1>QH zRHELmQ6Bv~{Yh&a1*${t zJ42m3&72NS8aZnbZBBDuM>^EG7SyrMxj3a766i|nXMd}H(sUqdT^4B3e?{N`@Zn14 z-n?^puI{}^Zl0EPL;Vt}0}Cy18iSAL9Cv?vxlEoKx2KpcEa{@*DsyuT$Bs%al2krO70H#A=Hy* zSw{5i8r2IJlF3uUfMgw@pYw93j!~8Jw?lUOroq82w9Ic zWc77_7RqTqKhDs7n%uQaDM`E&47?(7{-I7ju7^q92Cr0!gC%~YYf+# z&b8dz1bTEG?A6jb7-H#lnmW`%wei`7TRf9nTq)n=4hzk zXnaDg9k|v?ZtF}T{kdMPLUER+W|QZ`+g3$h!LR4PqtQ1mTlc1~qTvHCHz$$Z{Olx{YgnA!NBVu*v=K z);v<Nqybi(?mr z<`&s-vpmAh!MLxVC(Z`$hK5IzIw5f1b38im#M$7c8REZ9hMif4Pg#Z`A_m+OXj}cZ zK-l;1MO)qJ_dM4p1_Pm=vn}_4=Y&tBX#xIUO0y6#ehIj_pJz?J$1M+yh6^n^(i&Wp zNL>u7>(A5pO+q)iE{CuCc2{SH?uaf&Y>j@urM{*v@!Ag03~k!ngSGh|Yx75;&Br`# z+G>sCT0e8G70{UOCriCrX>!k8X3}q1ZQc@Sav3yvBi%$d(=Bu>-Db7#%Z&XuW4|G= zmnU#Ek!uxj>^)YLcCaV_^Ar`Fl( zgj&~ftpm80JFnBVUQDQUDc9PXYke%*T9Z)gPOfz-*BUBx_=;Cc`)AzUJe#-N$hbWi z*WKUJGOSJD<}R)^f@@tbxOqLH*3De&Fs{{DwDo2}t-HC_c&_E{-DnQqPN;PU*E*hS z?IhZIC!yB;TgJzq-|_!TpG7;(mlKab-~A>X;JO1|_D85;lK)jCp%j=~D3aMS=yM z;96_A)@h>FS6Nv=jn#)lMn`i+@-(-%j@xr*LfR+43AhaJ_kD{p4tTrt6y{yViOEsNr25_lvbc@0CCG7IzWwOS~7k<;#8z;pOV>UYjNMW68R+ zWW9tXs@HehFA2?DYIiJM>wwt>)30ANKKd}U}gl%ej z5)_Fuw7Sp~elHH`IC>v-M>(5>&)0!PU7xqLbtbp<8_zS`7v*&SY8bR-_R5R6)+5ZJ zdoHYNHBP8?D%V=VZJjJ?HBG2>HrG0Y+j>~k+B%`uXs-2{nm>t=qIp8CmRxHo*Ve(W|{@m6KZp*zPpmkX4wdL_SUyMSvWHcdJ-Mwzxvkx~t)8N-seu=VEzpN+_2pXMqQz0p38L1~ zfd#^~j^JATxK;~p>ugc$d~2Nj^|n%n8TT();epg zfn4h(uJsGox>wZ7_cX7^z(JOAUs`i8V-8`=TFn3B0&`CTbEsvUmYBmBb2ww}!k8}z z%#%G#e-4~|U7x4gdeOn`Wz{$mxi1muUNpw@GOeNAyqTT5@8O?m zY3kWQi<)X{aS^w89%NnV>?k73xWKQ?ha_9#aMaw}DLd7*bTIoo80SEFm;)8kOzgCDph=)QbTQKBycy(J{QHHVysM#? zowpr)cLyCHh9UKT{UvU$S$5egv2IlJ(tMhN_BxaMHCz8+H_LxPWpaIgZ@YlhZSR_R zO{01FGyK`@Wk-hWknb=s>>1`EAk z^SB1+@IvfouW<%qK0YUMmQfA2H{9RnDe_KH!(SV!^V9f~Q(K+u&|V1*gM809uH4I= z5y;WsCfal|9pzFK|Bk$^j{257{*7^4oj!;#DT;p&p={l!g5NXpeeg^4zo-w^F?=wt zf31RU%>Gs6?c2wV{Id{;hC08Yt{(YQbOZkH{*Hq>@tA?w96lw7Y>0N9=q8jZ_12<$ z!%F$Vje(odztrh&d^}iV<+s2)Yf`77?{I8&-?!4y{MH~!s@SSZ635dbQSx?c$x9gX zMNx8=wPYbol8C@B)ZR9 z@)|DbzH6u@nr|)Hg-f0x;aSg=C%+Zse1*YoXg? zoc&Qt&uXQYv|`+E1qX|*9Gu1_#|ZhCSW9;0l7)iT$E+pK;F41X=2C0PDeNV03O<)v zOZH~WhNAVStR-*alK+a(3bhZ&CpS6}8#hCL&>#M9K&*qX( zh?1+VB`;$weIT^-qP64`T=I5-xyD-Z9BzGsDEW%DP~MW z9Zes=M+ZCifRldCkeX`(1+8&$l4}KK z9c#%CxTO2Nua>Buwd9A)=OTgGz*=%WWA+uYH}Xnq|7p@d&Tutls|ZDUz|V}{U!XTL z(6@nYkh2Im2wv@>E3bGC3o;jrf3I5go}c4X~zcnG>I;vi|G=Y zZ0#xe+*39I^BCtl$QIXA_T*Mi6|L^%wVI|~8@Q{3N3n15N6_{z4br@lC_x{UvcAt2 zb-y0c60{3sHBZ3oXI~PtJ@a?9;BWT;GaLhEpFboU6fm-P%V!}{BfOWrP8Kh#?CU-q33g+zV4lKzZQ%@zB? z+TH0--2EEt>@vt&awq0< zx+po=TCy{jY$Es^VlDY9mvn!DMSI#%YsuHS=e5tyT_CEsIxx^I$biN*va%j%E+S^HxrZhfr4JUhS)NBwc=JF_W`kxbusaPUjQ z?u`fO^W7NpDS>%TfEn)N{kY^yqT~c?$s@VsTA`(h){?`x=X z8TO+;S)!*!>(i|z9WJ?6l)T8YSq;m^;PafTlv=hm% zREOi-riAA%VTtZ%%q;?Qc7R!yKHW2XQ=ju0^H+g6$HUa)*<52rQdVmXtgSuFt^Fff zn-@qBmh}QIxk}jNzMy1Tt-HGjrmU|pru*9&I#$jPFvG2X#U<|+d_EAAEUWdtLF;9e z+&1Hq$9W~SO%_IM;zy_OtY%xR83sF};kEsoE(y`;OP2Qm5hoU9Ebl=XOX1#~Qg$gz zGwvR!X~B<~&uxVT7khlB=`r-A=-OsU?AqpA#&Um+KzqXzfy`lV_<>74DYWyXwd9Xn zvW>ue+FG(YN0Plo$rXVlYLzxbtkRx|m1HWndXV7nIcux`aI4Kl$>*&l>u||Vg1;B6 zB^z+bLq*A#tR*jEK6e+bzicgeB4dsg{qI$4$zK`sd4c(wS2Ca8fJYS5TO47#VgEe* zJ(at2)E_Zc_o#J|9+mda`k&{se*fI9Q(b+^k6#4@_5zY6MubYpk^2wk_Eo{{2UfZM z;gau&k{@{`HOHSA9IHDDYs9^Tjv;>1v>qJKCs|@>sD$MBW46T2!V;f*e5C0wzE$ug zYuVS&BJ6Em;XKN>2u{PQYCNg?316cWejgMk`V*XoF=K2Ptg7>ABWN}0JEXPf0@V38 z*eQLidLI2pgxRD**~BPYkdCLth;9>{GX$2t6+WdzeK9w=MBge<7(X(`&x~;kW4Kz= z{NUu*(R}~Pr3d0hMwIUYx+)~!?_6# zjSc*?fZB!hUdW~Yvf3y7JBdpBbKv(;y%%_|3Mwn9*Glf#hA-w%rVUYb5-erlnFzO&E_H(UJJ zpnelK?4hMr9fiv&9UV}nj@nr5Ed6DcRX!a*2zP+oJ3jvg@k7?HYi+}iQzfjKI!MRU zW!%@>Mf$qxZS}ZZ11|R@*vhl+H^SFUc$o-Q|`WZxW1CPrB!BSxA^#mZ$P{|IB~ac3TOm4_T%?f zY=?8$N94GeCinHS_&%McW~h5eFjlreKX%`O@ONPHy<2}RxrG`S$=3wBtcfw)z3Hd* z@kVhzdaC;Zi90LGr?cQI{b_ry`yIxPqk_6GVq|rH5!#ySB zsc*bVA9&R21F}plYu}V*8e4G+=&(?XZpGa1VU15agH}q_G0$>>8&a(sx<01PLDVZ` z;rO)05}zbb<6?LUV=3R-TxJa0-l~H%wX^WOYrwbeBY%7IpFczKOSP>$SoUQ#HoJBY zk2Md*@bGgPez`mISRcC8x6dXw@Nb{VHok(ll{Id!x9U~md}-yiK>WIby1Qt*wdlv~ z_UthokdCK0+$U>A;<0+Wawuf0>s$p|gP>o`^lk;FX)$&MH+?TICw(QK z4q(0xOyDa`zb5)f0WAfuehlmiB+S4qb66?g(^ebHGA*n+NPDp`etvWicsP=}Bkf1^ zVfmc`U2n?Eqt?!+hL=WXx?6cJu>7{`c*}St%c=hBzLp+sQ^sO- z2ibP}SnBFqYu_uNp_mnvc(Y>j-6!pzVL8Xg$Qk|}N;NJ&Wm$t1cyFPGb^C;6eNkZf zz18-ZgPU_}wS%L^CUyV#Sst6_MaHJ^I5!0)%yBMh9Cg2BbH`Ds*BLQBsP5*@WKZf6?=$CAhJnzSJ$n{86^i+RBGN#vH}AJBDp{1>3H-u${!pi@{QF z#+Y;F>ae(;Gi!d24d%NpzdkR=F)t@DFY|f*(OmFS;Qcm3*#7;>oCnpi@+{?QVYP!S zvs(r@hh$Kur?rf)gA-W?C$kP(vkvkjI`|g#{jus4E`0}=lk;`S`w(lJvdo3nGX5N| zM9fW34d!?fW2O~DmbpEHGIKI0b6*B!7G_XpNd{$>Wl&~i24z-fP-aaAW!7d;=FJSs zyputhkF2p@+VqnQa5iL6<|}I%+3!_6KZ5(c93Lc4Za*>S@_s*4E8Ww$pV`*C5^GOu ze30Y9>A)(Xvv^$i5q(yFg(R`|N#yGc?$INdujw3*-LFCQesG%h#dlR@&*#nk!(9-I z!~2Kfb^n>%>c8AxQXKg;Mi1e+sG3*33M_LTv>jykW7lYIbAx4`T|jqWeF0sf#C#fy zbOAMoUjKGVkgvaSlzKhQ%3IQW$-UvKzA#ktnDNZfxk$%T5y#Zd5#6gViS~si^*P;n z*y(WB>1l75;(SK&=cPAdZRGAx_|ywys0#U0$fuDn3Xm1`L2&|eiAT-%-psoc$ld9E zceUpnj*|LLrr-8uiETeB&@Yd)eW8%~ih!zStXCx>FA>Pscy;yez*O%`$7$Y|j%iZz zJ|^m27sxwW5Vgq|JIT6{c${6q}0s{4}Q>dBz4qPpL+ z>i+w5gzEmTg{H2EP!AVeJrkiGA*jzqs7DIw^AYM>g69_^)V%~(FGZ;Di@GmIsK<$R zUyV?Y7u44x)Dr~t4UZ~4Zxego$>2eIUOt8Iylp{=!Omcm(6`uj9R znI91k6;gd3pexS46r4qS&E-O>uY!Q9`QXh*Y%&vhQ&zT829#b_*(b z>sssi{MHxLbpgLh8&?XB8U`HMc96G4U3X_&kCKfW=~2@6r>g{F(*RMm_lKZv9Z;Kt z%ToFhCt=?Q+G_!-e9gZl+H=R`9&G*XQKxp`1+5yTKyl0aoE#>6w{_5#(%Q~KFTS?@ zx}OL>+XQu$6mtc&Z9rAXyCouDE$Z$O)K$pG2%g(VsMAH=4iV}GLER@pJzXGoj8I1k zYNvpzBsp9pn|p!SVW&lS`o0;=-Te$Zftkgw*!SGA|+33-nW>MCuV zB#`?@sMiX42SlhP0{M84ipYs^q*K7pVMT5%b?-I%_DP9)0|Qhw&pip!*kS95? zI6|#0c%B@g&J)_45}_U;s8b`Ma3PY2r4aiDnT^xUW-b zP23UGRhnojsCP!FH;Q)eick*|b?=T)Ckct}iBKOC)O#b;n?$?!N2vRVb{9mb?yOGB z`(QwQ7+Ttu24dE+F_?8c1giT6tv`QyL})TPPdG{-KN=t_O}f8ItlND&LfutJ^h7{a z7JM?M-4)0$rRL!Iqk!k9ndk07^d2IRpAC=|SAPlWDvv5>zy;W`9N=sM|KS<1s{fRb zYIOwtb)k_LBh)#9x+Z8_?P47o+Qquux{Gy~;Qf^V{d(-2=FxV1_rs6AYe9A2BTLik z(AiXa6Y1r_nD+@_K=MhL0i4v-bKShV|2gjyn~?|IaG`T#9Sf1n=u3RCfUqCGX1%&RA`&|v6?Ojz>MA=uE~tM+s4WH0|3s*l3QPPKp}r=lPGf&XtlE7-w3~`h zuM_R&N2qTKm7xlM~pg$|9tpciweP3gjpl%RZT7#-$pR&Zx!V=L@>;j>$HUYAd>PbOu8&DPU zZZXJ;tN#R7dw5*=8d0Y-&ts3SgR`wwBV9z>?Y*}BnRf@YogAIc5cT&7cvq735Y&zl z>VJaTDWKjBPDj&bP>&Au-5FFhYv=-=qH~JUfU4R(L?9m&AS>!=!p_|z)K3KUkbtV@ zGL6MtrdQCevc{QWeC!RX@)6bU@q(+v0%S$~QnY(`gnELgdt`+AwWxbkKs^S!8c)X} zJtr8K-Cui~;G7qX%cltBFIExr<*_x>*?l1Zbk^? zTRmi76StSCi3ddeSwVeuPOC=S=IBQqoKBIkMe#mH@IE`>UD@dofj-AW_r1QFpw122 zRUANqVCe5uA)9KsLLYMB3MwbVV?4+zOO7VQ>xhlePw{Ic4wbO{rKJ4 zhNAAOpsupUYGIA@0&6IZyd^a9BI<_w#~M-hiJ-31NK?`7D-oI3mMQZNLT9fBd@J<3 z1p1o+Rq?$}@cnj#?{@^>(I_)VAiozNt9G{%)DJwWZ^@4mq*D6+#M-vrO}o;&KXY|( ze@034j*w`5M4}A>^{I#@wiY~p5s_#Yq35q65`B{(kZRKuc!xXC+hwYsr#3xdqr@Xq>%p+ zR3BN7QU6)SsO?32P7}E{-a$}P5vqH;PDhq}kE+`XzxLxt|JDMrFoL*~pjL}ecNWwd z9##AAwVwY@5B#@Q6L+3k8)>|?+6&aWL7Pga^%=q67xQ)MOLMoV+c2oBymKExZ5*NQ zD}29cgj!cnw~kQn6q;`yp>`DQwun&O?+&!pT1Kd|1@iV0YI{+)RX|m`YAtm2RU{I$ z7Ik+H>MC6wCwOiXp>`J3wh`(9g1TFTS}Le}M5tW_wS9zouAp{^P`eB2J`w8ELX#aM z)YnAaP7&%rLG2u&_7>FAfU2y}MOfjRh!xzgQ?&KF1$C7b&JZ>_*rUpOLErPepaW3S z+=W>t>i3ACpDn081FE{gAa{=r1y$`HDXIDhsr-KE?}n(mCtY~weNu!oRll#bzTc1C zFF~|cjtDqYS~*wn-Or=?<8J)7WIp-?QUB#TzJw+9#u#GK~2;PtnP2e_$NYxg%!>Z#xK?0 zZKAy)k@jvE)S*Uu!$f-u@g7lUcm(krp}CO(Re8)P!Rt8@UhfmgV}iP>UH97p?N4WW zRC(j@HNJ6pFmS^A6sqlUqHW*XeJ!3NsOLsFdq>!1LWHx21m6<_s%rNFfjlXKe7-=Q z6x3BRe0qFK|k& zuNJ1MCiVuq)Aih5G0J@y;!|;P6LTcb7Sp6;zZtY1)Hovh!B|6=()mbxP$SSbg)r}j zF6Pm#++JPKehJa;KyFvM6KOZP5ns(V3DMlws7mQB&`R(t+LF(^Irkox;$Xkk8;d<&TN6KLADDY^!{JQMKtApGGedK$J3DeH z+m`Z!L*?B)mlApe*?!yxfM8n`tT1Ez}zPX#dsxY!kv?hLU*q8K<$Mobz$k zsei{-mv0a%uX@H)+)A{6D4$#oS~F^kw!{5nZ=9z3zr!WJl~2)0(8Jn55AHivtLX*U zOnnEd`i=SmR`(nAjj21Yz)T!`>o+peUJqT#eAxTOv!L~$_QH44qHBZdFt6%5n=Uj)tce}%b*+q3)eD@>DqoTjzN-Au0|-9mc{JErMPx>fi(_o0L`?6!u*0U|B7HL8+`>@T&($qY0^fz ze@wxJ?h+RYUG( zs)2M14T#vg7IGchiu>vI5qp<#y*ga4SEQb@O+7AQ_k{+aHKTzMUuc-nht=C($`{nD zU)mRxZ5uJBw5|4qze7IW1SPxER!Do%v+%!(A^oedxfy6Z=rr)B$7Wy0?(a$Vpdp}z z0?*W zx<~G9`Td|BXwB%0i2ip+?q=E(=@uFZnjU-8v=?&mTL_SBlv6$83ok<>rL;Fnbf@S% z?=q(C3t9^arC<7U z+@7HIpoyqw`q>Efv-3a;``MwW(Utlj?M5lQs$u$BU(ifHQ@(Trw`U*6`!P-WlI}l* z_tm1Wq^5(sG#!oFo2ft2Ep#z>4*SjkSV$B$)U4!;aALzk8a5ZRQA2=H|y3#nL-RM1QtT_j? zI3Jk6?b&@`BGaS~q`kL}l>e(&jZX=Y+4gG2jM~;+ z-p!J|Tt+qXtZ96Ms+Z#}$E8T>&8+F4gJZAsC8MHXt-pcLSZF@V@ zqPA7Kp2e8a_&giA4sE~;Wt4MP#71*K+e~wjZlSpm+s@;9eZl=G=e9^a)u->{+IIWR z2dx?1AFZ%LyfMq6lphl%{u2_23nj=pW^oHHeJrNs7+TQcQZYUbPGKa zvCS&vVie{%y!$)udcEwgy;gJWsBP5#!;7GmP)o7@;E%^^Kx;-zBX(N{?}>}W>McZN zH}wjlZ#N(F6~>I(NZDa6Xgz3o#15|`*P&Z@JQ)~~?@iFU(%VS8(Y@Bb^$uupc6bl8 zxOvzIOpDs#Bjj$TPmpe*XCii3k6ecyMp(JxGk+V3~yI&>NDEgc>4B^5*d zK#6Ab7WfS7dUoty5#C8hjZ*rT+j|rB!t()zNn5#?QJtwZ% zKtWncjnOy14AIo9V6Q`;L!GXmofgn^Y%JKye|OG*8?gvj8>v5J*7NQZ^#zK)@mqZ> z|89wzJF6EpA7gtTRf?Drc}bSvV3Z68s^yB&emgN}v{&3WSK++U6YE! zUbIf=*N+vuFn_ML67TB`*Ay8 zLKopRzp~Z-pqc$n?cyB(S_fk*ayP}>M zZx2FlSL%+m8=Vtb`>A?|SnH`ddN0s=P&Kp{o};U?kKSA_diJ3(53^vV=m)H^bS&5z zXI|=_+2JT%N=G7{M|I&>;WL<{kh__VL28~&srkhK&`PKlc+}?`{up#T)8rgA75fF2 z8b=1APTZJ%64Ro7asuA5>Oq4*E2U_BR(c%F_2gP7MfR^Dv=0wKj4k$bG?dZLu;BRT zJR?Ah&a+a~MD(GraL%A~?%rJS-|MOe-RU>F(%z_WCgZJxJ@nXsm@n{NuI1yY=sKF~ z)CXQT#tv0&fi|C_ZK-M&eL-%-b(A=1t&MCL%S*JXP;P z(0WlD9x?qmr0sDL?4i~JDcT}@`Ic(F9@My|UY3(@%BATNZvRqlKe|o`pU=JvnZoC@ zQ&FQUO+(s^HiI`khe=V~9q=o;t*f~$sn;}J$Fvztlk@TvjT83$4!>=x{N*v^m(q=> zWA4YO5ppJ@M)$LnKHQs7_@!lxlX{OVMF)wtmIpdiK5+}hz%NP$wLF?_#98kw(YT6ulwv#sz&{{aV)L=#@7)Kf?w$1mkat z?6;v)WWN)fqPImGOFW)aWWS4>qPQEaD(26F9P`KlXW^Ky#+Un8(&+dy1D*s4ke1R- zNaqFL81vheg@P|n%f?K>%?y@KeXEuX)& z`|og1DKv7b896nKoLXKEu+UO>`V4ypVGmci^)Y7;=c;ohd7`9w>)O=q*RFrnVHxVh z$k4#xrcuC+8WlSuw(9Xvx6s6>xs{RA%*ffs$l2D&+0M(sZ`*_Gc~l#Anitq9MLV*V zmS9gltPhoYTO{`)%*eabdU#*BtkPWpG-~SuI|c2lJ2>+8jn=>}2IspPIqi&`-Hn_* zjhwxVoV|^leT|&`jGX*9>xB!HZlUJ+`l5Z>I6@o-D!&+W3+v&k#n4pbApj`qLFj5k#mZXbE=VZnvrw5 zk#mNTGs4U9#};|&rlmd8s5v^Qsr0lYW|TO~s5#ci8E@pAYvi0~%5$lcV}-VVvsGa%rI)+VC39nEBWIbB^OTXZ+{;PPO6Uu}lY)^-|2CS|!LvrqRY6Uqy@R1s zo6oE^YQAXXtTA$43DDK-Yb&9L6mlan0ylTMQ!~gvIM9lg{~M#`w?@wQM$Tp< z=LaL_Cod;Ozi_X666dSoUZ-+bMsn4;wLGy-(Qk~fBUXa8Iolsb+kY83{}?&{A;+Cd zYF#+Z+<%8>z9}Oo-^eL6a;kYbDXP)T^~kNzhqOoP_G%e5ON^X4Mov8=r-6~v$jiZ+ z0Q$vmJR`OB!zM<}t&E&zM$R@y&bCI*c1F$)M$V32PKw;O@QUe6?7fV$_~=eX&0UO~ zU5%V}M$Ya=&YnijUPjK|M$W!Q&VEMD{>X7}R%mM%7&#{zIVT%A zrx-b>8abyKIj0*rXBasnyqpv%&CZV*>CQB2jy7`63b54L^dQ7)Tbvtf)EsZ*oNMHq zXXKo3R{F7a~warOlCSzA=QG$?l&{1dPJaSZf#nsp0T7%g078)HU`MMllVM$Qr==dl1?>1iUgXB&%_2IZEq z?psG@1}e9W$kkeY%4qjr>=n7IrxbmMz2i>Q7`~IvGyQP6QFCR$iTV{l`F%`^o@Kut zkM)pk?|GGhx7x^g(a2e2}cfd zWaR8(#cH*)qga`rNE_BL|%HFEYda`rcJ4lr^KG;+EcIR_az-Hn_>jGSIZ zPH!XUFeB%1Bj-pX=O`oR7$fIcBj-3H=L93?L?h>9Bj*$^Cq<_=cV{D4;U1zbYM*A* zJl)7S!^jz7x`TkM$QdJ&P_(n%|_0xM$YX<&MYHmwvjW($Z3JIv}R)OV6Imt<$YOO zBW4aY59MUd`waB?M$Q99&O#$+k&(05$XR0KJZ9u9HFB02IZqim%Z;3sM$WTF&MG5k zwUP6pk+bIiWA4rae5(G(kDpmEcGUZ1wP-|NB$Iu`8g1?HxTp7&6o)DEBj0%v&i$hrhA`yAaLX%-;vAGIr2#0 z$fJRn-)@x^>K&(UD}KL~&-vWfXLyIo>mi`Bv%9_y7ID`xQdH;{Ipg$g6>vzXLJ zn;KR;aDNww$qi7?J*lRnCGE$$hQ zxcM!U-=s6kDspsVzK>q=rFinm^VAnT@3nJRUFBPKJI~2qCSRyoR5j4*>VcShZk6TC z$Rp{@$a@1v-WQ0uKM+$l5c9yz7~Z{b$yNI@0OGDNi5V*0u^9 z+2+=f&a-_5(|NY}<9rH=_w!HOF`gKx`@KNS*uZ(87>Jn?IBHrT=KVm-2gG<^`S~!A z=c7Q(oIuRSH)A5qyc^^7LpslVE(jdC$amyM&yf-4lN)22%=4kMLfjpE8YpimG2S)u zSs>4fTXlYZqxA2&_joHr>0bnnj0=qWm$%AtTKaA}EnRaf-yifahw*+6n>!!ABA@rp z_| zjFDIVBiSq59i4Zq-#9jh zftWLam~%H{(uhN}Q zP;v9$OS-K=%Da#7aTUJbmu~O%bo=U(K1bz$fUs`QcHV!}NTomIEAJ??SoiN?-|_z; z{HQvOdcR=#i>-||Dq+)$;zM_7-?6kq=5nE(3tX{77+zfaiSLCgC4fUs_F z5#RA2lCInL5n(-Ea|rA8_pvX19${VnQs4SpK)P<uC&(f5=@nmp4v?-m0^u}U{|8|`o)2?Z zrQ3U%bRGVauwGwR3G4d*_T~SFux{^l!n(g+_k3u&yt&FMQT_J-OJ8Sg*Izg!OnkpMBw$UzT*e9_}Wr&u0Z+xFTUa-jxaK{#GTd+gF{i?(aRm{Pz;p z<7@v?PM3Ed>AL+9zV&v$ue<@gvw99k$oi~Hx^B+{gmrr!@`WEJtjF&^g!O!ArYu=gTv` z@Uw*V`E~w^-R<9VzVxnyb@|Wx%IiT`_vZy){=vTWdGnK|Z=Jv1@5`j?`Spq~{3>D3{gbb}*9q(M<9wo(TYj2ve;iDHJ^rnEPF|n?H%Qn0 zd6TeSZ^H@e@p_A}o{ysl>+$};w;tXmU7z1~2^)Dc->tE!{@BH<@d;aG6 z#_tpI>+|s`VLe_;3G4CsjIi$C3c|Ymdwu19PP#7t3*Yfy`i@^icp^QL{p>4W{;vt^ z_IyKF_y1d8{*8q7eE5#A9?$Q6`F|j+%iHEl|Bulw?cmGaJ)2*SGk z83^m~$V6C|pV^l`D`CC9v-|Sr^o8#rtj|{-!n(eEzHk9wxR5Vg#23EP7cTA#m-L12 z@`X$L!et5T@wuC@UjG$*;fjRycvbd=s}k1ht-3FK4`FvanCiFwJ;`r#@FyN*5ljJZ zhBfn0F~XQv@FnY&;f@T(ypJ<@FrzWUu?2T#GNuz2;3Q(AjCm0WNJX>E#*D|0 zD3QgOzF3Yw(KsvRV;k6re z4rBUZJ+7fnZexaEEmBb{k1+$V3RlrEuQ8*r85!~!Qy;^z9@+C7(;VZm9R&**^Ax5d z1tkj7XUs-2N)K`BMwJU^iE@*#3XD(R54>7 z#t?joOQ>Ajn4Xx2!zfb1m?tn1yOFb`F)c9;n~}McF-@=rSMbnX#>CQMQUPo$&#Zac5Oy+TnZTug1K=c$`7`>WnQm zA)*HJ0Iy*=&Y|Ny#!SN%RIh1FFU&(Sir>q5#`{RZBegh32)mCy;zOLp!?o!zE~Dc8 z%u~!k&N{|4#VCA>>$tZrV}%7cgaY-9X@z%i6%ReY@3@NRA0!`sN1KN@C)kFp^^IwS z;aG>uh_PU%oD;l` zP=W{ScDWj*3_7>_!gRq z75agx*olk-IPd6#c{q#$ud?4_6gJ==)EY?rh{ImwevNgDSbTWd(M6ow%Ge+Vt z@(yENA{NV#f`Y?24nvWI93!|MU<9_J*juy%n-MwEm=>6ggD5zPV=)v7IF6#D$%7GC zh0`eUwlS@-1j)!hhHDjuU^$MV@Hut#7M zt|DeCdmAQUBZ^Jq8ih&Ni2T!8=U9iUXz)JA<1p@=!FXXfR^kNef55uMc7)AjzMuy- zpvZ@`7jI%EPN3*4<~fGpbDT!;k2v>u3#)JnC1$g?V+_8+d6b>Qyu$m~frvQ94ZSfJ zdy(T~_9YC&CrC!2xwIRjuo`DjVjkCCEWr`vozHr}P^`c)+_`|`FdVCK2GI-IZ!iJh zAr%!D(Js7)O}L7f#f&qiV<)nFLc1^!@i>TF@r1D$`;qrk_8$zy5~Lvi66POTB8 zdnxA&yHIc$*Ga5Kj?Xy%n1sWKSxy?(qu>hW7dE3z0{0As~gg|&rYSb-Ge z`+@U`H?bT?k#{TC0t~_@*pKYnjH!oFScMZPyq#+gMqnGRq4JN+Jxs&~{DJ5lT$3;o zU*I?j?PM>&a3tV2|;%1G`8Uy?*E1RF?@_Y$dg2WFa?KE`B&x_enGbVv==jQ4rLB- zzl9|@gj@$%W0;QbVGeQsf$`Xg@Wb5mqC37u{v(u!5%?9kli9m413w@Q)sHfNFatYa zQkd81g2_n4Unut*dof016^^6XG1e`TQSWyidm;{dkmWdWn1o}9K0&*%5*bfY7A9aH zqEB%w79tHTPP4}F7h=vZ@30KVQSdD3n2$Zkc#b_1-7poKa0TVh^Ed@#uo@>(_yTRl z5G=t#ZO3n-Gh5BqR4##shPagj}iIr=btNM2^3C{DIjxiYjT`-(v?d{lnga z_mPYu*EkLvQTRId#+Zd|NP~T+bvwL`)i{O1VPWPG#9}ET!^6xy=#FXFf~#oGvv7kE zk3*=*r-!|R!?-I0pR13rk&E{rHo|!Pf>QjQ`_ov43_LU64oeZqv(nYk9n)|YWqD=d z3A}|QWagEr+OY3@+<*c+^WPA|u?cy2$5Lmkz)4i)odvP5-)WGA_sZ5qFMNm{xQ;sf z6?{*`VF#`uhQIr1htXJx6xi>YAB)4V-_qV4Q?Uv5uc*rKPV&|miIqq}Ze9s{5RY*Iqx~)~`w7DF zNP_)dhT5>7v28y$coz(x7t|PIunNbJm%rL?h)GzF-29zZ7tBU7D)G*~SZqaj3694k zBq4W6@?s^TN-<`LM>2BVMY-sYh1ies(R`;l#$rEmmFAg!OviSlp?n$gU?dWdiUwuF zOh3%Vuc%Zm%)Evr_!UuiGp8^bKO?d{=N?1x6QU~c4l7K>0pyJdGY_FZ<{%k4D>4_* z8?$f$4Jz?%E0~1~C{{VlJcgn86v@b0h2zizYjFbktI~J$!z^sU6_l$+-!KBpaS&Om zvv$xKjBz{7cm2ya0Ss1GH)>pJCKHQ57A}}#}XVsOnv?i4+;1KbspxsRx<8-V_ zWiP}B*p54zF&_93yKvW|%rk66{^oqE3RdC>vOPw-&>7>f3P+Kn1!Z6?*5V}cKF+vc zCbl9K)mlgunT`9x;uLk z2H;!d>Jet{LuX9HYMemsp6pc^g99l4LYQfVSj@wA{D}s=*t;+lU*kCL=*{&9JunGt zkb>+l(r>(t{iysBn0XRIu?T4>{W5zKK0qSQ zpjdzUiRt(Td0z=LZ7~d=U^mJRpgz2YIP669tBg5j;xy_EWK6LiF|V-}Fc+85U=Y`J zOhyW-yiU8Y6-8r7$7CEvmBFN8D~b-`IIP7*)PI9 zj5UNAIEnnjIe!?7{fHSsUc})fYP`idLOf2R&PeLVT4Wo=JqAW#2htEdnzf9@*pHaE zIq%qtqGR}W2u#2iIE}LJP##tw4Hd?+kKC&ttE`GNhu;e9FZR6kfo7g!wp+Y76N%Z?aSd|{&Cw52u^I;vzLxPt6TFB?ScxQDL#eMgkLZc< zSdKkNMX`14ALxcLSc09ngaThP9_WCfSb!}!gIw#mj^GIl#$0@dlgR!J{YNVd!24K> zLkQo%ev3vJi={Y=sBdW}>ftF2#B?mjDP&A!eWNV~V-9}CRpi;oo`5IO7w=#xzQ8JCm+&?|#$H@N*6+C9;bC;ZtC)yyaR6bPX*V80Z_L6rq@lw1JchtHti>r5 z-a=js!~*QWpD6zWeZVk$hQr9Ym2-f;h{F#^L4j?w2R$$a-{5!T+0Iy?D<0Mk$(F0Sk2K$iVC)PNg z!5}QaZk$8W-IRyUcpcNR5eE_VGsmF``d}*7<0QiOF#pjU0}+R#u_B8vXPap;Aqh{rA*M~)=+1~kV&Ou$@h!9iR>iC<|eI$;bFkOZ@z zeH!)A3&RkPJvfWJ2Ut7kg7HYekGO(653+ZlDLP>kmf#!g#@{G)i1~v)n1;pJiN8?% zFzXq;F&PW60Vj}#oJZ&v?ng_!hS~TI2XF!TlDTg~2fT@S_!>L$8~#MrqdXo(8$6HK z@D7$@BlhAHuH&v0%0madiFx=QhY;}_*LXBQR}8~@NWc#`jek)17;_X);Z;n>mq@}X zWc!_Z&;VUA5(}^yCy?bhYZ1-R8{;t#8*mhnCz#J@i03gHi?9W!knJS<2%6(1Ou%Q@ zg+Gw@6!RKSpf4t21$N^yqE3gIBB+B77=n+m9!C&hJnudy4yBMpVlF~9I6df`pX!Wtyu5+cuYeMC9bL34D$2u#L8Y{o%cMEC{n4^Rem z&>USb5Th{@%aDjeNJZw0tOHa>bM!zgreQg@;TXdHU@f9Ln&Sn;Vj7lXBa-nC3SMHI z(GtB8i}#U$A8{Jjk>fIJ2{EXPW_TI{FcEX{HIi@{xvnrj&=Aie7UQrG-{K&yBJZC( zwm=g+kAWD4IIKV-e#UuZ{fqI%!{~_Kh{ZH4#+TTQbI5X)^M-PG2<`C#M&Lcf;VbOJ zAIOo)H3<#y3jCJ@0mvBcK_jY&$UGN5G;B)N2DP;VI zeF0VQ0NSB9VlfT#@i}(j6vD4@jY3sCf@kq6#$gV=z>oM1myz>2>krk@6kYKK-p2}T z!%4tGc({qi zeQ1v7Fc9MqhcB=lNAVZ3M}(VFxEIav90p<>;_w9$@e9r(A~M|MM+H2HHt2~rFcu$U z6}BN6e#P$DtM;MMu1h(fAO{@g4T#0y1U_ zH$_kmb`1NP!HBKZEdg18&?&u8;_w2`eGzLz%pz^63!u# z?*}Y|O1K{_@jPNN5%aMITX6(ekd^O@EP<+Mh^Ns9Z(#DO*BS(^uaJp!hEd479`;`Og{REGN_H_ z=!E_li5Xae4cLR@NJX~%v=fz3A1%=hgD@U(Sc%O@!davuTLI<@s-YoTq8kQbEM{RD zHeff7BMmtUavZ9lK3bz224W0mVhPq`7gBHqQH5Azh(SHHKxYiVXw1YCY`|_D$6v_C zXDOFJH8ey!yojNgg!%X!iTDZ0xPWjz+v5({&r7U~dUzD=&;$0?aH! zhW-4zYsk*0GZaHb)In3U!}Ayb`-wf1VL$(63GAnrY=!+Cj$^Q&P!V2&aYYGKMm;== z_ILq<@HVDn0aoH0?7$(M#Xrbal5s_O+=s?^65a3$MqnalV=2~Q8}{QAQjxh7`!LF) z78>CRbVYv*$0W?bGJK8gIDpgm8(HpRpG7&`i-u^0&ghGwco(zqDc0f#B;f@9LZ)c0 zpD2wQco;45Ec)OLjK@b z?h{Z96;TIG(GEQ@5Th^^^N@gVu?t6V9@mkhET0mJ7~GF$cp5$N8b)Ip=HqiD;%B7b zG9t@`n>;9ms(28Op(A=D7VlsN7GV{>!yf#GONh9e`HqsPf(OtX&)`M8hS8XY`S=`( z_!%kq1L5VFrznBSsE0?<5xo(McQ6(6kbrNo3rBGg5fx|$N}>uLLJK^D7cm&)@gd@| z23zn8j^iq#V!}-Ul)*h{fL7>?moW?zF&j&<4%=`LXON1_6`AKKi<)SJC(srBF&vXH z2g~p^w&MVf<4^mr#Nd83L0fdk zs~CwXn2QzIfSovubGU|_RhXx!h&pJB_ILq<@HS>(5mw`S?8EQ4f(%u;k3ex$LR~b& zljw$5Faqx(4lA$$J8>B2a1Gh3u`i=MYM~)oqci$o2*zRt7Gfn5u?vTB7HP;*o%4fe zR6`v!L<@98cMQN#jK_4$$1<$LX6!)6niMY`_j2 z#A&1=>K^tcM57uWL~}faZs?C;n1ES`$7&>E7Y^er(vYPl{X`kmKz+18NA$uVjK);V z#d5627VN_@TtfK0Tvt&HF{q8kcmiF}4?{5?GqD(}unD`7jPtmLY_%9CltWE4KudH& zPxQwyOu#I}V>LEo4^nUuJh(DBP!#1+3k}g4ozVwFFcveg5G#?0T{w)hNJEy|j1$VB z2I`{)I-(Z_VKk;W}WgJ_O+=#BvxfeDy}c&x@|?7~5uMk=BnqK_zrDyWAh zcnaOnA44%7GcX?s*nsUw!ZBQesm~lmQItbX)JJo)LpSupP>jb+EW}Ez$9C*PGR`9v zQ4h11q7*8kCLTazJdSpF4!!UShF}yX;X^FMXIPDIu^oGH7$Y_0oM>{-+UU&sVFbWg!KH~5R67Ur^;YaMl zQJltQTtlYD>^~@kQmB9$sEfvEg^qY0eefEF;T=rIhggWuuo~ZDD}KgdoWMo=gN%n1?0!0vqrHcH;n!;T--#L=(mlg%FL3sEG&A z7>}bJo&gN}F}eefEF;T=rIhnSD0ScPw}1wUawe#2S(3Dbgkg4`&AXjDW^ zJb=b{9PRKNdf^oe!6;0?`-sCQNWfRvgdedFM{p8Ux|2K<2CIDlg~hrbZkiv1aRP!y$63HPEtnxZv2pc`JoAPmP?Ov7v}!g73t zP1uPf9K~t;3DcVMhukQFGN_DNcnD3<1|87@{qQv66BP_&cSc{F=j=eaH6S#=K z5!r_MiTo&za;S>hco@ym7M;->1Mw!tVhUzq0hVJ860r??a0n;y2hxz?3DzBoAR3iX z3lE_Q+MpwzM?bud5qKBVF$eMZ0vqrH_TUhX;{s9<@g(yD`A`gHQ3dy*KANI6I-na~ z!XOOCSWLkzEW&cE!6y8OBpk(A{0Z|E&zB=VN+JgLpdK2b1=^xBUO;~g#z?%2>G&A& z_#Er;19sy8j^P|q5z&@@AsuV4s9VFKPq96mt;zQz{(g#Gvp zXYnUYJLVyBqX?o=5jF7;nxGXrq6hk6Fh*h`X5eGQ<8!RTci4enkc?Bfgny9nX|CHS zh>|Fe>ZpVNpat5ZGhRS{#9{=-Vlrl8F5;1ZwMfKP?8bhi;505F4Uz2`Q{+WaL?Z?@ zPzMdr46V@~UC;~t5sMKRi^-UYxrj#s)*=yGu^ao5g44K!G(>iwe&j__L?Z?@PzMdr z46V@~UC;~t5sMKRi^-UYxrj#s)*=yGu^ao5g44K!G(>i!e&j__L?Z?@PzMdr46V@~ zUC;~t5sMKRi^-UYxrj#s)*=yGu^ao5g44K!G(O zBNiht7Lzd(a}kdOtVJTWVmJ091*dTdX^8AZ{m6@=h(-)*pbi?K8Cs(~x}X>OBNiht z7Lzd(a}kdOtVJTWVmJ091*dTdX^4E5`jHn!5setsKpiwdGqgr~bU`olM=VBQEGABeA{sHMfjVe_W@wG}=z?D8k64VrSWL!D%tbsBuoj8f zirv_c6r9E-q#?2k^&>BeA{sHMfjVe_W@wG}=z?D8k64VrSWL!D%tbsBuoj8firv_c z6nOvf{EXrKLi{%aGVyy9GV^;@erDrm4ijl|lUl%JcstWNkI+>84tyB=jX;O8TR?RP#uipOC8Jx>1CcoOZ<0iEz1 zx}gVp;U)6-3O;dys^KNX9Xo#93U#6{O-C!owm>Mr1(_ zQY7F@ti!k1jBVJ3z1WW< zIEGU=kIP8Kbwq||Fqx49c~B5{q7=#^231iL_v1nQ2Tkx8TB9vG;yH9jZ}h{fh{c;2 ziFYsoQ!oP`VJ;S7307bgzQP84hppI&J@^%e@f%L!94_H1t|1~KgNZ_RBRP51#j z@H3Kd2q`!b5oyjuM40pZemR2oR7UXF1gXSdLwF?f6tBb z8mNs2(Gbnh5>KHcx}YceU;tt<45Kj~lQ9FcF(2_*j#XHPL~Owh?7@B{<2cUZ5>jC@ zWHcF(4Y^Se#So41sDhfPgZgNU=4g#}=!9)*%sFumgLrAIUh5v$%v*FrX$QvLQDLq8Or4 z9#v2ibxF$5zp1`{w9GZBY{Sb_ws#(HeRR_ww)97GCE;ykV( zEsFPNM)4dKKiLFLI3kfTbA-u^Y?(9M*oN=OoXHeKag;$t)WH3yk4Mk~Pog8bq8DDq zAiRmuco$RgA?D%}EXS8vkMFP@KVv_R;v_EMFI-2)ESXGpM zJ3Nc-cnJeA7$fiwCgFX|#sVzC=U9txu?0J^4~K9JXK)FBBRp#+{vJFN?_JAe3ZNKD zBL>w`8xNr|9>WvpfG&6e{qP!wVid+>3TEPCEXHS8g|D#*+prtIA{i%e9)IE*GGxnS zvLO!&qa@0qGHRkO8lWj!qAfb%dAx{M5R2g$gNc}qk1!vfA^~f#0pDW>_TnIZ!)g41 zRD@;EWTKE0`Ee(rQ32I(A09*_G)Eh>$8+e3z8Hu%FcRZ186O}Hi?9q|U>!DMD}F)} zj^H@X;R^miWR6TGD{`X{N}wz%;U3h%!)SuX@f4mxH}pn-ypCab8xt@MvoH_wSb^2} z2AlCC_TT_ga0(Z36((mUlLm0lV-E4&!&6#pRqlPm+_rP2gv0&It1lOfEia6B&^?7xzoKxNk&$6wVc8 zN})Wep*HHH30k5ZI-@80VGxF43?^X);;T}VPQPU0d`5uTU&ksF0k3guA^wNW2U&=T#? z89mVtgD?zZFbOjdhs9Wq)!2Y7*o7n{<0LL372)})AGuK&rBEK#P#g8p1TE1HozWBh zFbKmi29q!YaafGySd9(Xf?Y^LGEU+mQW2h?`jH!jQ3~Zz4Yg4pP0$kU&>20^4}&la zV=xIb5QoM2Bh07y`P-rVJa?Zz(j;IN)?z&p^Jg&MV>^B#&(HZYn}hfr=W!L`1u~ng z$csBs29;3@51|QKp*_0dMZAikcpH=O0p{XUti;#YjGairQJltQTtlXUnN2PfLMc>0 z4b(+LJcg(6EPCQ)#NsWC$282wA}q%mBw`!(;1G`E0#XrCD6`3id?<#psDk@YA5GC3 z9ncLgVIbbb7`%s>n1?0!0_*WTcHvi~;0&(dI-&|^Hg}*f?m`UiK|M4=3$#UNyny}~ zjFEU3(=i8&u>xzc5!51q-do1t!PGbs%Tbo1z~q)HQ7)ArBD&I@GzRA?VZ`=q5qAa#d$uY1iuyK zXC#X9dvTQD_i{JG+4z~AxUAslF!F>E$Iq~^Qn*{imm-aDSOsL{ILWW$bCdrL(#r6Y zN1x_yez&UfyM4~e{>~$(8*Q>b?Q>eTEO~CLGQZp7Y?}*GMhSl2McDpsf7*82=d5z# zPU5_64Wn&gw9VF~`{2Y=Km7_1_BlQIz3k23^YhcD*?4wdeh)X%v{~|%CapAaxgq6bGnic_meTUNQ63C-uv@wa44vr49)fyIF>WZ5wSJ z5|%ood?`=Q6`S9t>p16lr~P&gNqcPhHf+=7cYpsSUD_sLX`6(lZ8j|JlQMPvcHZjx z-FfV^Pr_24grz$71gU#|`OyOe3$BWW^TI!=z)>q&ms`6W)*Z`Yh0FYC@J zo9|2{&Gy5FZCi9$e%IwooZY|dzG?SC)++nw zIQz7eCwqsKXU~y8&bHSdCt-iR67RIx-LGXF^}NbMzihm;#fGKN&Kz~ZGG01Pm*Kt<*uBrK*S%gjSc{(s43QI!@-VjdT0!)}hzEZLj3h@osr;JM_G__1ZkLW^{WcPPbR$bbBRE zx7Wr=n{^#BRx*F2eKxG?v1289bl-HmJyyz-c_HOV*nh0V+kCox_B`tHa=4c_XjpCSLum8GAWa!n!T?{7SsdC*?VH*lU#AJ{eOfPoE=+)8|Oy<&oAXW zeRk%oE?>_nxBcF^De?X}EAdiBsP;&jv|sw=e|+PtE${r4`zD)LkEf2;=TgV(bLre` z$@+EYr;QIaKPA6Tv+Z~CJLTx}W#i@ihH9temGP1C%+9P8r_dRlqZKprY9wYNauDLQs&X~FP!nz!Pnk`4h z!L3*JZD;Rs??K$_h_px2bU6}duh&jHopR*fNViAIku-0=f{#V*JaNX_x$m|4WsXQ0 zx_p0{F5k`vIY!FSasG02n$0icCS^!}o%0oZJS=_9!;$V-+jpV5=U1o6`IR`CzqU{Q zINMffk3Y>HFZ-Nsk9*F7?U6KHj>OqM>vG(&2$myh-hR2~!0ng!9P4-~BiLWJ99_OX zXHt%i^OvL3bbsA?b$^{XXv?V1=-d46Sm?*tvah<2&1`pfA&>pfA&OBtcsBWX6jGoH>m3f&&(I%V_9 zeyi`_{PB8>b$&g@I$o}iQjR+xy!FaC_m`vRgH4lioh4x z%Gc*s`XzBP_BLMnC23NQ#5?sm&kfo9QocS{QoesKNW6b8NW7F0sy&h>?U8ZTd#6p) z<1A@5UfOBnbl;pYbK|6L>90S(j@M%$?Q!?Q;65N}(oS2q#M!;mX=m{IDEXxh*?+wK za`!wNFLS{eYj^*Vcqt>;UvD`wZg$M%7%5-J`ODF1(tcaFl;Q7h9?px*Y5RPMK97>- zJdYCGKjnECn@_J9f4skZ+a5W_ruoa4d7{gaINM(vFZ02cBWeD4nJ518Wlrnz^_tP~ zdd=u~DI-*SB+ce`#?!lh+IX2$vQ~6C{xm1Q+|PUa>&z=RPM70PllDlwcYK2PnUY`H zBWp(DZ8;KW=atjW;5w50QjW|;C%^Q|o#!^*X`}ZZM8``R!Tx&73AK)-9KBZj<>)k< zU*?-zuRQPSKEEN)CF=Vz{XC(qL$5ELCgtlmTaKPT?sJ6Rc=tIs_rA!^D>vR>ubU?0 zBm1o!BXh(V2j_JoX@96RxBYI}dK~OLk+P*6nGZTm%F%JQ9Q)cX@18d?{ET7V#qioO zKf`QX6lL3=_IX43Y4b^%#OG)H^>c?dx3od_I@>n=_(bnh70K^B=CH>F_e1Bnj3MtS zZJHf7DNpW$beW;jr9Pb|`>9i(+YZ?Wb(y-IlI|~4;zRXa_OkTKlys*py6@iSX598? zV9&_NTyUS?&}kB{>kF0cuTSsOHcgJv@uAAp>HcwX+v1-SPTQrt>dZf9F3GuY`)1Q} z(O;)M-sg>MnvS>QV$ZE@hd<3Z=g$0-`t-5-I9;F2Gk=*9@9%?@Dd}>Y?VqIS`RDJS z+^@@Va!jEc=iK}Jr=&UaA#|FQmtH$1UFy?oI{kKf>yqbH^RT9EJM~!VH2?Y0X--}4 z`O#@5LzL-`XRs}@WO1hNk_T77J zkiAakr~f#ayAmIIT!LjveRiJ7vCrj8F)rcRgRWUQsUP~#%68AzG-akd_7Nw;O% zG-;=P-bB)DJ0)JPU3u&-X?m}a`t-4~ANcFjYfzUd@%}zYnUXH;lyQ;1$+-CI(`!lB z=U=-z&A)banv|DbJ0)GWQ||fn9^_ojBfxM`u<;-))&aPI454$84M&8~HSyo{;a2k&EaX{Q`3<;h%=F|%{fO$)YD zr|U9xyp*ZOED!D0=Sk|5cz5pGcc#i+8-8{n#nbncMPwp3}ed(!Kq2>#}{&?eva!aLjbNE>p(`$3@!c zJXh=1=e{;$=UH_|(>pG1x=nM(#ryoDO>_F~jn`#{N|*X{nygKyJ~@Bxde&v?e#kuY zmnrdfO#EfK`%mb;OS*HMJRY-sboWV{=CWYG z-1%ak8jL1eJ|xt)Av&TG$}8=c1pS&=d4ZVTBX;C z(@y97*nKY4c*Hab$K2(|R zoDN;4q)VA@-@WVEw$q+l|KlS$PST{j(Bl#;Q|j}tOQ}!ChbmL2OIu{D-L|-MSI-xH zjkd?iID7AjoN;rGllkQCz4kb%&wHFxr>@U^og$c~uhHJN=<8yrwz%oeaiQ;}Y?^b9 zyw`3SQ@0P^bZ`IMx@4}&nAth#_956#ovzE&@lvK9vpmc@S=aV85UJ0`yK9Nh*SUEf zLZv&$>1&nKM_aB`0mGjuy8-Cw4}+i|gJx^M2>4qc|CJICq1 zyKB&lw^?8pA)~DCB92e^Gk+&`0wc;Kp`-_|I92a^`+qCr7w3Hbt-Jj;JTkkyc zuFc?>>2zJDj+eQs*R=QbMepMkJKp*=I{*1`)4Y!Zvv#91(CO~_bkg;HpdTkxq+f3Nx_$0`V$*Yx&uyP~pR(!crRnn1%Omyc^xL&x z?@PLT-AA3rU%pNYJ-+U}sy((k=ie>ceLNv`+jQ^wb@RB#%lLU8cSyR^cW;`%{7`x1 zcw4_tcjlgR?)~le&&^Qnmpq}$moynWfBEwGz~6p7hLT6hcjuQK1N*wLvwkGq?Hiw! zM_+H3E@}Sybs3UJ%GdSl$3~Ja$Lh57%GY`1czu4P?$G1s-8bym+SjMN^UFInHr;Li z?O(gJV{6CH&JSsuy#A$M_tbrp`kgTdUB0g0_CLMyCGB?QOCH@mcl>00+_~-Vf2h}4 z-L~7gbG!E4K3$HzUHc`Ezx}d*``4z^e!0Jp{yF<{sPk|4Z~yqp_{(EMf4c3zPD`)- zI*-5oQpWAt@9quhw_oyvDqqs{+R)?UuATJDmpr(@l5hfVX{a9%-M9zszqbL(*k#JL4^R9DBhM4b zagydQ-;SR@kCZRtC+T{A`rGgB5zhGu)qcqns(eY4@$;AOuA%hHmpoFw%rB??-aWuO zKEXZ4pDtymKYqdTb^ZQ5LYJ@8(kox*k^brP(f2ny+%tJ(momgQ2UFFzdtS1`1|un`ELJp`-1KF z?hm2ISLgAUuhY^SUwJ&Q*Qg#}dyd@aGn_WM1(K@yW{75jzQ9$vGJzK*h%@J^2qV-{MPLY-G1ADXYX*vPRiGPlsuuzmoynW|MmJfR=lbB(A$yGTx`@6$d#`bl?yPZd znjJ$)*Y)c;8Y*31KWw_UeR>Y?T^Xe7@sn$ul;IpN_YcAApG|k$9=!fZ`RU~el`eHl z|8@Jlb1ZcGbsm5DI!(&g=ifg+<#-u?|NOM+(!Nmh(>*@){FLssPnY(~ z>tMEz_8HtP>>=fEyrvb#Z(+pRSHYrgy_OZjw{F?6yapvTRBLV*SPFmY);x|Ke1ZIGt_!=?#KOkymQ*- zaj$8?Ia`rB+;Y;N+ma`}xoh`e$)nrsonxW$==&5Wz50#&ENP4XUdU;$&Et$u=zO*< zlE-PYzZ|zN?>Kw+EM1P9cNpYdv76QEbU1zpIc7U&3(iv=igpu(dquW z+`fD7m!vM+cb(_o`lat_{B`Mm>3pH;(&;jH-0^Yt2m3mRTsx!;=Q(IO=k9ADx-B-3 zcW$`(yyZyWo%DZuJx0<))#Z#~`sKLe?6yVs+utucK2G1=`5vlYl27+b*CpwHfO(ILrN# z|9p7!1h4IO9ZH+!yu0^|Zo8dwoPE=uPulH{Pw?JV=aK7RsB3$04|lG+x?j%o1hR+w zuggxGoyVH?-X?TD+aAf|tY?2Y&h=gLNSp0*GX8lVDv!)VIcGMHw=KczyIYQKvzt%a zEOTC7qj2^YXDvz|w@=>dw#<8}E4_SDj+|4e>)-n2ov-Pi3!N`iT{>Nlp?5z2`?;`l z)t%4oIhAwapUeL7NiUzj&B1cqx^$aE&3QQ&GRI^s>&ND{K3z^8LZR|`^Y|YF%VYf8 z-}5`q6UZD4eb4Vame=bmm{0OJb1ax{&#UB-zUN_`_{S)i$Ga!k^x*n(_8_?yN*-r? zq;K9euk*O;LYJeT$I)Zxork&{w_o0Se#s;AE4aR*Zj6mPH*}lbJ;5zU?xSpvrp1^2oUewch=CLiOF|vETWWg`duMKJndc#5m85*v}Qp#B(rw zcO2>R9E-&1=UIp&2j6RV>pmfL|DF9;=kx9za@}z5U;O#p^{VsT?mAwPHrYDe^3q?I zI$wHgSJ&(9uid*sx6hkTKkjtz3xkj0oV~?ae{LU~`*}Mq(vRCc*5y0+xM!F5G1~hZ z*~g`?Zh5jV>V4YVK7T*l$6DTe-nO}q{q(tT>(%{m^Xm5H;vBmD`0pOO>c_XC>iuuZ zv;Eci{+s^l$Ecy|)nlXc>i+6_bsjzU-0^eHo9s3Jc7DB&xk8^e|8?(n{qW}v)enE3 z+w~*8HI!a|-Tl|?i+7%e-d~*S!oTk?HlKUWg7*Y6Hg0(`pM!br*hoHSUIp{W*hoHi zKMlRV`18p;@Q;f>UwYRk=UV6=7w?|nUZ4H>y!)Tz`?v9ve9n1GfBba5+l`;jcf0Wm zl`quzh02%S_&L|pNUo>)yV$a@Tf47G*lT5si3+o?fc)Fo$a?bT_3rsH2kkY^Stq(& zo7de}{dsSEzh?( z`JJ`lmYZH)cOGQryrn-5{&C|aB=;XLblKOs{wM!;4!Qk*|3?M>uQJmGU(0RG|H1#? z8eV6_{%(tf_Yx+msW`e=FvHchs%JL;iC6GIgr+JO6e5AF{On zCQ_FfGXJd%H!89-_W#H~>AKS{`(O1hjJrnr&9Bbi_C|5t$-=iRXX6{ZbMWqjTs%Sv z{l7bTJi5hvZ%XprVt4WV&!u_nSC;R3zMJ=4RN(%jBHyW9nd^I1zKgax_YL=$n&w_p z%iL#boBK^2Q`gip510qdL#DoY*fcQzF%3;4)7U&>nwX}hnR(PSH;0|nu ze&%J<-@IZ5{6F@t1U`x)>sL)r5;D_0o$d}QA|fKNiYTu4g+>U+0&RkrLckjY6%i0o5e0QYK)zS?W+rc@rzf2uGloq~|EA{E zt5>gHy?Xucs+#E@Hl592GufZmS?p|f4m+2f$IfRLunXBm>|%BayOdqV{>(0CSFkJD zRqSeZ4ZD_I$F668VYAo`>_&DIyP5r!-NOFHZe_Qz+u0p#HoKGE#qMVJuzT5k?0)tD z`#XD(J;dg)huI_SQT7=72YZ}7!JcGKv8UNT*)!}}_8fbjy};v{8`-m-OOW4P3DO<)qVV|Zxn!U%@u&>x!_BH#4eaqId@7Q|wJ^O)eU>n(w>?e6_Vw>47Yzy1Uwy|H? zc8RP3uJItx!`0l(d--EZ~d-C>t zFW!Og%{%gacqiVOcj3R|`||yGSH3^*#t+~J^6vZ~{(F8fKZGC3595dPBlwa0D1J0Q zh9Ap&@Z3jyC$^XR9;%D=7___Q%em=i|U&t@w7xPQ_rTjAfXMQ=qf?vt6;#c!)__h2xem(yS zpT%$BH}aeK&HS(Y7XCMWE5D83&hOx}`JMbOemB2|-^=gg_wxt%-}!_5AwGvc%pc*8 z^2hi;_~ZNu{v>~jKh6IMT4wR*`1AY){xAL_|2Kb$zsz6Z|KW4_t9%}Rjla&{;BWG` z_H4ARN#G1R~fc5;9t5S|A;fuTtd!#Zp7cP(IqTi{$SvQ_8{CJCjnRX^L&_DrK-0nqnzUu@vpcTDuYbXd&7|twK5? zB`F_m#_zMxa^#4+Y8gY?Px?ETJlckJ-5&7LiI#YkBA;qbFX>e(en%VY9i>s8jt=b? z^^cb%m3OzE-g4CMmZ9F;S6aTOOp%WqYBSPphzu>I@|31B7$?ZV=%OtmzfkJ$>S_f? z5M?OsmZTP9yx~}2T}o4J$VY8dzgr$Tl;2)ji>cclY$bh4wIL1v=L#?M26_qk)MK<3 z)lcQA9@N%bYDWHElExG{SeI&`HlS~@U7DhN7paZ%+qyW|I+elLc5{$VQDQd>Ha2)rQBZ87% zDIIa7Q4h+~5kU^d4=tsdX^ZZ=*1K{-J}f0a0f|aily$9M!UPzKL^|OlE;3fPtmt1gMFkN zN>e?QkEn~K$fu>W7J7_wXf14=a=i4oHBb((a5NoCBrKUNS{Krf7*fb(doAP!dZi2koI8FP&6|TH>Fk z*GJSwb-LSib5I^zq$84+qy2JQh<)5g*2NU{ARlSe zgEaPtawy*|@5MnrrszHN2|f2Ijh3TT*dyv&(zGvF7t=m2G@zw4dTHxO(~-jdqP$xJ?GZ}Sy0jO_cehLZK+gr7Ct!+o z(F53Dnj#=Dv9j>w@Nz*>}#9Mnnu zgEaaOX{v`xq6W%w)9$*|61Th;hw7oUm%N*gvEk+;hsGh5)TD=LbRkXqjx_BTTG+HH z>c`e;?4@soT1D-2^JyPxTeQCzT?b2_WG}_mv5(j~w%dzDJMyvbRFc-Ey+As%)UBWT z3jIK3kftfxNo!Gg%10XKE$&))j(gQbKJ7KNAu}3VbkF*{v{6LDzMv%XDaWmW%3v>0 zhW5xy1Feg-4w2E4?X(k#Nu;rL^cbepX3C*57~v?1qVYDO8V6Zu`FB{bbba;Rsp z6gfy!duZMCG}b~rNTWQp4NGZTREE|<+MS~PZa(TkKDB|iNNL1yDo;xrOMB_TR#2PU z=FB*#6VpC&G-)f;a`Xx1xGll>bjzgYxLZU$?j9lEUFvSvEt9@?Xaly0bq|%^*zuI= z#8zlZ^Q&ko)E+mVw(g~k%J`w(_D~zJG`%H3={WGs*TDt6;1V{ zpK0oDg>tB!$oDFxlC(vnalELEe{Iy---r>uuolW2vM)3}IxPonKzXG55_#m%vluzFb^oPQ(n|yKsXggiM4ed6O(O?A zfHKspNK>n@E!raGP)T=P+9Rx$UY@o>?Z;Zk!8;Bjazrr2TG%?K?oyPYe2fsvam&zB zq-m6*50Q^`sU?(lw}qpL8e~^I6H}I;Hk79{mSSb((-irAi3ao!Z5J&;Nq6clrG25^ zKtH(cK^a;L#}VbRMWoSAdB&D&Zv~^nQMboy@%TW7K(rp!9p{O3z zkCJF1rpR}vDCy=?4(g}gMx8i<)HbBCE^5YFcxGWr>tZRDM4gz@7I9=z(jBGLLaGfV zQ4fwgwvO^No@rYsgB+x(9@-Ytl!LV>pO*UJ(-_9qDF-#U`$AixHn{tRlBgN=P#Mah zG_{=Sr~LFZYD+IeOR*K~J8cp5(9~TEIat>%i5%34en5HTU@472T1qXU?YhT^minjt z>!Fg^3$%^$kxrjte^G{Npngbi|8DY>LmTjVO6@_NR5PBTRED-r<&j29Fm;zAho1Fb zGUtB-A@}f~2)#>J7T`xW@rLE9d8X`l1meLj} zA8EHd@~QVQy4-b}ibHKkZ>`%lKk`(+m(8@lR37zH4r=h?ARkk#>()$VyzJQ#KDLV~ zq7$Z6Czeud!BRImq5X(aNT*LJ2GUgtwaQJSPPaVTgDKWRN#wZYQHCNawH8a=7P{?0 z4Je78p|#wWxHY8bpj9E+4b+VCl*Ur(d6c2v@M?v6$x9yFqAj8%)}@-M1}g8?;I@#; z(7IH=o2E82Rs)U~>ZE#*gQdv#V-HHY_2B5ZEzbsr+Ud50_LPnkl|&85!8=l^oyd3h z2swWERK`tHJ+zeCKxL5cmZUOXrL?YFzOfu?VS3H(Qp%w;wVcu@oC%t~JT3&oVHn?Tn954NDK0dj{ zO9S%VPj^W#kFB6*aQE2VF1_ZuOQ{C0Qa9hrDz~H;$Bzd0h`Vc{jGK=fcd1(^T8K#N z_CJ;)->WXlxNUIr-7;QwVqJHOltZ=o*W<25+oGlJwkU_zqO_L=DuXmlsb)%h^^3|- z&9rql-%A^nq*ftKuh+<-tsqTPw+1RtOWn1+Bxx-#dPnNIb-J~=IXDW)rzzD&N6M|i z&B3}}+T8M99RC_QMH6R~bL`kGErTVEhs=+OTrO3w=TcP~){q<^#YCzg6b@$g#i&UFe zzo-qg6)*iL?=?DJt++K)J?;phR{7V7l62hNb={V`WoYYE8?_l}Dv5e%Uyy@+r}DHG zrK!)UofK!N9=C0@6lto5mLea~!;K**>E#)!Cw(8Oq<`A0T`zum&9oNMl;gjyThhNC zcU`YBrIJ)XwcI^kc!k2cwA3AYsHY!oCWo|FH0H(xw?8v$m+EP(h8?Nf*tV4X&gcOZ zAv@!!{qNbFJ`TM~z4$w$fBu*HvNQTWH#YC=qwJnjxjDJ%l{9D^plDV`weOq3oUi_x=0M(P5wsO-7?Ux^#T19DhU3V$vAdNWh=2LC76#2-Z zsaxJ%O7&2h)^+Q5mwIuiPD;D4WwbQCHY$lU<#^RazJE!#9(P@L>u!!)kDEg^Q<_S; zJ(m6o<+j92Gi}9>49feL^e>M+O0PM6Dea4!_FtDuB278&9=S{Dc+rt^_t8r~wco9u zmQs2s&A4bRrM97nfBjV6tCm|ot>rSR0ftvA>2=atNK+22OZn+(w;n(84Rp_=*sYni z?k=Tj{Fl;NJ5JMf{cD52q-PonvOJd03Ro-nZ<4&|JHkx(pC*gh%wff>HQR;l%64OI z;D3JFvOQQkwkK=P_F^5_-tf%teOM>fnRQ{mWBaoGSXZ`x^ytnGV!vkx!*M7(j2$j1 zk!$D}z`Tx8%b2UH-x*AGmvOmG6kU3X!1chZ@)Reef zGBpuOCP}SA!~H-D&O^~pQ8tl1F4Ibx3cDsk+bAc}mkC`Rr$x;L@LmM(`kEg>ZV9}F z+!XdH`;0ATpR*P03$~K2VyoGgYz_O0tz}u4 zt*-TP`}>2ofn3<`)r(X4m+W*d`Y-yt0(xD+zh>#I5H(`{Ig9VZ*QT{4Ci#Ugss8+4 zz7i}DqwpYqh*$7ap$GfO)T;;e*7WCd!M1sPAoL(s(~md%^O$Z?>oaI?xle0jQ6uWD zf_nY=YIZ85BELrFzk>8E@DX}djK?~lzmsLLsH)(f%X};XD?p3T74vijcv<8{L>>}2 zG*BUZBCPHY-1_4?$P1mqbDu%%ihk?^y8ZazR4!TH@N?k5flYzUfnNe! z0$T&y0>1{f1N3t(plMoA%hU3;0B&8siE2wDOUq^>a=OvbZv$<6Lb%WzR%On zhhsXF4bd)v@)?j0fMW*m20(rYl+?+bs4)%b#8Rv&k;2g~g&eI$yc|+SJxGUt_ zKuO!+9>I3O=~{buKcMX$>%|qk}JN#|C=@--bSx1RsEw9??pJy@P#%eS`gie+c#u4hSxWv3~=kr-Lu%f!v7T zx7x_y$-z;<`C#`W(3jJLWnd51eibw?fcMKF|1SP4GwP{U&JreenKL@bwz-?K_yYW!4_?R%ZUlQo%xwotrpa+z4kNW0#%4NLH3Le2 zkbcaEmUysza24>v!FRyt?Sji-Y=x~Wz*b@Dm$EkwShx<_)`Opb=AU6azJ;FVfrX2; zU4s_%c{NzH0qoPj-|xpQ3k5#}%jU@*%#(ds3-v^Fb^)Jk&<+4Pm?!)w#-w+!BpA*c z5ZpJ|Ex32El#EG77}d_fgM;0JN6UH|L`q)p2Z(}IFis9w)h75e^zS|B7l#7C zkcdn@xC`jmB&|*K>3ZU!1==3qy_wOzZ--G?4E;JD`cMbHeFH{$p8T8vpTg?-Fcyae zyFyI84W8;B92pz|v34@FRGrr~cx>F(9&u}X2ZgnZrM-nRN(Kal&B=Z4nAD3eb!vct# zgJA@mpoqCP!NJgfVdK8R_u+g?92F5UCE!^xHcO>%50GP22jjU1jOZrtTt4_?h&C!H z>>3I2*##nG9h_5};avR@B5XcbvL0-h2T?vB?0*#^9wU1QjIS8!-qL%kAo4fLGwfwK z(p|x8Z_Bt{2Ni(Bf5`A6*BXgLvq6Eg{TZobca9+2OqbPcQ0Gw^@L3iqSi$&Y8 zd|}x9c(0r;P2ec%iz1kHFJ6oU6Tc<(TXqY&8r4tS=kJi7(r^n-E0vqGSrI6F2) zk!D34Yt{pjECHkt5tR?4wF>Zc0gUS>`5PhrV&}*;`6GkZ}aj7%qWBAW(P6bp_r$=)=))?zRE$;{~GMZY+(( z_N@GT7}0hh_gXITs+{Js#-h=bPj{t}})0!CGbc-jbOl!)6t@)~@6tG;ly42Em*2(VRL`#*yb z-4{H$H^^@Xiv`k_!kCYQC>;==A9RE(<^s4ncZ0eogGb(gsO$}6*%l(mk@+@&qZo|` z!)Psre&9L$3AB9}ToLnvA4Bwnf`t&**cZ_cfsb|Ii`C$LdNn}X`h)ky^*EdthL{rP z^Q`>OCGLsQ93p2L;>`XE&bXO?BtOb)-h4SS-QoK5Dp=VC@Nxr;$wIj9mIQ-&8{vwq z1&@c=73YzcCq*CIz?roN_(QbR9r|=M^h%&9;`DroxizicfIh$Ksii*VX628BGiy7X zUt(U>7UHfH`nwT4lMkLh8qVsj;9D_LAA)60VV~eS@Ys651iX@oky;A<5FU94?9Z21 zz1|T01K$Zk^QcdxR|MiM22{gqhnT}|mgn?xkoyKu z=L?9juK=^QOHYcKM;&-sc&<12VE}k64CmOad=B<>gxJ)fz5WmdtEHAbf>R0+r+)#< z-_WKP_5(j|(xwzT5KnDj3}*qNiMibtur&;p3A~?Dcr--S42a1(h^+w-X*lnrbCk6( z`cn$U@eOEu58lh*E&MwwXo4p{1H{b(KePj>5nwBav-C^tnZk|Wi&Y@`2N=sApl4GG zcLg6?;MFOG#|B?7e7*2Zc+ZE!gq-;70ezhh7JXPaEC2Pv_CODS_a}wDA)R0NdEvhD z(}6yBff`*Q_j=(jFdnZL3g3&|JZ)p)9>Jf0>JB&{<_=p5w}K~rE$ka)As%`|V#Z+* zQDWxZ5o(4*!jkTA4itsxS%7o%j={E}!-DNXdxlO9?iK0~+B-A~^mYn$4vBNPT}XIg zu+}YfKt==e}c=!8&DdGrqT3H62i$-xss z146w)ThAz`k1Q8uCBPTC6X5d%nU+hL-m+wTXt35NbcU2Z0r=HYsxPFqpc!RE8+}4& z!y7e~gf0Y*u%SfO1B{Gn?h^vcfihv;4e{DNLw}3b6gJ!mdU}TL3EdmIFUl3Q=SY1* zzo=ht_cJmt^p$|u`hZm5(652E+T75qp&tT!YTE*Dgf<1<3hf8c*k2PX;NNLK1=?w1 z<^Ex4e{FFn04r~?g72UeXnET5(C49`)=FC$+8$UP`ZDxAEalgRN;Dl-=_kN?{&-l; zcY^hNPi=QCto@cH2j!f$97g)a`z(=H8P7XEYi^6(YmE5lcXuMS@mzBYUv9M=GSL-YBmhjf_Hu&5gW;)kRkPGTD z$wEo#x}od3sTb*iu&q0KvEEwWMc-B5O}F*k^|p{|;XU>C`d)empvBQi@2q#xf2VKM zbiJ#-zurwhKtE9Lt{((42kVFEhw6vvhXZZvN9jk)8a?#m^yBps$!iZNu@_L{u%n-X z9xPk_Q5&w00RBi>+FE}Hdg%mDhcX-9i=fx7!P;^9czuFi5;VgT^-20BcD->m;tzeWF>eye_)emn4H>v!sR>38d9_+I@!{eJxc z{qOpN`a}90{bBtP{Zaif{U7?4&=dNT`cwMT`akt&^k?#^ndAi?!BzPqW?#q ztG}wx(_hnH*Wb|J)ZfzQ>u>7|^o9B&{T=;X{XPAC{R90&kXfuR(LdIg>dW*`^iTEA z^yT{J`U>E$)K}@N^)K}``d5(q8tncSKEH!^{qYmf|AqHv{TF?UzE$6*|Eh1-&kg^g z1q{sy8hJ*(QD8i*6&i~}TMKo_M-0;_GAzS39HSWW4`@MSH=~WQJ4o+gv@`ZJ+8cWr z9gMw=j>bMlC!@2`#rU1Eud$!e)!5(YW*lG~XmmFYGJbCyY#d@7Y8+-9ZX978X&hx7 zZ5(49YxFRVGmbY(j1!EW#;9Pa(c9=_^fme!e=zzR1B`*jiJ)z;F~k^Z3^RrsBaD-b zk;ci!DC7T(Q;buM(~Q%NGUJa%xiQ)p1DYy~amILKf>CLlVN5h88Iz4FquQ8aoM}uo zYK&UQPcx<)Gr)pB8D|-18|N738s{138y6TC8W$NC8y5t{vy2;z8;zTcn~lF3w-|qe^4pBtjXR9l#+}Ap#@&#=*SHVT2aLZ%`j9aP zQgJ*6H6M@CPaFR{|UNHV;ylDK}c*%I#c*XdSF}?6rL&Ws!#v8_)hKT34 zjRnR+V-dW^hZaH_JC+z5wWY?7+9D`hWGpv6hms}6QlJ(XUqZSNK1E)X-WwA6g}_|` zsgPM@Y%=Z(Eitx0?nmucDa|8+$kxJOBrk#*7aF0+5|9+~X5^mGkDAb394*}~ve4K) zvcT9Q(hfMHr4Eo2mI|pZ5z(^X?jPwEIUp*r#5g!|2(+@?I2p9x5#jKH*_ooNnyzuvfcutO6El0&kZj(0+5>?nGu;8 z`BUVq$k{-h8#xbh7euy)E{a?nxg>IFVxh3+q$gPpvBDY8Gh|G@M8M!NRcjTVPy^;GO_e0&kM;?qk6qy5cABj8~c`Wh| zsP{zVNvQWUyq}3Y8+k7BeB_15zalS2{tfb%M_z$8u8F)FnFo@ugUmINw<7Z+Z$}nH z7Dg6D-if>$c@IiHh#jQkk+De`mVzmZLm&5>UsTOwN{+akY4w!>Gv+zgno zXfQ92i!0yV=&cs8`x1tiWlF96O(z`4Y{)VvI2W=5_6&Q;J>7xP;4I-vgo)HRVCfx6lJ zE6{&4Z#8d&+#Tj@^G?tq^xO;i`^^WSbVlSMa}MNYMp#(Xd)#~ia!;90oBuSQF|UX` z2NEv;e`e(0=1b>P<~);!UpL<{-!$Jc=bLYv3(SS)BJ&;dUGqKA|AG0T z`H{KUTw;D~E;W~#pO~MTpP9=+&kFMkbEUb;Ty1^{npcATUz^`Ri|fqCBJ0iX%^%DS z=0@{J^C!^qUvrbW+5E-a0`xZXSMbdYh@(J}R&-4yuPDE$pr}<*VNs|kT%;EnMUf&C zI9AbY-6<+AY7NJ(MY|QXDcZeg9L#JUmvfW7iq-&bO$+Z+G&kJ2=!G!W?h5t0MQe+? zqTW75o#VPuZ;v8TRw7HshiG|W(EzA@BD5_ehDwQ;j(v!hdqRJd77D2fDK!DC7n&v& zO$NDY*_Uup4cJqcWRIA!?^AR>vFg&I%RuJxxJJ>UUUa?GcLQlPk|1#xXrQ(~2s-8@ zNMPyiQNN15cb5H%^{B9Dt}J`4=yhlheG~IqXIb(-a6c^isAzG~lA@1`mKH687C(j0 z<)CRr(HCIbDv(%Ov_`i3wXCxabS*9VzUYUd4MiJ^euVNK;A=6Szd-9-i?)H!wu1z> z0#@syptV%`ua$K@@WPgE?GB%d!bQNht*^q%A-9XQtF@c;bQI^HU=MuvM@B}JvyK2UBI z^|QF%-x^>Iv`(}JS%a-1)=+DhHQX9uon(!)PPRr_|7V?IoobzCoosISF>vro7 zYqoW#b(eLwb&qu~*oQVgXgy@ju^zS_u^zP^v;JW{ZarZ=X*~tH{%Jh}TA#C?w_dRR zWxZ(q+j_}**?PtLk2TkN)tYC$X1#8`0TORn^R2h71=d1qk@b%CuJxYvepL5jYl-!- zwbWW>ePVrTeP%7UKDSm_Usx-xRn}_jOQ`#mwbuID`o{X!T4#M{t+&3ney}!J8?7I$ zpRAv)|5}@@&DJm07Hg}u&HB~a4nOYUcECo<^X&q=m0f6uY?$)fh8?j@8wTIDZO1OQ zTid(X71nNc8+&)Vt-Xic&fe2*Z|`Myu=ln*+WXj@?9O%<`*-%f_I`F(dw;u|eSm$S z-94)N5c^R3F#B-(2>VF;DEnyp82ebehkcxVyj^0SVE43p*`=VpkKNbqXaB+OZx65s z+9%qB?7{XBd#F9k9&V4YPqIhaC)=a!|FciAPqk08Pmk&zZI7|X+73eSv+UeUW{!eTjXkeVP4d z`*QmV`%3#N`)d0d`&#=t`+EB?_AL7b`$qdF`)2#E_AU0`>|5>I?Az@-?Ai96_FeYf z_C5B!_I>vK_5=3c?Fa3L>^b(s_9OPA_G9)x?8ogV>?iG~?5FL2+Rxa}+Rxd~+b`Jv zvR}0SZNFr{Y`XY&-Q=qP4;H{7ki7n)!t_RYHx?1c5x@*z&4qa0h;yiOm~*&ugma{GlyfxHI@amo9OoSGltAsCPA{j_ z>FxA!`a1obKRErJ3TvQqqBF=D>+I>Vgd&IsouXQXqoGs>B0o#LG8oaUVFlsVr* zl#h1CI9sg>XPh(Mnc!49XE+m`NzP=a%BgmyIA=Ojof@assdJ_|)14X4Oy^HPo$Z_h z7MuqbT;N>jT;yB~y&hp*2ED!9xx%^9xyrfPxyHHHxz4%X`HM5lxdF;=a&88%+~WMr zxz)MNx!t+LneE)^+~wTu+ynLQbM6PL|L#2KJmk!A9(Epa9(5jb{^30CJOMp>%6Z!P zr}K>Stn-}nyz_$dFXu()-_A?U%TVV(&Rpo{Jm)p&>l@J5x19OT+s*=Kp|i+&$9dOz z&w1bZ!1>Vm$XV{$(*ubsn+4=+9fWRHSYc=55a{%Wx31d!|n+SfRJproH{e}F6z zw6W4T8KgLHvF$R*4F!2&Q$_JO&@W2QkfoEMPId8W=S=uq2R*MVo>n{*?4Bu0&xTs7 z;NZm<6kk|;5%3C%FD?Gb`Lis&5_)}gaUZbjy5j3)+pD3Cn~HCi^h{`fopZbF>7B)Q z72jQa5BTZ6;`@sq0RDs0o`;JcDSi~Bh243eM~uxsi=Qce7V3Tl_N;PVEdF=#OT{lk z{y)WYL9z~{#Q41_>93px#S1}l4M=_k9{d1kK`nvL&G0E`AuT?)I4hw}YuTC@%~de6 z!av^?uZR9`b2b!z>-<>!6XY%|Hj96Cet~{&E#6lABeeZ1$R;15)_cn_jkJET_(ky8 zx$GQv_Sx(#Ry%bjn>@3uwqokk%G&B!rhGEt)YOeWv#tV)##L68PntB7)lI3Xm|9yl zv0^5xsjit+CQHjkSC19>GZXS-CY9IJV9}WBs+!uVbz`6vWYkWr96!DynyIL&n~dzr zDlleT`IrjKmQS5pK9iMCshGhktHwfFJ7H?|bXHX{oeik0sXeI@h@ll@s;7=Usj{YW zbmgSV+L=A8LC1_*Hl=(jSXx$HS39MymX%jkRo9l+R#sP)l}{aCH@Tv!wrmopU}e+F zr&gAao>WmbwgL>ES}shKCFNtrRMgbOaa3t4O(Vl@*i5V$skFa0e(w zC$aKz(3`T#D&a9Ux?)`Q)QVUR3MQA;R0u_)!J67~5P{yqn4n`Srh$oU^rY%B6U(4Q zVKAFiSyd6wz~G5$wH2~RI)>z@)m@1=|ftMziPbw4RGr0l=E2@>`Cs&WH zgxXLtSqw{g)z~sPm&Q-6hQViJD`8ZG-)a~rol-ruwx(D04Jt##l#hodCsmf$uwgT6AO;SA0WYELmWi=rZ>NgB<5iE1v{on5v|vd|X9YRr$0^Fk8e$yh`1avCxtF zJk+i~=j+ccmg0P4W#Hop)nmyi$YN)o7zsAHe2PFEa86}yC3O2w6;oL>jNtqgrsBxb za#4roMF3WgNnpwF0;|i*#+28BcPD}CT_ca-6d!n22WPVwRFRH>-j6Ml@m4t&B3TAR ze0&HC!;CP-R@aIVC7h@-!ihy#3=`sRnovLyJh%z6~X$b!=~K4zj4B7SVJB_~A? z2!3pM6RO9sk1CMZKpB9DaALZmNGOe;I|*8oVoM0(a8RvfQ>KbYuANC@8_vlolPbql z3Ln;oa%I&tut54Ks+n+PM1c#zn`P7Dmn3;EB91b=Ue*IEtE(ypBqt0A!erKHxcDXt zO_^FbIf;eXQ#Lw5+34yz048w-rA>?}uc@VZxHi)47^sxMAkaY!m7T4rs+=+f!Yr8| zKdnds;ujT_5JnkraUvBkC<%ig65)#R!7!$k$JJHIP^LUIc}fLDHH=X-)~NvE$QZc9 zNpvHPL{F_$MFMJ4@na__(SnduDPjZ8Tv{-pA|VeGpz28#ztPT~;#zrVdr((XFveWz~cVSW&rI_J|I~iajbG2D;L+?D)7{_3UNu1b4NN^7gv3G)na7{7kn6O0c===^K8h2NNq)Q z+8xbAr`^#UoE6i+eNhn%>e$RYnu{)U%3!46QXjo80;opwa)Kv7HkyydH!LNl!D=MN zom4qlTsERA#*LE~V$9)b5-Wo>RT(U4YGQdYJ5SV%XHJw?SrscCH??|ljFyoam5>7& zE0_TDGzh_HkzB8#y-^O%6NreM$^aHb%cEy~GzTXcEMQ_qGF0TGCB_2Jjg8Un(>_{H zz(#Z)E*g_(E}RB9Z;_nnRRU>n2Z{--i(gZ4s)i-wE2;rr@QREaaFVPOLr|F!*jcYh zQqkTaO}Zl))2b_RW{06IW_>VQLltFk&Bpa)boR%_S5!g7kHKQOu#ifmd*u26p`{j< z1*|N7VXA_)MeJmqS~p2J1C~m7uCl@9V6+O94{vPm3lD^e3)F-$|VdS6)t$jvSG14l~zH}!^%|l ztKV2QICkX%8Yk^+O5JFfh_TbzY3vl%t7LddS?NvIo?1WLQ&(J|5 z1`A?T>9FCYLwl8sV#5bvI&jd?p@T-Uk`o4JfD%Ct8qNmv8`y6+>)WqS-vRI*&Ia}FJ*;#%8+Ky9!GpzT>44In!=;vC!%Lt_ z>B+;(j_h6rO%7v1Njy_BU_cqPKa7>0+;hN)UZulWzZ0WG?|!8NdJSVG!&vV@Ls7+$ z5hX*xepC_54DZ`-SXnG1Tk73!SkICHah_~2i6<*1@nqdmr6p1Ql9F8(a##?FkMC=kyzNBJ0)fq<+H$0WK};cOo0vxAa6dTqHe5 z3>!XZAnQF85-|)6{KQHJmh>9{ju<|2(9r(qkddXO{m~nelGaK}T03yiiNpJ1F_N+z z$&vk_XmH=5CBsU~hC!cu_GKl#PAWOEXKAlkzHiA%{Z8z|Mhp|_(9+=}hMp*>;X_M$ z_Lsz{!KH(GW9R^PL@66F7y_`Al@1tI%6gZG6uLCDlnv`SXmBaCHt57sc4EoEQiz}a zrJ%Am6hey(g5<j3X##0NX(7!SRFqN_Hs zg%@YVcjV%n`n6SpAk2>h8sRQmT)2Lnn7G>(7jUoNz+$nR7MF-G5EHmK|Bvsz#iemU zmmr$3KUOc8!ZQaY?HEzv#7&@hi9mOg&WhJ@?L)*%QY^;fWwIsrB)WcL9+ynDD2*2;8l0jw3|0zm z{Q8-q%yaz~Z!~eu5odeOx8o9YRvl;J3N=0*jPvW~arLbF8C#r}JOPUr$N-B^#NzCP z30XbYwZ_89R$M@8!x?id9$dShWwq54E2<8n3n$oBigCT&6Rmb2JAifT22Y9T+7%uc zu`fJ0qDz-9taE30jzkA|s>BjLiBIN-@C~exx99$!W}zgN2b2ezzXu{Lv!~Vg>DjJ~ z{`;h#8vbND!Lx9h`X!#W^S}Jcho=j*VhX@_o-xi(Fm(|;^JOjjn195-Vv~6_pURKm zhw{;UCO?t~xW+mEkp+1n&*S;LfG^<=5Ag^u;+$DL%!|3n4Ze~6iSNeyv%Ppncpl6l zd~e>3ci{W;{rC*ti66js=bd>M-c<$(hgiXb#i{|y(#7TpVP?Sd=qz{^U29ow*9I!ne{ZQ5 zZ41w?^Ln*|XWF%gqXP(Zgms8`b&)B91qy?w+Tp7kI}n~~C!T0`I6D&dRmAI9b{s2V zJy|L1gF^ANAM4KsvO#PJ8^%Vkk?{1oQ(#-NjFq!7tU^kShg3X!ZZbUCO`t(@eVxh9 z+#%CySREX(*K~LiA7d+v=Y&FVFZPS@OuJgv0q!R55IO?hN8%sqv5`<#e>}n$z#aRc zAY&p81@D6#W0(rPB6nEafkB`X4}3CE{ihryGrMA@#TzDe>Lc)R{3a&R+pFo9WL3{<_p z6WEQ&WR3=BrEF!#(BK@YQ=vgh*EYyZg$9f@4h^0u^g@FPW-=NSkTV}KK$w_2G{AXv zW6{7V+&w#s*#^g_u>z^lpukhjj-tVN>;iUiRQqM@3U)QSj?H2>NzN^vtzyA#Da&WG z*(v#gc{d#Q!SQ#X=deem+~YE3>?!zshMgyK&$AcV%WN)tjlId_FQ5|6o*g39YUsxTA`i(<_#>@>ga_0XQXn@{nEE??WbA$NQ%oQ9viUtSr%;yGb zrQjNl9b{xsS&Pw4} zg$6#N#7iXCXke(hf!9zp2|qO&7@oTS*X9PtDKzjL>xK(*jRtCN(D0b-h(u~MXgPBO z^qu7FILpDB0uDWI2H+Aov6W8;5qZlKV>d#oES$u%16rO=?^LD>O` z)N=!Gg$fPSuaD}ZBiCrKw?cz@=VyUZXds-bRtlMgR<6;Yqe6qs2FhnGg$BY=3JrXQ zOOjZw(O@5i21z5(v{{7)!k-EaGK;EQqd{kd2AK_%&squ%grgK1_zagMv0S4;7lj5% zBha*2g$BZ(3Jo%gs$8SNAcY2*4V2GX3Jrv#6dL#pmn5-Vqk*Z=AZY}eHmlG;_*0=l zW>J-EH0Y|(AhUt;SxcdTaFjv=pW%`umTNTVrqCd11e!Lh&_MW8p+RO*m1{IOK%qfq z1Ld=pLIdF_g$6#uB}pvTXmFrHgQO8?+N?qY;ZKDInMGBu(O?&a2AK_%&squ%grgK1 z_zagMv0S6UAqowWMxbf43Jrum6&hp~Rk=okLlqiiHc&omDKrp{QfS~aT$03cjRuD+ zG)NkOrp+oe5dKtXkXcma8V!z6Xpq@J`K+bTKsZXFfzNPB63aCj9I4PCX#|=!tI$CB zQ=vg-QI%^nI7*>GW&`E3mO=yJD1`<-!zD>9*JyBzLW86cXxgko1L04F2AM@wuF>FF zg$9`ol+RiU4TPf<8u$#CB(YqhK@WunNh8p-S%n6|p9&2!i>h3s!Ep)=G8-tLwG(fs+p@N)3xL}Wj`nbLkP@9_+9ic_iTtPL6a}nj3T8jnpABS#*bp|1jbJ0$D0T`v zjg_%-HilKi?Z^hJyD&jxkJyyvX@~`TbwOae6rKmr%OHf15GMZ}k~EW7~{%kr|Rg zehqwtg59i`RP+AKJsR}ng;AG;nZZnEF^9F5oKoJ$^Q`ptVn5!`vsQoJpQl5Efu1#E z?WID4SXuhdmWu{2h6Ea%$L{ih25%*y!4QcImlS4%>JXU(SaZo0X_Fogz9tW6cW< zPE%-*$sk7SC^V>do(4V;;&+t`us6jE!X-13ZU5*k|WH;h;QX5TR0 z8m42HOZxTV1K@WCy^NOe4I}mJj`>`n0rll?OJ`>n@!=MT25TIJ2ARZi^I9o1)C0AP zn9f6LrBLr3wNj|}g@0-cuZYgRlYfgiKBHNAC9m|XH<3@2zeSuZC8}k5CXsIVw}>@F z+J7H~q*y7`@#g)@4(__6?fK_Xnw6#Ee|2&>$nX zWu;Pf(BOm?xQl4CR=bFqgs4J;OuUwzI@v*kmiV2*XKHScQHUxu$jEJ3sgxZwxVQz* z4SFjy$S6V;8f4_QtW?Sl8cc41XwXKXK}Hd(&>$nXWu;Pf(4ZyG4c00&$S6V;8f4_Q ztW?Sl8a&hj=LVw`8e|lq3Jo%HTUIJ%2MtbdfoRZCp+QCws?Z=Kw`HYLcF>?D&JD&W zG{`7I6&hsZwyadj4jSCi0_O%p6dGg{p$ZK$a$8m^Wd{vf;@sem3Jo%fP=y8=xh*S| zvV#UMwZOT-ZVC-Dicp0H8M!Shm9m2dEpcw}jzWWsB2=M4MsCYWC4~k}<<_n0X(t)E zQlUXcZp%ug?4Uva7PwM4Qq2uAicp0H8M!Shm9m2dr?x;en4r)gqX<=KkdfQ6QYkxV z&=T)q3@9|nC_)t)WaPH2RLTw-w8Xi=jS3Aiicp0H8M!Shm9m2dXSTqV!W@ML8AYf< zgN)pkl}gz`gR5E~8a%DgAfpIvPESz3fL|1U;%`QsNmHri{=3TT!ccHz@VEFM#x%o` zwW6R8LUP#Kp}E4K7h=kjWrM>!kiag~wYI8oX6BU!g(9G1R=!;4*~<8IL49 zZJ*V_5qnK%GbMR%i$a4~#K=n<^1kQxo{Z&7IQd{JNd-zjRP zP#+imspf?SS1L5{KXfk1)MzlTMWI1ak)`GauE_AqXkKV=wL$~G1D8TBH5%N}qR`;L zqV5U}QpAQoR`WuGYZV&!8@7~EsnOu97KH}K6dkM3AZ2v;VKy%`xL%=wpF#7GNsR_C zv?w$vC>o^Dz#~2yW;ZW1n5EF5;UV*sNR0+BwZlP_*+H29*0p@F(<$yczX6lz{*aF0TRl%wR2nHmk|w=gtN&o}TFEvclM z7aH8B&>+^3O<(28&u48mRje{6|c(Wb;CU zM-&<)4^SiWsnK9%3qu2SM{^@WCP}n;p}}Jc4U)#EG1=5;u)Kw#fx2s{F)@=U+q}@= zafJqn!_%l-YBYGeg`t6ZzCojcCPBD)p}~_14H8DDahcR;@No-619jI@drd?dp&tzq_&~oPnTe5@(-^**TYxtT8V~@xTow04kI`|Y+{VNpgCh?-4(_ASn zNG%h&P%x24%bS9Jj(ed&DSsh@^RgfB=UJ;i@6Q`XgQn<}TSv=9gP$cDoX75BwX8!( z97n+W$PoHyB>ZD*{qYuGpoM}V8F%7yh@>$U@}gwtc&U{_CgYS24PNv-uf1DRXyEOe zhDx%tQdpzVK+O#r3cYB#*f)4dp7qUTrQp->MvArExxvU5wu^{?q2>mSJVB)RD|{|s z!8~{;qrvML%nTTNlfUU%Z$6(dR|*TH#3Gr#>nWW{Z@lXWGwq&Q5-nE)%kERCerg;?H3d@rb4gC?HsR7 za^GNCihYCgTP>AOPHg`Dn492jkvqRtBCo0Y(44+gXzIREeJyuxaAAv@8+4EEZK}Be zjefs$b3}vX@#~x4UNkJ%a?#+17KH|}NKj}H^F(7lSMZf^?yZJ*@=9S%M(5;OzSgte zH~bs9QdlP?*30wGpYyiL`y*EKSgu3cVt?bG&Xh#rKM-RtoL&_S;FmVcavp+alLK zFOk>OV}WR}9pXlzK~wv-vHG%u2CefI8qkqYXh6M@NT>UTkp~iG{p8d)jDEb7S|&T+ zF#e#vVN~BRrVcn4SL_>T@~lsu8~j$kMRb|iB#f53Z}2a*Z=le?=Q-3IcM@^q-n7^cE*^~+@M(QEpW#CsBQai4+}aNz81odOMZ^*pQ7 z^}9`=jc2{KfwmG2+DVD_GVS0govxL}mx;MS$3XM`^--rlrycS}m%zSo#C+2=&`r`a z^S2djYxP(5I;%^82HRTEV>_E$0MZ3;zmNRSC^N_YwEGUmBK)Xn`AUlD}|=^bwm2Hvr>3e ztrXP0K|`SzEf>3pgXA?N84c8T3O-%fWMbJtgPYVYqCx|oF`Dl821DYrPM^v^O#R-# zzps)dvx5e|s^1$ZG)N9Lk9;~b7^cv`!)w`LX9o>_QfQ#iz-PdY2#kbteiXcuR|=lCt#k{Saix~5S`%~;9*2%Lz zd2XO~5#8R(E+;!^&`<3ms+EGzz-^AdOrD;>oTQ=dw%lJPAFt3rp+Q5ZN3VxW2E&I+6ZNN`>XG`Jw6EA&Nyi#+RH z61YU}B3>pXE|=+*p30TX1&1(du^g zA-f^PE~3$j9-a8;{Mm3YCeqpYPicb2ROl7Co#S<%=Pu&x{DXFqUBo*Qye)FG^AmYZ zJr?P95pRh{mj71O+`zxDk|nbB1%x%gz(jyBDY@sM8@*Pf(}cNTd-BW-ByEbjxp& z%MKcxR;bW`4yQr`>WxGi?`Xa&1sbS3niD;h{akkLXdWC?cQn(nQ+G5|ZzR&`b`kH9 z`w5Bi4dv7>VnZJCF3--s!PjaRQSBRe2VFvm*hRcgp7qK525J{E!BIKLWCsnNRJ(`@ z4SYuL1Azwt3+AL)DLj(F%z&}S0*`stdpz*C{Jp`GQsQZuKI19vvjaZG#P1EBYv#W< zcp>n@4te9nz)Nt%9P&zFuB5fRr}KAf^%wRu`*Vul8|>DK9xn%u%zqjV#zgvb{y#K9 zV=DBD+|Kd(z31-@p3Yytll%|k6A9iHxu^3Jc}+bQ^CTL)4snw_H+VB1SB+_Neqg?5 zy#;{<3JuaYb5UTCr|;5Kix<6{5)IyHCD7n<_LvVeI6Mgr_6&;iA5+ncLW8)ob3i1X z`ME#?{I8|=Q=ozR=d~ORctR7|`LCr;>YvvVRtoCBmJ)(4A(L(w@xu(RRB9J7!M%;j zWM|*t4YiAyfClQ0X78XByNHYBS)aU8P`ilUUdv8NcF>?i?IJ2P@ENcl2bKXAe41jV zusnmA0b?ryD?ID146Ky<2CJpS8kw&3l=j&HpJHMc@tbD8i?}YZZil?FKJWt^F^6mn z{3Pk0w5x(=Phc z+_iK`g11HPs$e3osmEdruYfz3{|j-GJU1Ah(H+f|ywbDYL_SgeWBX(&Q7zLmJ*Atr zrveS?n)yGrPv_Hj$Qv{HS#ZSsb`C#J(np1A3a<@a!=7Mwr$B>iL-e>Ma71AZ9E^#y zrttZopfMGCMQ-PKjq*eT=)+Ee22&HfEpj!5iM*yBi_L*8fCSr8puu)|Woc}CT;rNo z9SvUMpV#uFM1f2TJ*B<0WX2b05Z0Rae=QlBu|wW4H4BcIe;lo~q+iV&RWPE}o$O;;!+?^53f3MfC5hWXbI88@#S|5!Jpya;SOa#V%qSdDbVd6x1%Fhs(0Y&JG$p zrFIb&8u*M^{4HWzz=LEoP`^d=>B1%x%g%2R-!4$UMWjQdev3%Gkw~}G+5-}FNPz|& z<%}Uwy5U?Wt&?ZHE?O74Z?LbF=ql50p3)7s)ffq}Z*X8U-#6It-y$BQ9TfNH!P=pc zZe38Ee}2I%_AI+P#lFG$1@u@Icss8+zZiahDAMBm*_xm+72X!Po#QprbKjsiKeChT z8#oEx7P;d5L|#*m1wI$?aEP1axq*5vVpIFNA${3-F5*6U>bZ#2^Xj>X)EkL(x?RL0 zsobDs~Z%mS=tP+(7Lj#+{TSB0Fd>RP7=v zH1HY0$7;s`7L=q|DfG->X24jfR_a-=kJd--8}ySB{bf4PQ`%<-e2R&EgF(%F-(ZL~ zWQV*lOdA15%poJSQIh_&aKFMHp_|zY?6nm820cRb_?CU%YCn)?Or-l2Rt5!)sn9EO zJICun&wYda3ay=F-=JfHw?%Hh!bDzEkA)R*;8#YcK-{?I1{wYOs7;`aXT7$8w(^(B z?W9C|nRf7$ZrYv-H0apOf0^7V&}oOf(Iv1i95KIj4Rn+AWv#XqY-{yb_ByLefd<=J z(PKNCTL9AVI~S2|EBHVYG^RqY$n6}j>pjt6TS3R21P!((cw6MQ6(sVSdMxm{h^M7M z1NB_QruKD1`m*y}#6PO%A||X9)N>KN<1pPWVp)9F>0Lj$MC~Fbd&GY}JNpKP+&57F z(Ht8Gbw_i|6Yfv3i&!qtde=(9E$oBSmbLYiYRB5aT?*}42Px4>rd>Rxo3=o#6ehFg zeV;;h(4a!?A|}iY6dHJ+S!1+wV0BrMVx=%XgP8&BIBAuh^(JZ)eS-_szCi*SsC@(PXvVogjhY*HyC`QR*_j(` zf~S_Kr=8RfqM94j`y!dbe`T#pfd=Y7nv;E%?R<9rm32x;{VOXSIrXos)EkL(K|uWc zae4|g2*-cbmRKWw&IlNu^~``Ne~YNTVNC7A?5q^J6@-E#gLBy&Ha*363L~Mc{+PfQ zXrW*Tp2sQDP;ffrM0AK$ykei2YtHGnp1(y@D+TXy6Z-};)xLqZgK}7s9W=O9?Hj0l z1D{chPf$NA#oRzWLEWbdn@lV_Pf*{go}iw92I>jw-T^xzFcN0==cGV`Q#@z<-r5*D zEpVD=y|O@=Tq%@Gi7_&*@RUy1O5@AKZxP2g^ShQR1C=}EjfsKDaKwC59XM0cXXR}O z{*reedyAcwVx{m)9zFiS9}RARgE5hA2wtTL8dITH>`d-bAtplP;&$CxV}g}Gx?GfbA!t=ny+83 zUG7=$O6^MZ%w+GOU^{--QmSVrf741lGx^Uo-@rSH)xLqZZ*pCdow>ok)V@Ii8mPH}cU)gD z_YG#Hm>b-f!8(Dlo3)!g>)oQ=qV^5EhayY+1|8+T!6R%TyQIN=gA0=O4PKQ0wS=iK zT+%i-Ooh$rK84gHmmRK_@arRy3k4H-P2Dc;8{C%y4b;9t zQ~SChec9PJn4$I!5>^Uo-@rQ#)xLqZZ*pCdow>nHYTqCM4b;AYcU-6YhVcQ@Qz`%Qt@{gq9z?5q?XR4au9G*BxA?-*7q1#jQvx+FU*g(ubAAOQ{3 zO2Ip>(|xD#r20<5+i_Va$qpK@Q!PN28=zEVs5ajccnBXZCP8-(sryJYY&IIqdB#U zvV#U|^2Hs^FS1EK?r44_>5k_6hJ3Y*m(&8bH&JKV&(mveVV^K&WCK;6-toiX;- znw^!x&1$8PFgH*u1@8z{D+O=g@Qz`%Qt^H^Ipc8uSi|?-b^;Ic$1^ zPf4AS^qs@Q!aQ;K0m&Zi>0VuAVb~Z*7dV3AFL7*EY~rt`yoy ziS{z>;3=K1mByEeJDNKNs+k5ybA5FRblM?rbP4PWN33^U1KlKjYW}u@ZLR*wUT1YF zRtno%(PKNCTL97pjEQtx!3Ub4F%^16Zs&MiZ_WS=SZ1t?%+Li@|Jqj2(W=iiXKHJL zw?%GSK_aiIt;g>a=A}RbwNhwmUpJ&LJ1d3L)Jh=%4b)1(I}X)K!P_^vF3HYH;R3Z% zNI(O%Qt*!J*X92(zL{cfFh8Ry^#W~yXT3$*BK1Fv-b0b4|6x3=pg8~hf;ZW}+0qm% zh4TyOaV~#5uQ*@)+oDK|^BTGYn&E5mqTK%vBd!$QO@Rh#rO@QV+knFC ztQ2b0N+DrxpjHarVfb-i8SFK^p8^e*$M>VWYr9KU1Xg&~TNzj>cM(@hi8V4^>nZKl zy(1j4i}+15-$h&(ShqvoSReQSj+mD=27Z!sVcu22GxFxMSJ=HN<_2fv(c^kPE_f9j zjEVHB;Dwr?F%^16Zs&Mi>A8z|Rj}<&vWs|0g11HPs$e3osmB861|OzC12s2jYF{^` zFFSLCQEG0W<^~OgUbI~7BI2w0JTrN*=gx!APNfiQxz9`s<}Y|8mN5(?|@EsNAt1_uF>j0n!SD9P)T;aVf;kh(VTz=YHr{i zhd4L*RLu>%U6iwu?92_WR&#>{G*EK`?|@D>H(0Lb2HuX#LP>V!2D;ogIFH@spj3N<(I9FyD?WM^)0qnaD2xq;6h7T+nXlyiXQ z^PPfE(;Fq$a=%l!RDGwAfCg&c!285e_bGV$Cf6m|St+Q0Wlg+?QK5l%T;nd{YPC}E zc2Uksva?dSRjm{f<_2mP(L12i?INyGyNKS7%R)(Z<_1jdA|{}Lnj3hBF3t_ss=0x; zi*inmH8)5=12s4B4(N1qgKyN_z}sL08{Dtv1_@}O<_6vYJt8m??t5LI0u4@y-y7>)+g);6;55&AWq~qzM{~K97$egP zPieRA9pQ*?7{@pBJDMv4l{@5(iGj&*#Jp4;I8)NQ1vdnL$-9re#m-7`NAoXv^!NvV z6r?x6FOEdIA$XN0XiSA(k=r?5H+kOCydl_SC%L2fn*?u*+=gHxuc^lZ=LSEdKm&D0 zb5r}eA${4I8$7M%25N55Q0PU=H_9iW{geU?{tLXuzcy=|J?m}Jwx}nerE%$^z@qq- zJ&l-W(Yt|zw1eW_KUh0d(oe`Ip?$($Wz{L>2J|^-=NFt9NPH67bMi@On2KiAlh8b! zpM`?o>Pcv#E6Kk_RC9wY3~*YN*_j*MqUHu_Zjd(a>I>V+xq-+hqd~{`Ri<9LVXBkX z$+KP;t&5r)q;X+(<_6cp(@xJXn8luDS2s8}Sd}z4m@Vf9mHHF;6)=LQN5 zntTv5R+t?$_`5=bgtatZ~vJcGfkFeH!L881r=xNpmK`*BRiS}G1E0~W(7>moav+u+G}xlhK%s%p z=v8Ro(@{AP%MKcBQ)r;jz-RO-H1O%D9EfEH4FdAlN9r5K*Z`{U6k?ume=0O^`{cLc zWCsnNQ*#3~H}DzK3JrWZDhFcOL4&ZG8z?mJ8NCV(d^#!zV%b51Vuc0@4SYtgLIaR4etY*GKCk?_umGCHl*Bpr>@YRvKR> z?o$}l%g$Fz&h{_WA*Xh$|da7>MOx?Ltm7c%f^eYP)j>gzLKs(bo&gAF{h7i{1O zR0OjyZ16bP0Bqoyy;)Tm0u{k53>!QHHUJxVW-r*l6Q~Gg zVc6h#umRY>Gkd`XoGp-we4Lq|KY~Tr01hX(~kYa5BHt@_|uz@E~5zNA{K?XJe8+c|f*uWF02xei} z;O{t702_E_FWA5ns0e0Z*x(mn1F(T-_FmVJ2dvo7KH9F~*@a=YQ)4Hm-!6?^8Z*^Q zwO;NqE8ovHyu%6f?4u)8z2DLNKJ~sy0dTBZs5ki>uRf4hKQlI#&CO0$m#X6`o_#b| z>&or+#$D-HHkK(x`>|}dyv}>-j5NdXdDQvrqp@t0A$j&uYM@QhSZ1~j`dF--teSA2 zHXE#7v`;MJn#r0@zqOLJ5@Lh3bBmezem$r4#Nzg{CN@|Ym9dSkS0ssC*?#&*j_JGbZ6EhE}`L@C-Y8~H^_b>5RbNyG6u z*U1LUM%Et^Hh9iJo1|qUX4{~T1=wKFi1y!K7&iC>*uXeb02{b76l~zeCblLF8=MU` z02_FwGT6Wqs0e0Z*x($n0ocGZd%*^tKt(VM!v>!O8-NWwvlndO2~-5LFl=xx*Z^$c znY~~GPoN^0g<*s9zy@Fg&+G*ocmfr{EDRf*4>kZBcxEryz!RtlW?|UiM6dzaz%zTn z2A)7gFbl&5p9UL%4Lq|KY~Tr01hX(~Z~@o=Y~Y!_U;|H}BAA6?gA2h1U<1$W1siw* z6~QbF8(ai702_E_FWA5ns0e0Z*kB>p0BqoyyZYydX!%wDj8Cr}a0!mz;-umRY>Gkd`Xoq%&r>*t~=#d{hmo`hx` zu)u=()Uy~*LOUQmsd#pl{Uo$Q(taj8Kb`ONTaYeDi48uUM?53npH)QfC)PxK=t*dw zsQHu7?oRHW6dFHE&exlu^6BKlynflpC9SEWpHn|q=TtliZR%*}wn}6F)+KsViuRYZ zHqEHcd+L{@;rLwcd=i?T)sQ?1?F$ClBwf-n+Xj6szy^axwEzCXu)#)Czy_Vi1Z>cW zhFJ$2n0PEtDGVFD6l`EzHvk*Ba~y2o#wNBV3>&-xYydX!Ol7cvCr}a0!mz=nU<0s$ zXZC^(Jb{W}7KRO)U<0s$XZC^(Jb{W}7KRO82{r&5cxEryz!RtlW?|T1bFcx}z%zTn z2A)7gFbl&5`-2U@2A{_gcoolz%zSCk|~9y{p_O^+E3B(>?${#noM>2O;4sLcoLc$%`i_wyFx$BY;Jao`Zsla z#j}s*YF)V-SIZo`VJw(OK4$(7v70v(I=>vG61`6Y;Q; z`P8!*PeKD5ggv4Y={*b^EY6>c2sV%-foC5H65~s-!FWuTS4$W+_ypJh*9|;V8f@SR zR0OjyY;ZQ%0Bqoyy;)Tm0u{k53>$nBYydX!%wDj8Cr}a0 z!mz=)U<0s$XZC^(Jb{W}7KRPZ0~>%1JhK;U;0aU&voLIMIoJSf;F-N(15cnLn1x}3 z^T7sS1JCRQ8+Za0!7L0Ld761F(T-_JR#Ofr?-jh7B$R8-NWwvlndO2~-5LFl=xU*Z^$c znY~~GPoN^0g<*q>!3JOh&+G*ocmfr{EDRfb25bN}@XX%b8?Gmzt?t=_X||SH%WUY7 z)>dmPJPEA>5UU#INoe=B=t*cds>9WB70*5@pMplUE37A>U7kM)jrTNIJPFM@WI@IF zPeOY-dA4}^mi=7B=lgmpS0intE{Ib7AvS2{79;t7iqqQFOMmV2)dICbdX!4_R@cwe zbn2uAH$7chZ!)`8)7A3&Uq|MR>^}NMb+7tD1sm)>+PQ7nxUV%&+bc!;c_X)^ROdbQ zOVV(BuAP2@UJ=|s^|5IutVp%;GjC+el}oA4wKEK~Nt!oewhempV1q#;+JApx*kIZy z*r4;6fDJm)Fza9g6OZL7g<*r$!3J0xc&0Vjz!RtlW?|UiMPLK4foJxD4LpI0U>1fA z)&m=W4Lq|KY~Tr01hX(~@EWiI*uXP;!3Lf{MKBA)2CoMjfDJse7i{1OR0OjyZ16^~ z0ocGZd%*^tKt(VM!v;^{egm+9XZC^(Jb{W}7KROWz}f(8;F-N(15cnLn1x}39l-`* z1JCRQ8+Za0!7L0LtOYgz8+c|f*uWF02xei};6YqB02_E_FWA5ns0e0Z*kEO>4ZsGT z*^9qu_5><|S(v|Q{ww~X*Fl4ZsGT*$X!C1S*1A7&dqmYydX!%--vq&qds> z;n{^@wo_v#r{6A(T^e{Uq5+p7gt>}1JEP|!o~$nQcrN1Y)^ibe)4odao`#C&A{qxQ zun_+$;%8IWQ&KN!KVfeolfE>))am!7^h^135!cH*oR#lqPo(on*wR(RBUHVgix`Ft zUY4`LmFj*EHrUl-gIn{br1GA?2OCTx1t;tppAE1!nD9Xg<`9Mr_8Y_6p!1O77sgIB z%sTEjF!5NPQW!S)C+;^et{Z?2+&K<5aAOl&6NU|*2OEG5JX0Ch4LpI0U>1fA=8n>t z0Gkd`Xou#Z0BeIb_{+T#h7C5xZwgo&c;+_N2A)7g zFbl&5YvoTn!P-C$ApV9?kQiTr4aQ@#yjsGrK{`Tz(F`__qY5?9-#&rWvpdy%sVT0Z9n*!LtGkd`Xo6BUwcZ$Q zTk3yXjdAF?T32p|T6ZQNpWm6xd$Px!$;JT-EX2Pv8Eg>vkWQfcFl@l@VFVkrt{Zr!G}yoss0e0Z z*kBW|0ocGZd%*^tKt(VM!v-$~8-NWwvlndO2~-5LFl?|L*Z^$cnY~~GPoN^0g<*po zzy@Fg&+G*ocmfr{EDRg$2sQv4cxEryz!RtlW?|TX->!mR807%s7e+y1d1fAb_N@O4Lq|KY~Tr01hX(~unX7#Y~Y!_U;|H}BAA6? zgZ04%U<1$WT|1qbvgrzHs+z7=R;#Mj@`m+`cF&FqvsvjZr{C;!c1nN4xKVDgalYTg zX+5#Hy{zY}1?uJLQ7YA2T|ajxcRT<7(`U>-OEyh6ZBOr&>8tYk`K=kPMI+~{@2XE! z{0-xxk{ZLbvVXS6O!sm^;E0ZGI0`M~rOGzZ*2^|5IutVp%;Gov+ab zNqMXD?xQ=}_px|(m7Cp_-sSYWJG~osA9VpU%-u(g5xV>6Hg%J_uVQV`dGFDpkqT>u7t}^d5igEW5*kIrXvF{GUu)(Xr2FBU|_aeFz6l~zeCblLF z8*B+S02_FwGT6Wqs0e0Z*kCKL0ocGZd%*^tKt(VM!v?Pb8-NWwvlndO2~-5LFl_Kz zumRY>Gkd`Xo%1JhK;U;0aU&voLJ%dawc5z%zTn2A)7gFbl&5*XB<< z!Tknu0Pzc>AThoK8;r+fd9{RLgRQYPz}mnwrNIWCKt(VM!v=2v8-NWwvlndO2~-5L zFl?|5*Z^$cnY~~GPoN^0g<*p?f(^h1p4kgF@B}J?Sr|6B4p$Mu2A{_g zcoWtJU<1$W1siw*6~QbF8@w5805b2aU!r2e-3yv_FTJSq<+4?6vRpZq?5O6nhSi$CT2hn?0Q!6slrPf2~G=1)m| zEO~5FXgr=gp*I2L$>gcLo-`L{hc)j|H>)pKJPGZvX6JTpb$3Z zNg9sNSd;>>It^sxXN3>wk?`wPPcD}oJ-GX=1LJ43++Zfs&} z!mzGnK&xo1fA)&d)V4Lq~==Ef}z zHnpF9bZgP>*->G3TjMsT-yMxR8Z*^Qbyse2cfS9b(|TfYds)-7kN&H1luGqh*UvqT zdnSd(uNwF2O=fq0;)Tm0u{k53>$nAYydX!%wDj8Cr}a0!mzv$IrffZS zp}Il+xZ>`kt;agIN7e5}=V*I<$C2L8nKD14I`64pl7{1Riu28DbEd33B=;MvZ=g-m zoGE78ppOOC27^Yl|Ng?P4PKVv?xW6Qg8L0R(JG<&9b zxw>7QSg|&ErrEh&-MCU)FV*k=r2W!taY}XGQ@j~Hl^v@|o@ z27N3(o62&;W`j%GYtD(pyfnSk>G!4dOZl0?dU=Pl^8M_IbUq1NVuK@8z0VZFtPSRm z(%Rrkb-%|O+jq6z*nVsN#&+Hl_;_RcBvNp~uFK)hWULJ)e3U{tgjpNh*2LPN^N3+> z(20gw$C-kO$MTfIu)#;c2F7m+U;}rKgALr+#MXpigO7s^zy_YF3^wotDuP)UHaHz@ z05{_gm=87p8+c|f*uWF02xei};2f|4*uXP;!3Lf{ zMKBA)21kPpzy_Y#3pVfsDuP)UHuxOa0Bqoyyh9bG8@REFtqH>h$KhQ|U<1!o#+iaAP!Y_+ zu)#NRrT{kZ%wDVwJb{W}7KRNj!kGftz%zTn2A)7gFbl&5-@};#*uXP;Z%t34T}cmA%WjdF{P^Zh1H>uymduA_G?y}agcWxYGO+xhFP&y0VT zY?^M`#`BfwtMdAeBQsiyMs8C#srxE^VO%uQxqY~CXLCktMoTH$&uD!kr8@6v1SAc| z=L60+ugz#p8jr~HwEzCXtPS|BtoVgdjthQM5G2Nz4>o>Z z+#g`C4gTc3Z(w{cWy`~jhn;?pG#<(CH+U?!cs$=f;j}LM97K)Q22VEX{T{}r8c$6M zjlVaZ)|;U9Y-3qo-!_}soYy*9{ZySfG*Z+^DT*HkG3N%;xzi)p<|-k~AEj z&pX!!Gn;dUWNomHfi_7qn`Yafj|JFZ(1`ZmUl=xcM1QNn2IWx!8x02_E_FWA5ns0e0Z z*x){}0ocGZd%*^tKt(VM!v^<*4ZsGT*$X!C1S*1A7&dqSYydX!%wDj8Cr}a0!mz=A zgAKq2p4kgF@B}J?Sr|6htcCjxIu9OxVeCZ1tb+|qJeH>vh7Ep$wE@-!o@os>@B}J? zSr|6>E!Y5T;F-N(15cnLn1x}3-+>Ll2A{_gco1v=Ht@_|uz@E~5zNA{ zK?7G2!3Lh$3pVfsDuP)UHuxjf24Dlv>;)Tm0u{k53>*9jYydX!%wDj8Cr}a0!mz=k zU<0s$XZC^(Jb{W}7KRNT0~>%1JhS&dlCKv}=Cq%Lc3WRh?7Snn!|8Wda##Ky#%ptn zCHel}oz|Wc@HC?*p%(g+#15ZgEG@||Y z7v?Fc=S~^Z?_I@HQsubdDXD_Q_!4X|9+TzO5{3=_4QybXDS!>!`3*L3V-s5wh7GO& z8-NWwQyFaF2~-5LFl;a%YydX!%wD{C%@e2yW?|Ui0=#(*Y~Y!_PdeYc_V@NXyga+g z&7Mx5cKSV=K8rW6bpdnozbRC`dF|%>&1(;+AE~1%epBdt@7kh~waDJyFl&P|aHfE@foICEoUB^>LT%q~uzLHK zYtOE7vo(`7oqlU2YvuPFtesoT%=ha#ttS$-w=J>3`Zd4bU{*3~QfSOhHqx75v2n6V zUf-g%Y-HK!Me0_yuwrenY_xNGUfnXHtw)ri{j!l?q*UiU^-I!le9m>=Z?J4+{ULet z+H(flBrO{;+Xj6sa20XTi1y!Kn6<%mSQ}t%;F**!Pc|+7H?h|SuWJ7<;)Tm0u{k53>)kWHUJxVW-r*l6Q~GgVc1|#umRY>Gkd`XoI=D@XTJYfhSNA%)+q2Tfhcj1JCRQ8+Za0!7L0LycKK!Ht@_|uz@E~ z5zNA{!LeWiuz_dxf(<-@ieMIo4c-Pe02_E_FWA5ns0e0Z*x>D81F(T-_JR#Ofr?-j zh7EQD8-NWwvlndO2~-5LFl_J+umRY>GkXtc9MoV_``Jf_6z!fJ6=w4r^PPSR8VedT z)l79nZgEt;f1lHOVsU#})3c8jHtPM9)Z-h+PYR6>G)~l;AaPRT_R%?Go!iC9mQ#+^n^LqtcFOe`)p<|-k~AEjdCq4a={XF^vyYB3&?f2FDQ4TC zj|HBKIA}!s?=Q@A5f|dQh{oCgZ(eg}DA>S_O>9jVHrTXKt(VM!v;IyJ&a%j&+I+b`5wlP z_w|ahGtx7herKg;;XRC9j!T&LFg`mvqqS({>*`LmsNy#T^F54*TJK?8H={Q%@}35c z_b_%jd;?eEJ&Xf~wCM0(_dSe<;Y zomjCpc&6F8UER1+TQAL&qW#iraY}XGQ@GM-yMco8_dq=Uc?*K;p(`GGljWYS8i7{?n=kBy;8Iv%P!ZFQoN^Wku)5i zN1bO1xEIlV1i=PwY+`G|u)*=T-vDO{o~e95dQ!2nx33}|;=FI5Ti5f``A)wD>4N-z zgOBGC&&c;@InOJ)MVYvct|ES-=2sCXf2MGLa()}nPbU}V^#i6{(waK@IrVdOPQ}__ z>S*V-N@M@lC3;he_LsCa&8W_M!knbx_+0K>8|YaL$!`i@FwiFHl9t&v=wpGah=WG7 z|Ng?P4Ze!2h*%qVCgq8VYi;n6_Wv@TUFBw{CZ{_6PD@V9uOeb?P>tw0$vIB!sy)os zbM?w#{Mz83`v3Q-qn}szs897=8_crS2H#F;HNbm{g|&f+cv#6?2gFz#tnIurd41=K zzZ(X#(pgTw+39TDncM}u$)71~nr_-g|CQ;h^7_*)x-5^*Y zXVK_=Lvkg?dwp_6wVzO{va%0)V99_3*(>>?Z3Y;zcB7K z1-~$M9uxe+*olT&2OF4pEKey68|()*Fs>Vb4cs}7-xS=~#MXqliugwSreLrE?l*Af zHP!}hY+`G|tPNUN8yIYWwShaYA8h=-xR=$wiukAYJ+5x=@tTJl4?F!HX*`nOnfzF8 z@p!&}!f8Fe@5!{#Rm3N2erNJiji)As#@`!H>rGI4wy`X)zcicKoYy*9{ZyS`fncTuN7(gM*cU9 zyr+TVZy38AzJaUa{|zI~6b60}`|dEznZh)jDd0@OGbh0Yo9k=wZR%#8yIYW`wiTA{dDqd@tj`!euL-xdVX&sZ8(2nO!a4`nyH$(#Yn!N z;;xgQPPZ?Hnm|7vM!I(1TLOix$Vo1n95x>{a8vN>;L_t7t^d({^zeqr2wv~%0C zabIiR$h;AyXg_b{mXzwer+!Hqj?cBu`wixeY&j(N8=PUFP13v(vu)7F;@;$b2OIph zFE)5EdC=+i`{eie6V(5ZTl^{CKkT#~>`aLb9;x};RUS(on-m(4Cr{{2aCgHQF!EPD!cGd+L{@;rN{8WP`=oT0_DHrx|FI zv^X={27N4WrZ8wk`|mHznZhW}6mX{CnUr7yPoN^0g<*pifepY0p4kgF@B}J?Sr|50 z8*BhJ@XTJYfhSNA%)+q2x?lsafoJyOegjXSBAA7_-{2j%-@sr4+;8AcWvmU{*u>U^ zSsSc}wSmC~xZl8?*LX*>8=KggFz;yIs)=_rcOJ=0TAL2ZFO2cu(fp+I`38S)-^bF4 zWv}|v>C;ZXXVYi#e1k3khJ3!k1L{ZWsEYdy%;y`t)p|$sb@}rRcuxbz^9{NjzJaUa zKi>dvR~h(0?7PD-*9{io?JCBZ00;5?nVh*Z|iJ+<6T)aAOl& z6NU}80vmu0JX0BL;0aU&voLJ1FW3NV;F-O+-@p^72xeif8ytlD4GcEGbpv-Qe>M4f z@mFv5Uo>CQ{%bh5_jt`!$yH9jZzbQ#|Az6}++s<-|97YL_`WC8LVv?}UCsZ7@rLAv zNuhCL@_oGtN;fCBcSYxzv`$4i*Yl+^JqWzNA)hX3^PyLcK z9G}gcf5W(>_4rD|F^6jmv`JdhGTR0{54@v!(1`ZmUzm3^AAol>8*2l+quHIID<`WK z|C`urgVo#r%ecMAYt~HGbo#B8td*|~*3KQ68O&B&< z0c-#^@Jwa=rr-%w1hX)|DZBx{DHv>k-xS=bj60Lv*u>U^VS_DlHaJ;bs*bC;ZZJ3N z+-`5&m5ya&`U!lrAIo;j>%1p4NHZLtN1fLVzy|Ikh_!(mo7kE#Z154R4X`%wOy&P@ z-fwVQ`|7l3SGn08$sJC=yOO(bzd;u;C;vB$Rreb_FhchmoT0ArxZmK_*8K+SWORoC z?`hz;-=NFk8@S56w;;y-26&&szz<^I9focooc2G2A*x2qdhW=r*^6z!L0i&Luep86$eI6fCRuNy4QW)I2z z29FqMle9E5+Xj6saHcS5MEmbA%$dS%qc~IOJSMm^xf2bueya1?M;~`S!^rHxl+H-c zaQdBs#qJC&ptZTdiK$}89nWY z_cT;I`^Y$8fra?bK04RQ2A^){)kG$JVS1s{@8a}gut66vL$bjY>L=>7o^0?Diw$nf zpM=JH8aUXX%i$ZiDn1)L*!X>er(s_=_*2n7u}MDMc-ZOpNaK+Py_NN`+~VBZ*~1V)p%-BX#BnLwBBTP&o-9j_2-&1oAX*ntDmYfE7)LOt8=@v zabq@9+bc!;na%T4s`H-uC22T5pLbq2nAw~&B-ahrG0-MyX47mN^szV~J*l|vWV68` zeSK}_r}LeD3(^Jo+Ti1P#53~!Sw-|g&&%$Q*x(a2zlu2dwZZwx`E5Kuom`mLFCC$0 zCVx)-T%A+F22)2nw^bVZw=U6}Qnc4k7tW~8dqR|?;rLwcWCJ`i*?k1@1a&tyu{B|y zpw4XYd3BHaR8KaTWwF7xQ~Lh%p3ndr#LS8KPf*A64PqYO?yQ68 z&E&5eRNa|;JMK3y?nT7?2JXE6Y&xY-+E)=Tab68{_omdP>7`D;FQs3~uOhCOcQ7m8 z&+gXQ0CjW~@d*94p*sJj5azFzX6wI0oSR*#?)Uf`#$BzyVZ2rUMWa%@r-OmNVH{ve z_UtM(?nNYNEHm4Bb}>N%tPLgzSU~eIYlAzmHo)4zGi$*Ho>UROdaR zLDF!1{xR(Y%>nmMeN2~BD?fOGdWnTy8%bQhFs{(PxON4LYBZIyXDi`i1fM{1-;v)0puKWA%{>(`x>jh+h~7hcex7 zQ1|yRhB;IC3CrFrXEH6*dzDn_)`Xy;NK4&@aOkSL=H6(x0e42qaNsBYHZP3R8R}lw|X#f3% zSsUDqwE@-!o=N$n^Vvs#civ&#t?Q@Lr=5P!rqANpM_s_1JR4L!39T_gPeOY@{Yc-J zz1|pYTk3yXjqyOtC!xL7diK$E`LmCBPxg5BQJ2Fva8>+gAAt=9eh~ZaFbo@93pOy; z1~XdIhU82EY|!^tsfQz7H+Xqk@4s3K!v?Iegipx_=QoB7+-=7#$&R)TEeiwbyyo< zZQz;GU;|H}BAA6?gX_TtU<1$W1siw*6~QbF8{7ak02_E_FWA5ns0e0Z*x-9$1F(T- z_JR#Ofr?-jh7GR6RYb6XXZC^(Jb{W}7KROO#M%IC;F-N(15cnLn1x}3o4^KO1JCRQ z8+Za0!7L0Ld>?E8Ht@_|uz@E~5zNA{!4JR&U<1$WJ=gi{qfa}ZVbrbb3)2goeix?~ z-Lo#45M13!p; zcQ|=AsCr}j)gwz}tMz>Q68 zO&B)V18e{`@JwZ#DR=@E!7R*~!q0G~V6Xws6x^wdx3apiiLD9qR@T$;R#t-z@K#oL zUSn_o81SA3j{6O|9KM08;@@uoHW>Ip?7PD-Z18A)_Yv4Y z4hx=yCP<7g!3N_oSzaw+*x)g+fpMk)HgM-R*uafVY)u$8_&=}#*uXQD!3Lf{MKBA) z29JXczy_Y#3pVfsDuP)UHuwwJ0Bqoyy;)Tm0u{k53>z#3 z8-NWwvlndO2~-5LFl@l@TEZ`kasct0f*>)z1RIRUWO=oOVS^{JHo)4zGo`@>o{_g z;CC(IDxw@fTtyTl#+P7&@t7>HmN0DacdQMtHt34B@G2X7y1-!|#f&1+$SE!$; z(|W#L9jVHrNns051fAHUS%e4Lq|KY~Tr01hX(~@G`Ig*uXP;!3Lf{MKBA)2K;svTt$=v zh^vT##P||yFdmcT)e?pcUXHZ^)&`y_4L0xuDuP)UHh2Zt0Bqoyy;)Tm0u{k53>$0)HUJxVX79bp{Rx|{pr)$nYGt*mS}kw*ZPD)8QDOFA@}Sf2 z_sQ>*nQEr`LvHb>eE+c1dSY>VS1w!RVyM$$5Q)v16y4Gj_JRMqO6% zo5DF`o!iC9mQ#+^n^LqtcFOe`)p<|-k~AEjdCuPy^c;rdH-%#iv`IR4irF^kV}a`i zgGRLf{=!^0*a6oKjI{x-BDymaY~aQwwk8Z4>ieMJzOkq0C6bv@N znSwi&aTU>xO>9k=tB7yIRYZdga23&=*H|04v5Bn-vo=^6YXgG~ur_e#HQ2z7O>9jV zHdqC005GnH|s;0aU& zvoL20tKv+-U;|t?aHleUQ*dJwTNCCtg^%Mm1%nOnn}R#9u{LmH6I&BzZ7>6C1A`5) zHgM-P*uafVY)u$8SPg6dHtQ68O_;U8nphhcY=E_aJFme8Zfs&}!mz;$!3JOh&s4@$L{Fe1n1#8D zconW98f<{y6x^u{HgIDTTN8#2z6CY_8+fKN&J;X>ieMJzOyRXSQ!v;7*A3jMjNcU8 z*u>U^`AuOv{H9>A0e(|(=QY*_Zfs&}!mJJEU~OQq0oDfYyapS%v5Bn-!v-6J4ZsGT zsf??LoQ68O&B)V4Qv25@JwZ#DR=@E!7R*~!Ygp5 zV6XwM8@N*$zbUw}iLD9qo5Jq+O~GIT{HEZ}Ypf02*u>U^SsQGMwSmC~SR1(W8rKcn z*u>U^xo+^~)>t+-yHOpkj#KN6(YB@jx78TWZm!mq+ZBzw(y?qTQ;POu+2vYNiuYts z(r|npoqmGmfcvLDHtmEJsaAe)6|uy^u7M3~M3$c%h7IQ9Dk9jxGpWG_o>1t)Qs#+~?xT0wH?5HriD!Iz(_pRhx$xJm+NH7+KOsn+IOcGTfi_7?T4vjz=Yii8290R{ z{e}5W;c)z>V5|-Bn}Rz-u{LmH6I&BzZSWJU4GcEG+Q6OHU;{Tcu{B}X;HO{%uz_bP z<0_&jP!Y_+Tt(a;R}l?1z%PvMR0bQkv5Bn-!v-G&8-NWwQyFIpoh{{=Px8+fKNt|EE@6~QdbRm2bADx$##_)Wo`%D8Ue#wNBV%yom)aNWRQ16((7 z=QYk0+}Om{ggI0A1jrLYVr#-&H`oi;4GcEGbpv-^<4nPgO>9k=Gli>hreLrEt{b@X8f@Uk zCblLF8~hS%05N1vfUaHDS&aeuXmygAH)qz@67%12;CYHDTD`Ot1miz%!L`-M|y52xeif8+;Pi z4GcEGbpv-Qjv&r#{C9vY+`G|+;8xC+;3p80q!?&=QYk0+}Om{ggH~V0%r;a8{jIUJFju3;KnAl zCd`>aHZqpY&2ChOtK-yqW3+9l|7|tKvzx1R<#t8mu5>IL%ao%1Sa!LVl;S_W@yM3!Pv(i~kzuD>Rbf%iAHp(qF&i9)* zt*d(Pziqx+pkAIHrBc1s^>cS}cQTo={Vdru-LyTuSEjGZ>y42atwkf}tM95$RGcX+ z8tL2~O73jVXw7ITMf(}8OH!)yo<>H}aC|=CJX4s_nzr(A%wbgnZIWiR%(g+#18gv8 zMEmbA3>&n-2FBU|Y~apNTsLrI6I&DJy1`d*-N0Z2Tt#%}HLe@Dv5Bn-bKT%;xNcyu z0j?Xk^BQLgZfs&}!kj6brqBOz-Jm>{I8!LGuxnrg8om&A z1{>f^!JXIFHKr6w`|hLd8g4JQW~atZPQP6myEN$TqxEw4S^0jpyQ_g}=b)cC6qlEyN#tw#qFR4+@P zPnQ*UuRX8pvQanE?&`8yPd&Ijmg#5|Qz?ln)>M*?H8Kt^8yW+uv9EYY6w|hpI2KuP zJl53tUPKz9%&MP~XDFVGrbuzh$CK?RHG?>#{QoD)@ec7LM#0FHFebhsm?6`RDG8dY^)KLO~-UzIet&*)&2tm`X`pv8IxBq>*uON&Qhx^k)C2Z7Fdq_GN$45gSlx_E8UM zvg6{p%Uo#wQb!2{dLu9+dqFm%$e9=Dx@_br?XF&`_0)sgV}_1KF_n_IVofFKSR>;w zOZF8HiDKH662~Gdj>nohpDEA?Wmf%^JVWthG(|!Q1bQJ*zcU3shu}4@y&u$>LN8R7 zmmX&d%L{qLB?RhsroiVAyyms{gE~{F>#@g~LS2u{zs9)M$X=MOQLIj1sOz%P?4{j> zM75rJaC@wwqftzyB(7LfNjlcZIJl(#sK&nHAyG`*QsP+b%l@RR^O*vTPiECm$#WM^ zMpGn|K%f@_FUr=*UQ}e@I=U_!`ANI0k7_;j;P!Ztjz%$+lDJ|`CFxir#~ubw7dGK)>98|kC*6Z z6jLdQE7nw!jx{n4E~!7Nv9EYY6w|hpI2QY|Kk4es1~fjIRX-)qT|600kx&AGUI@H2 zds+6#~ubw7dGK)>98|kC*Cb6jLdQE7nw!jx{n4E~!7Nv9EYY6w|hpI2QY| zKk4es1~fjIRX-)qT|600kx&AGUI@G*+bnxUk%61(x@_bp?XEtm_0)sg;}tp@#Z*e- ziZzv_V~vc1OX`nm>?W$0Pr5p@0gX>))lbQD7f(i0B$Pm)7Xq7STV$IT z8MuY6%SL|E?&_mjPd&IjHrLT8rcx4Dtf?d&Yh)Z;Qh!uqU-6JArfn&4EcRu8($$#_ zXnZoOeoCIZcruzIp#%cG5ZE$%O}1r`fv?eZ*~m}YU42yRsRy^mmO2{6R7&ECHI<}e zjf{g!>W^ydD;^TXv@Io$#lGxMx;nD~jZbFPPswu^PexNDlt7>t0 z8~I7QtB-0u_2Bk+osLE^m6Et(O(p4ABjezb`lA~AiibooZA*z`u`m0RuFh;gNvTceCe3P!rMt;)n>Z4juJ-9u#(a|WTQW96JsU#h1WE@;l ze^g^%@sKE{Z7Fdq_GN$4)tL=wd@`$kN}juTGMXZx1OmMf*f!ff+qTHS?R8x?@{@K~ zAJuy5!R@iFjz%$++P;V@)>M*?H8Kt^sXwZ*uXsol)3%g27W=Y4>FUe|G(MSCKPAsy zJQ+=qPy&Ho2<({cob6a-;Lf@(8~I7QtB-0u_2Bl{QAeYgN=aO?rjm55k#TTI{ZWm5 z#Y3W)wxz_e*q8lDS7$b$@yV?EDS7VV$!Lm%5(xA{VAt%e*{($fzE#&{BR^?(^--;- z9^4+g>Sz>GDTyoARFaN0G7c`OKdP~>ct{k}wv;#)`?5dj>dXc-KABZNCC^u3~HDTyoARFaN0G7c`OKdP~>ct{k} zwv;#)`?5dj>dXc-KABZNCC^ zIvT}PO5%z&m84^hjDt(+k812I9umd0EhUb{zU)uBI_AD~+-MTIt`ANI0k7_;j;P%*4N28cZNnEj}l60(*ad1ifQH_1YL!y|rrNpt= zm;FgsXEvbm$*lS*dG6xLXo`dq2=qc=?`+>}?;->D)pgm(Pug95RO_h+x5wT(8pTvf z;)*quq+^YYgG=g62-JFC62|u>`%HnvjL4yX4Oy0a~DrWQzVo?pcew~$@b6Q zQ)J-&x-J{}NxQ3$YCZMf_IQtuMlqF=xMEEu=~yG<;F9{I8vBZeL@{kkiDR)Z`;)HD zY(V3aS@l!$+{Kg86bU5|=!L+6*}>U?MFt+M>#~ubw7dGK)>98|j{|iyim8;u6>BO< z#~K+2m((BC*jGFxifLO)9E*L~pLBI*0~(*qs-KeQE}o30NGO3oF9Z(F4$BTLGVm~6 zmyP_S-PK36o_cV59IB&HOr<2QSW`(l*2p-xr2eSJzTzQKOxsf8SnSLGq^mO<(D-Cl z{gga+@nkebLJ0(VA#iwhWOjIwfk*1PY~&~Hu0E>u)PvjOa2<_eDkX8nno82KM#jM< z^+z@K6%UDG+LjW>Vqf+rU7gv0#wWAtr{uYdC!;A6N+8e+fuplyvZIR(JVw`LBR^?( z^--;-9^4*B>u3~HDTyoARFaN0G7c`OKdP~>ct{k}wv;#)`?5dj>dXc-KABZNCC^X~p z4~b&hmJ-KeU-lcQ=Cx{gLM zm6Et(O(p4ABjezb`lA~AiibooZA*z`u`m0RuFh;g62-JFC62|u>`%HnvjL4yX4Oy0a~DrWQzVo?pceucWuM6|Dl+ghx-J{} zNxQ3$YCZMf_P9t#qnJubT(PE-bV_|Lw~&!Ye^j!scu15^%g#E-A}fx^x;nD~jZkLQ zPsuYBPexNDlt7>t0$<3!n0=whz%S~$Y~&~Hu0E>u)PvjO3pyIbR7&ECHI<}ejf{g! z>W^ydD;^TXv@Io$#lGxMx;nD~jZbFPPswu^PexNDlt7>t0+(f9&Mqr5@XNX`8~I7Q ztB-0u_2BlnOh==bN=aO?rjm55k#TTI{ZWm5#Y3W)wxz_e*q8lDS7$b$@yV?EDS7VV z$!Lm%5(xA{;49hJvab{w_%&UZjr^qD)kn3SdT@JuMMtBUN=aO?rjm55k#TTI{ZWm5 z#Y3W)wxz_e*q8lDS7$b$@yV?EDS7VV$!Lm%5(xA{;2YUDvu_j`_)T4xjr^qD)kn3S zdT@JuLr0^SN=aO?rjm55k#TTI{ZWm5#Y3W)wxz_e*q8lDS7$b$@yV?EDS7VV$!Lm% z5(xA{;L7ak?8+houhwC`+qy0r`ANI0k7_;j;P$vi zN28cZNnEj}l60(*ad1ifQH_1YL!y|rrNpt=m;FgsXEvbm$*lS*dG6xLXo`dq2=qeW zJK1-$?-UvMU0s)r{G{F0N41`MaC>}5N28cZNnEj}l60(*ad1ifQH_1YL!y|rrNpt= zm;FgsXEvbm$*lS*dG6xLXo`dq2=qeW`s{nz^+g7LPuFE5KWTUMQLU#Q+#c8KXcSW^ zi7VDrl8!Yp4lb!bsd}&s{tjO_5LnfnEsQl>H#P zsmQ<|=(=p=C+)62s`b=^+v6r3jbbV#amAWS(y>Oy!6o%aHTD$`iDKH8631d+_9tDP z*?`6;v+Aehxr-;GDH2K`&Oy!6o%aHTD$`iDKH8631d+_9tDP*?`6;v+Aehxr-;GDH2K`&WN|#1(5QNyi!)2ba_z)!0`&B#LQUN*s%Q*`IWEW&;|Z z%&MP~=PsU%rbsA(KraMt&+g1_FEa2>U6+mgq}|m=wVrx#d)%(0QB0*Iu2@q^I@ZWI zxTOB5#=hbqQB2!X;#lm<{-moj8_@V=)V3iwyjQuFFP#((dY`T2DQ=J$|mEQB0*Iu2@q^I@ZWIxTOB5 z#=hbqQB2!X;#lm<{-moj8_@VZjznizlNg5=tP@3xVHczsr78WZ>^~T{iNQc2^(Odg{UL z@f#hDVk#wZ#hOaeu|~$hCG|%&_7x9_V%nAx$6{ahCtaP{fW{}Y>ZjznizlNg5=tP@ z3xWU19?Jfw$iRnmT{iNQc2^(Odg{UL@jp5m#Z*e-iZzv_V~vc1OX`nm>?W$0Pr5p@0gX>))lbQD7f(i0B$Pm)7Xp9G{+#`>$iP4Ax@_bp?XEtm_0)sg?W$0Pr5p@0gX>))lbQD7f(i0B$Pm)7XtsA zJ(~S*k%5oux@_bp?XEtm_0)sg<9~HDim8;u6>BO<#~K+2m((BC*jGFxifLO)9E*L~ zpLBI*0~(*qs-KeQE}o30NGO3oF9iNC`%CtJMF##w*JUF=X?OKet*0K`9{;DKQB0*I zu2@q^I@ZWIxTOB5#=hbqQB2!X;#lm<{-moj8_@V=$lKP_>`-+D|F>OnUW3ey$ldjHe zK;x5H^;7cP#gow#2_+Edg}~pke`J3vGVmX|E*tqtyQ`0CJ@w%B_?wPKF_n_IVofFK zSR>=$lKP_>`-+D|F>OnUW3ey$ldjHeK;x5H^;7cP#gow#2_+Edg}^h}bJ;UR20o|j zvXP&(yZWfsQx9&BXLK}*sg%SOYbr^{8W{(d)F0K@S3D$&XX~p4~b&hmJ-KeU-lVk#wZ#hOaeu|~$hCG|%&_7x9_ zV%nAx$6{ahCtaP{fW{}Y>ZjznizlNg5=tP@3xTobip{Yi16R~_*~m}YU42yRsRy^m zn2ts^KWTUMQLU#Q+#WB`(I}=;5?8FLBpqvH99&X=RAXQ9kSL~YDRC_JWq;Du znGI-sGOK<{p1XK5nj)bD0=*D;Ve>`J7Zw@#B3+k_{G{F0N41`MaC^K^N28cZNnEj} zl60(*ad1ifQH_1YL!y|rrNpt=m;FgsXEvbm$*lS*dG6xLXo`dq2=qc=o#wjDb&3pJ zSJ!1DKWTUMQLU#Q+#c)bXcSW^i7VDrl8!Yp4lb!bsd}&s{tjO_5LnfnEr_xVb^|#YF~gpzE@cpR~LBsMb>tZjTr1XcSW^i7VDrl8!Yp z4lb!bsd}&s{tjO_5LnfnEq~*nCNI!y*G;qU*Ae zpR~LBsMb>tZjTLhG>WN|#1(5QNyi!)2ba_z)!0`&B#LQUN*s%Q*`IWEW&;|Z%&MP~ z=PsU%rbsA(KraO5G+)}BQ)J*vbzL^{lXh1h)q3i|?J-A3qnJubT(PE-bgYqaa7q19 zjeW&KqL{X&#Ie|y{Yh76HlXpztokW=?&8U4ii8pf^g`fe%~v#ER%GBSbX_*`lXh1h z)q3i|?eQ`ljbbV#amAWS(y>Oy!6o%aHTD$`iDKH8631d+_9tDP*?`6;v+Aehxr-;G zDH2K`&86%U6+mgq}|m=wVrx#du*noQB0*Iu2@q^I@ZWIxTOB5#=hbq zQB2!X;#lm<{-moj8_@V#~ubw7dGK)>98| zk1cdGim8;u6>BO<#~K+2m((BC*jGFxifLO)9E*L~pLBI*0~(*qs-KeQE}o30NGO3o zF9crGd|mT3MFzf3*JUF=X?OKet*0K`9pSFEWd9cyG9TvC5jV_)%*D5h;G zaV+*_f6~>N4QPBatA0wJyLd91BB2BVy%5;CxlMEHA_KS4b=k;I+FgBA>!}B~$JRO; z#Z*e-iZzv_V~vc1OX`nm>?W$0Pr5p@0gX>))lbQD7f(i0B$Pm)7Xoi; zZrglQk%8Olx@_bp?XEtm_0)sg<4rmm#Z*e-iZzv_V~vc1OX`nm>?W$0 zPr5p@0gX>))lbQD7f(i0B$Pm)7XsTicWiE7WZ;gvE*tqtyQ`0CJ@w%B*j`7Ym`X`p zv8IxAtdVhWN&QiceZ@nfn6{l==gc1n!LSX0SuFai` z4BS=MWg|anclA-NrykrMJL_l^Qz?ln)>M*?H8Kt^sXwZ*uXsol)3%g27W=Y4>FUe| zG(MSCKPAsyJQ+=qPy&Ho2)woV_U2oQ41Bw;%SL|E?&_mjPd&Ij-m0TfOr<2QSW`(l z*2p-xr2eSJzTzQKOxsf8SnSLGq^mO<(D-Cl{gga+@nkebLJ0(VA@GjoyPEGPGVoox zE*tqtyQ`0CJ@w%Bc!!QgF_n_IVofFKSR>=$lKP_>`-+D|F>OnUW3ey$ldjHeK;x5H z^;7cP#gow#2_+Edg}@%oJ)3(J8Mvpe%SL|E?&_mjPd&Ij_R!HNrcx4Dtf?d&Yh)Z; zQh!uqU-6JArfn&4EcRu8($$#_XnZoOeoCIZcruzIp#%cG5O{ZU@8-LU4BT7SWg|an zclA-NrykrM@7B>Mrcx4Dtf?d&Yh)Z;Qh!uqU-6JArfn&4EcRu8($$#_XnZoOeoCIZ zcruzIp#%cG5ZJf*p60$q2EIqvWg|anclA-NrykrM`|4;EQz?ln)>M*?H8Kt^sXwZ* zuXsol)3%g27W=Y4>FUe|G(MSCKPAsyJQ+=qPy&Ho2<+cHu(^Mcfd}fkY~&~Hu0E>u z)Pvh&e;titDkX8nno82KM#jM<^+z@K6%UDG+LjW>Vqf+rU7gv0#wWAtr{uYdC!;A6 zN+8e+frFceHV-Z`@K9Zsjr^qD)kn3SdT@IjtfNs(r6jIcQ%O43$T+y9{;0;j;vrE? z+fw3K?92Y7t1}zW_+(c7lstFwWHd!W2?Tl}a9H#3=3zw!9ol*AQlDoMv083&itAJy1bJS2)~TS^>@ec7LMb!Gz^pUkSClIJd-jHXB^fj}<= zj%*&?JhI5Zqjg<2@{@K~AJuy5!R>LRjz%$+lDJ|`CFxirS#6BV-+EI$H-(r*ZP^N;WWOOHsJR)$Tuz@jaNnG8VJ7 z-qI84wky_qgc#jq5%^g1^ybHk@80RUE*teL?XDQrdg{UL@i85ZVk#wZ#hOaeu|~$h zCG|%&_7x9_V%nAx$6{ahCtb+~;$NSV#y6SK@Z6;bMpGn|K%f@_XEql%&nz-d}&s{tjO_5Lnf!+w5*Zh>;$nLymxsfdGR3HB# zTe6@%*GQr|w}@UWI_=KO<55)7mVHY^9#7dm`5KRl#?+e)I!DBj$G3DJQ7?NMM^z85 z_A1+|Hu5if7Bs6Y(FO#n5V)Xuk=|Hyfsvyh(Cw@xi*n<(3kn@comSLdy>S$dMs@D7 zb4;uwO=s&M>NG~4UC9RKY$*!2xZ3^4F}?@WSH@zt)?4~VTJP~;bb~|!n6IT51m88AeTC~Gm3f}$Cv0iNO%{+gu?8qYX_<#*eJeIe#cjY%x zMkU!vGFw*LPm~SzPWNuJ0o5g5XX#>tYU@tV;jIha{m-#pY;bkX1J{5Jh9o6-uly#; z;3YdrX3J{(iL$}&>F#Ydpt{8CEM06+ZQbcPymi65|2fu+4ZfZ8z<0m~Lz0q5SAG*^ z@RFS*vt_mYMA_iz^yoGlP+j76mM%7^w(j&C-n!u3{~W*DyuSGEeYaU|gow1e(5co_ zA8wE9b+qeq3yCY%RFaM(mm`t>sAOO9kSL~YDRC^aA`fY=^K}Cnqs*$GlIJL%f~LqQ zfj}<=zSq2|$iVM4%Zzd;&qm;wL!IYr|0n21@HdnST8oX9czQ3O2+R03rTj;l(04ke_#dg?nkBD zIO@d)cY+PN9jw~vy62r_Ck-2H5dPo^-rbK%w{g^q4SoVP=ytGbr|X_~lASbcutE5P zCwO;1D&59WFE;pT&IUiv_f@0DZwghYEWfq|mFMg-9?4FU*|OSxqSp-;qzl^D4X7^h zI!o7egKFze&*7~L-u=(9UTpA-oCkghHW-qW+^6!JD1(>mB$+L%?I+3x`=tA{*?{U2 zud{TqLA7*jsMckkEDaw9~f-GxrIp89Zm+^3`6ms?0&v8IxA9Jw5c z^hYK8iibooZA*z`krjDJd!6q-qA|*>`YCyi;wfl~j1ma+Lf|uf=U<4sj~>WJgZmA7 z9ksgXyPu)T|5Y?vTsH`R%mnZ5N2S|1>cs}X0ULBXShdr2&pXLZ8aCJ<{J|5vyC0Qq zupD3`<6K zKSP!5q}kxQLHJ`Tcy~W4-NsQbHuy`<21~Iv=yu3zq?=#)|FR5FvXf-CthS%%+F*V< zzr8k~y2R@&U2B7C>rT(%tqb1$&#_)?@K>x2hAJ7m|1TujNmIhwApC(9yt^NjZsVvI z8~hDy(CuK=PS-u}Bs*!?V1w`nPw?)3RJx6$UTp9WutB$jRXbhxyp!ytVS^3AA3VXk z`%&pOj(V}dGhl;m2dj3v?s+HKNy7#kggxZ5;JtgXeNK_-DSa8a3`dszPP? zwH;Y`1y9B!*-0{6R@+bXD&mppk?pI9RF`<2rRyqUwRNZG@YV(I{^wXPHc%}(7Wjp6 zSTeHv|3Z?TG#ji9!XHz?yZce;Hja9+L6WmUmhY=ZjkQ4)D$B3!eU<+&%XlO^NoLDx z`-!d%-j}|wy*8k_#Oo|wYlCX*PS4@33*PE5T)Ou;_<*m(HuWD`CdTnd#)*D;fwsvUkoLj#|@88~fXI`)K z^9^K{!&7$uUr4f(=7Y6C_@gR#cRwoK#!;`e!5;ZH7H10Gj#!;^-SbYelST|S2!GrJ z@9syX+c@gQ27Bgg@a}wHHENtGRH3r`+V-zprOS9EJ4t5CYWsoo zuKs|^|CeP9@_!Y{Y*}qT(Y3(==>hGv0o5g5XX#oSR9km?4sTuX?thL4whq=CBXFSg zEj+lzTCylNZac8hk<@8L?bRDc;b>In9y_sT9cemS2T`Xn^6bjBfjwKLxW(1(KaTM| zn7%R=vlS8$Sl$R6+B!^cJc>iDZ{cAr){;fJaoeGVj-*a2YOmfn3P+Jh6GwxQ*M6 zX|gBnxkmj^-L-KPjz)F1@0>sDNYmLmh&qppdMeq#o~=^c;%fIF$M_yhUqZ-ifdmBV zfWQUKi}c1LxxmWNi<+z@i*n<(3kn@comSLdy>S$dMs@D769d+frn7Yrbs8hju4Dsy zwn}k}tKEMb<9jfDWh`bZBp|T75jebcWU($kyj5;ADrt9(uv$-jxIK>4(T>b5B(7Lf zDLs-!=SKaJ%)a6wQ93O<>l}-H*`Kr}8;E~>N*do}M#Hn09%%kjM+pQbhCrh*mrJw_ zY0&Ld6}h3F$Sq6tNJb5!SL%qVxtv?kZrw3cUdfU-wB$`J`DK>;I+oi5*fEb(#@~FJ z8LyS(a@*dP-=0sotya6PX!<|8s_D;nHJ0}OWIY+>pS5RDQI3a~I;FgY6)&^=PqE~M zE9d>?ebeq_Oa4l(DaZ34d9{>VtB^q{uVl%;w#NHT*0&u_wCo>e`#dV`-e$@Fu#VT$ zmb}c8|7pqD3e;;mylPr<%aTVddDN1pSn`-9|Bd6f1FpdOw!ESxPqqA~Tl3$}%AXS~ z`F890uV5X|KUn&umYiDOH(Q>!QjTAH{99S$zsHzwBe^fP%)cardm$^Ozt>um6#bO# z`uk1o6hwc@cKtoCY}eoS%69#|uWZ-f|H^jF1C{NX52#)LGsmNOp|V}`LuEgj7b@*t z?V2|#`_cSS*{*q{vVYAdmG+ufD%&-`RQ98Jrm|i0O=UltcPiU8|5UbX9;$5Dd{o)4 zd8x8p^HXKJ=Bdhd%~zG}nzyK3|1*!f=C8_j&104QXg;fK*SuEQuKBI9UGrRJyXL#f zcFlX0?VA58+cghXwrf7DY}dS4*{=DqvR(6JWxM9f%6840)UN-T_-p>GY}Y(m*{=DN z+PRw!KGD2d*{=DuvR(6RWxM9v%684WmF=2;E88^>SGH^ZrFQ+##KG0B`B~e_dZ5uL z)>DPQQcqaxmH#yOTB$!+@?R|bzgqH>mi!-<|DP=RNS+5zNALHw{=eCh_3iPlWUaS$ z$u%-RrEK{Xmj9Qm`1@J^e{Es?fBOmk|F9kZVQYPM({u_@#{VgguWf%U>+@02ZXauY zcUtS64J`dW;;uLs%=@6FHJ+M-gck!k7w8*4py&Xio= z?(c9*exD^D!*V--EpK4qy?5So8UKC@@A)Hn{C0nrjhgbO@&#|{zm{cxxiy{*dH(JG zwzc$&Ed0l;c$-@B?y&5yxB9=#vcJvJf5__p9&7#|wd{|x=68xU{!dxsnQHkzYx%Ei z`9Ep-Z_VRxAOF8t`SEvayw6+nd6(7ycX&MQ{(fxvFSO3*HnF}>TjieZ!>7KKSIgsH z$nE~uwetTXR{Te-_4JuM{ONdE&tbB zd|Sxv@$X{IpRWOx__g@^-?pD?9q$)e^4gZX4$JKhZTUQ&f4l!TTF3J)%m4FMzT9oi zcUQ)%-QP5;zt>pyKeY0rklX&>vhe?=h5zbS|8KVX-_*jtklX$5XyHHK%D>FQ|IhsW zZ2LcL$ zEW8R?x>q|{crCE-YFcLcc(@yy#8Y0`B_W;yd{5u<#va*{3Q#o z+pX{4H!S>jvG94+!sBrZkCQF@x3~VkxyZuzEUUkzR)4Rz@J%gz3%QN&W){BtS@=9{ z{eO9mrGLVbms;{QEVuEsdwU)!!Sf@vdhbk3w#bcL(cu9Ae>_TKRssHNN*-@&_#WG?v@P z!8ATYi;w{I|8nyPNg@@h`3TGpzjjiZ%Z&t^VF%&3{#E{)OD0|Mu4W`L6JCeu*{z zdHnxb+kXd3o@vSJv)t~`mbbI;8R7Y~`+tiyzdu`e|G>(h+bq7@)$-rL!e?s>pF(cO zpKpz4fz{vc*7so}%l@sF{5H$~3hR2w->l=ifn~q5HNSUQ{oi2eSG4@MwdVg?YyP&J zUtZ~0&%M)%cbOG$9V^~;R=n3)@d~+(_t&ice#3aQ^JjCbzc*X`6>_`3-L3J=wEXw5 z^l!7)3v(@f%i{k%E&cP>_~)^{J)Rd>^1Chn4XyF*W!b;nlJ~achphbB$I^e=8s7sJ zzS~&w*R=30AzqdzXL3NE_USe zftG%CEB-;OZ_jrXOFqPsFShXgyM^zYto}E$@HOQ|I$I<6!uEJ=S*g3M_2kaR@4=1a zcRBI`zsPw|Jra@gezcLS`x@!Grk}_~M~%eNi!A!)OLXlK=}t977JatAuDz+8m&l?| zKA>y)PnV3B$c8@uX|O}DWzlC_>e`MS{TFgu|0+vg$Zb81uhYMf+xio9ZKsa@3t9B( zyYpHhs)op-Z_;=cmHr|d`j1$8EgSk%EWMW7`WNfkM?3U|+}6+0wbMHEg)I7Xi@a8d zdi;gl)*oo;3t99{!t0EV{tLOSr}=-PLtn^-{%lLHWkY|CrPp#>Psg)UU&w7eji)ny zAshNncJxnrEsH*-@vc$oMHYRF^wY&$HAEJDx>jB*M2&ADi@x9fu=Iu8*3Yu^h1}L}Xz2@C^!fN#w#Khz(WjJeYjup@l$Cl3 zf3L;9v3XuAM133zS@h}4bnQhQ{S~t4Gb^7(7JYtvX2|f0Q=%KKK8J<*#MY=k~KKe=UoCbQ4{By2HPa+j^S+GadRuHuTS0dM%4S zJwewt>WE*+qHnw@uN9&mS0RgjbSqtZuA~1#7X1_&&(G6BR1J|0{eM|{EgSk@Sb8ms zzA-be6`~$rA&WkbcaP<-Wkdf8dYa#_JM@Lz))OB0cIXRP^kZcI zuB;GMLu5n0yQSB%q2I&OYgzOwQ2(cudXYt+SnCauMW3&SI=>(E{nN6c-@447++NFu z{tcF1%WeG&b#0pteIbiJ*(k3SqF#3vvgk8woh!2Fll3kCLT>9fu=Iu8)~{#j3%RYg z{=ZAC|L+p({|{SkOv!taFHob98;v7$ds5=mZqNUF)4S{W|2YxWd>&^pF8v-#?zhlO zze;VFUpJ71ly-@y)TPFK6^)GkKj}PvgQzeR52MfxW?_}!HCZ6|!5 zD;=tNR{XUs{S(%B_Ok5%YUxk2=Kq{^o~kVS1y+CCSn@tB%ltB$&)p?ITe4DnSjY1- z)^)$HSn`jo`5tD)-`JYZ;g)^%@whiPfQp`}078eeAN_i}4| z_gL}x?FME4Pg?rNt^2b0iO1!6{v$=E=|6 zPHDIA@051?{!VGv{8Tw#`~FU`x9{(icKiNLX}9n1ly>|6PHETtSUDd1{!X#y`#U8M zl)BT(&kL>Z@BeG>J>aA$x~}o+o?Ws;0a1`3DuP4)rPR;dhXfcJ0X=-%CXPV($E%OmgOMrkIvd2#Ic4)$SdX5C0;2MlAXSPclOYU^kN=6mG@JIGJ+ zo|^{ZuPylpPyDAU`u-9g%khlV-cLGyg{N;!%$@v7k~6=GmNqAiUAXUMO*YQLi`tx{@ za3|+^_gZf~CJ1ABqMudWFE8PVJUg1lF4TAv?&Q0|{-QK_%oBNv;*Gf^6*?~d&|YtJ zo`~(@^AcpFpZZojC*#BMq&(^WY2z>9PEPS;#XOOx{Oewj@I;@^duageU&Os6S?_JmHBvc*8F*;Z7c3 zf8qj@bz#?k<8^7=zuS2u3CxW4K5u93^tzF7-%nI1`+3y&Bl*Qgm6Lc99>;6UTCYBi zC-upS^3hf86Q0OZwLJSE;fXx(?*oH`C-QKjZy$44&zL9c?xHNVQ|Nx|WSUn?+j%!G z$Cxr64?^l!2~Xlm(YQ-^A`jm3<4$-Y537jW%}>ewNqpY5N1~V5#d>(AL>^K-5}wGV-gVVJ;Z9EWshB5nsbAW2zJw?8RP>~-UYdWO<9)7ZCh;0` zBei?XV}HiR( zn4d`F3*A->o`r`N0*j2rE#_3FJAvh>Y4DwZy2p- zl+|*H8*`axI)ACC#64A?xG@XteSPfTn9s#D$+P25{sqaI+jUB{|BCcCS?>IOP4dko zXZ{Vzw~+m}#J?kb=EJDpZlHc!jh<@^lzyP?n5;t}k0?nBL)`-DZ}@7O_=Mwey@OO1 zB=uFEaF>^Z>gAUgvG{(=#dWW!XgNpNbrUDQnewri^hb;Sj^%Wq{H&q;tRw!O zl;it}>c@VDQ-4kB+sxKCjyrJo4QL0P)BGg)MR_>ys%fJALFxI9d2~|#qW$LSa_0My zyfN`6mRo1|e}9rUB{}nEByUdkEr_=yeda@Hp7?;;^HR{(gTD4>x=5Z_FIa zlLE}6H1CeF_iIl61ogjH?e#4#U$0YLXdeEV=G{Qz5@%AcXk91zW4n!ZevYL&zv4X3 zX+KToS6nx6Uh{XgcvZb*-u}=&cM)my-=R{1+Qr<-4(sFK4;emnK6`1>TCej~asi@B4( zVeMW1&Zd65n)>-h>gS&b_xoGKx>1~W(tXH1CERC3L9pFnJL#u5k2+}oOZq9s8P02e zt4j5cxvT%pQghY6n%bil#XVss_iaZ~eJk4g!?+wBU&yx?U(rtPfA-nQ{T`Q-P30ux z@NVzPyV9!%jxpc zBxfG)7q-Uuzbx5D>+k9Q%9B6l18jRae=Dfn*V8yXi^joX%HIQ|KaBjfp?s&nRsQmSoJ9*5V-;YTib0=>}^V+9WALc`-|9nRJF?aE7 zpz=So+?D?k$yBn5oMnRlT z`MitlPau9j>02(10B^~2C#(TmJy%Ya?dOhv>9t!B#_Ntw{()pj+hMKc@_+Q-9o9bP zJK7&($GP+O3h`&W@{M_&#?1=a?}qmU_|tgse!$~+AK-D^|9c$w{T|2tzQ=K&?{VDU zdmQ)m9>@K>$8jI;aooRqyszZnZ>NZLCA$k~zPyC^^O8}`L;O8MF3<7z3^{%e>Brwg z;^cc!zo<;@6n{^N)2~hQWz3!YLi*mum^=AL@+vKU>IZ{``+15o$$2V6cAt202ccb$ z)a!xe?tNz*Poif`{JwLC^YQ!69nQz^J9juAzwg}PeEhz1hx76K&K=I9KjPeu@uOds zcs_pLxr3khediA6=??Jpa@jAro5^q3!FX9b}?@fGP;>X*(xp;??{35zvdW7m}UZpV&!%$9RFg1S2KPrS<+*bRFwP?--mc3;`TF-{2fd3<4DfDAIbZZ z{Q%+vNuT-Sq<<&z$#j2ml#FK`r>|4~V(#*{!p_$**YyIN$2lp?_3J1pIn+K2>~+HB zYnUzH@%VGYuDmn+>qESc+L!`bzdMKO8FT0NT#_?CkL2eQpKiJHH-qFCkevBUl3z&n z7ZJah^qId(`qLybIf+*~uWHynb!92XSu6q%w2mNPjcpc$Y0EzzrG}Ael*FC zA%3jo&R>7x14w@$$v>yOO%P9_B(J(s-gE6d9G9p4eTzKbQ#)|{?Kt0~|3XRi%J}`6 z_pQa{7;~jvFH6dmeT@-0ipEpHPOitl$@tKCK8ZuX^#HG2KZ&3J7=!CViRW>BDDgb5 z6D6L<^`gY{xNekq9@mc&&*M5$;(1(8N<5G2N{Q!jeJSxgt}`W`$Mq&U4@7^-^Dtv@ z-6`=ru0JK7$8{(=Z{4Jg$GH9C^Y|Stzn$IlWAqc)>$p5p`VCISe;uhG$2<|6&Ln4k z1j&yiew5|TUr&Cgv{Q>Lh3G?>oeIfRX<0mOFpU_aJ#~vadsYPtuRMoQ(<@D)X#V5=^hB zxitSC>W^PHPqW?;RxkFi*O4=+zg}*~xr?KwjnnbnEO&W$huUo#@o#9I4&_DlarWEE z|Ig%~`8v{%x%0Q4hU&#Njq#scHS(ZEdn2S|(a=1uzp8THnt=~@mCwTP_!e~DW zemcqdYwG#iQU3W(uJdR&_)tHe(!R0{6vxNJ?e*D(VY*Nro~Qfv_T>K@dY}G|H-BNj zHSG)d)jmgX1>Q%`g>EDNlSuz$>Q~DtzC9_PtEgQrpm;_RKaKLUmh2mP?PSbBl&{$o zZ(my1*+lj+m$T7-Uz42qW|DtHJpSCEoQ?kbmgL`AF8@dWG2cq^?=5%j^#k!ANk8UJ z|71IFiB|OAJ(REgY29Ey>(ANurT!qx3TgfQL~5^9WZ#VX!*puTFR8!ImhyJIzGM8N zq-2~0sS#kk9FKptDvgI!Zbh%&K^R{bBwF}Q4TirC&YpSnnepf^DIfRE#P=kA9MyAo zlDDRQ|CQyU75#UU7q8<^ely9L-%9e^iO;p%`I|@b`6Oq4H_7iK`vt@ol0Ng(sGnX> z_9uDkwL$O`BFC*8S}pq9frslMIbY@Bd!iYu<9sX2;}ecscaZzz$Z;o+$EmX?9{T&V zgJ7FjYP>Ob{&{n6aj1_!k2vo9`}0Z=#N5e$q4Irh%zx-Q zu+Y;-EHobOrR&bAUi`+e|4T_;h4{nNUlve#9cVu2N%Ptp6z?4J|0wyth2)E99(#_) zcPp}gmh5jO{vi1~hy1M}`4sYh3h}AL*OI@ARDNa3*HkL6Dfz2P@=D}yHpvH({VmiU z?^$`$|5DNYS{)tF#PNLxzJBnV*Pa3K=(~s`1vfxU9>wz%)&G6+A6<>q9)3J-Oa=0{ znCf>v<>LvmuSW98#QpgK-v>bby_m{hPW~S!f0amox2Sq)`SIr)e0MbIUq<|L;uGn< z>`;ogEXkjwcxTgmv5x#7K>QT4e~HRFhsv|-0oos~B!BVsL%c?rxt;R&K9yI6?59RX zY5A;A`fpSJxR~S(i0?(b9{E3z%gUAGyX>j_Zp6D2|CHiyO!HqiYR{L6UqkJ=g!m;?-e*+a)#UF(;@?w$ zY)AcJ2>G9Cd6KW-SFgN)xG}@XelfN8=bk;@Uz7fsG#^eQ`C&9ZFR}GY;!EX2AK&LJ zR%pkBJNfCJzaSNJC->iH1gV%i`3bP!ML#c?ig_Xr$)0)eqF;XS8h9l;sl!J=a$~mI z=dX$Xtf+q7w0;Rs?SL z_Az&IfB#+(#N5d{lYPvc+~4mP1TlB=u4Er`C-=vD5D?FL0rt7tUI`bkXuoWdCp?jt ziR5YRo$y2+{zqQL6!Tlmo!noq3PQ_6l1snAIp-(v=dB>&uHODU76dVO@}tC+8&^Th zoxBIhWA5ZVNgi`2?@jWUJGuYdF9`hSenH?r=X2cI`_KJ?Am)iY74_5fd4qU(73A2e zBvD32hueJ*jz3H9OOB-VtM;^Sxf01I(7NyUcHfNi{{!)va)MAPmqe{*;n*?g~Nz%(eF_f{%yEpKb!8Ymly+%zocC2ceVPJa+|9>D~jV7 z$Bp^K&hHX^^dIxP?R*F;`xo`y28 zM6cfj!5LDMBwu(gK=#j2yp3d?U-cVOJncRI_?(XAaejheo>!jZE`K*tzdDuHOWv{d zarzsGe?xpf@;8RA-}}=2$I;&XNg(~BAgzC#N&3A!eSFs%-EXZS{rgG(4eD>Vdie~( zJ8iyPeZTkmlasstc&;}O1ldvlzBw)aTK0a(`71~5eUR5)#w?+HKH!ya%wtyW%0Gkd zpI-OwzwEegkrvNbisw6O@5Nb$bVzoKU_X4 zdFA2z!)e|-iN?by;$w)9B|eULA@PaC2U5HRUVjdPSN(h>JjqA6&6g+K$>Z_w>R-|K zpYrF2AhpK#M;z+`zI|}7)sM@=`ZDFay00(et*^GX@ROBGf1d5QF=M^{XZu%EC%64! zXxe^<58_B*hgYs&iQljerK0iJGVT67 z9^c|6YJ`WRCDh*$-h5!p``-ADu3gce>eKH>gtIBW>!^P%Bl}}L9)#bEy&HRqXuQ_Z`%oFbSLyf-?~^zZe?fRZ z@kN%${(~^)au#vOymOt4$Ie#+l$UzU_m{c}{2jfYmH9DG^~K+9%Cl(x7WsUY3tyGS zsXURtktUDw@tJZde);zW$^<+~@n(q2PKcKamIFbsjh7 z2d|$QGnnT2!|A@GgU5sLTF+mQ^2d9Sy3v=1@pX#wq4C}3=}Y~f>*Rqix7V@b((>eg zuFK}NrP_xJJpb1IBDI%(be!r-J6x{vV5Qh=JJ@vx$vY%2PU){#D;GbF6ESMEg6^lP zdhHODiTZaF8eb=QtT6xz{d7b?7B;JM^uaw_I%NKr&6tFv+hac`cI9CV4}W z-%0W|B%e$2wj{rsvfu)F?s&`%ittP%V>Yde%SLHgrS6@el5puBzk^>;5^R` zziVadC1<0~Gs4T0F@@AGx!f&cspVR34Axg5(R$DI{06BN6bIsr@)*Yv1WP@65H2Bp zuE(*zhVBEm3D>xic@^hj>B>nh^ZW!U-)|85apLzNL|^?{F6F2DmHB0amQyyGe}B>W zw~XHoL0RI`A5W$JcrNjam51L_T$bZEL}fp_tFQRoTkV8jLHt1C*Au_Z@o23xz1{G> z(C;s@F4@ZE!I*LM+$@j!Uq^481zE>PyIX5G zv*6;d3Hf`5`0L8UGyS{=$AaS{mGnD{#+>5S)0Wf5`N4Si@)CqweZMis_tg6B8Tg;C z46c{xVQPR#bE_%6k zGNv4@CzkQ<@T_NV-)~+MP3`gDTXx+d zp{9y=eX#e#wRAp~`@dVXzQX4zm;2|vNdI1yi~d8zA0_?_@&70n|NE2w*V5{#{<@af=cTm$ zT9Ez>TVLnzbIQkYw7y@L?5B~uJIUvfd;|G^gXG_mJln5Nc03MUyydC91AP6gxPLqS z#-yL`>xce04#GS9@gVt}?b;(qJ>$z|eAP}HU(x-^aK~{yqV^l+jc510urA(R?D%(l zydBRm55mv<@?-AiotWcy8NGF`Ae+{CQpMJfD`$>(UB$CjFU}yi%q!QJm%Mof&sF_# z6s+>}?L0A7^C)>c!sW?czaCL8^KC7iZ{>P-w2mvWKS%Y2k5n%9_0?YF(@DO!%EkZj z>R;^lBl$3rw;=gwlDAR0l>da5FXc^8eUV>C^2sU}{Zo}oeC^b~@J`Cb-_z<(cq`?i z-&OU6ALY0)XLI+{;{6XSRDi{B6sej>x#6Kc_opLGfKk85TYs$snA*BD7%2OBl z^-1~r0&RXiO4FZ3`j`7$%A2j_3GeARo~xD6K7E`#NZk&9ecbplW~sd{NGa%#^8Tus zliT(^R_&#{{gUnry{cmA=G~aP-;s&^;(eXBAHw>*Mg2;@{48x=^ygWte}d|llk1E2 zW4S-MO5+xP->N^keq}2c{hL%@+O?W%2V;u8ac}4C-PAse)=&0Td+}de<>LPik~dJf z7yY*!H)f?bZ`k|i z_nh4Fb;_muR_b5sJC*ADvFb~CUnvi>z5TY<|2HZZ{jJKSKm4raiTr1k3(wZ_CBDN{ zU*cP+a?vlVT;$V~i+y|fb%^NJ!oCl}G5(#Up_ZZ2+4C)9$xADlX3B*%BB1Z)IPNPyxsVZxy&o@@_*D{lJ#8NKd1YV`c!iD!8(}TKjrRY3%vDSd@lj- z@3GwJ-(u%G$Cnbnl=wBoFQ)xT-%~tyk^U3JpCbEqvOmoAEBASN-q%sjzK?Nn5A^nt z1>q!Qtx?+h-gjwV+jA7>X%yEv#79t^8;NIm{)2G2v}D|zh_a9PbM*@C=PG3VBfWj& z^V;9y_e0Ln5_>&$^}d73wV$8YaxBO9DPVJK+PF+TDIT>P$nmFkcAk~@HIbbw?@G$c z9Lt@;a({e;Yek}dEjQ*QajNC-LVh5}pL1)f(7wS{UOD)_Kzd&rzyES^-$ZdQq4IL6 zKgB!_ASe~Te{}w)k-u4M!>bf1mudCix+jC-H=F`?+`~dF5kYp1m$R z`MKo(GUAUCKZf>U_VKRsct1q`A13?Ik5}fcxoPv(4c>Ug9!!thdHy__mw$5Hn1vKy zV~^YU^%=N{UcK)sX^UfZ>`%}XEzZad{>c33H|AsCUi{Z} z{_XSs{_cJZdy{;9@!!|^$M@<|zuQLr@<{)Equ7sf_O^ZNy7=rkeo^J3|FUwa&t9be zs*~gQ{Jj2y`g;4PZF&1Rdt=@u{aY#i+dOXLyE3i356J#T;;a1fCEpD+-@#KdqWp2S zx5}mdZ={v?ruV!f2!_MHoNKQj`vA`$o~z4@?)(QMAjhLT(Zcmo{P$1u|Ail~tfQSs z`bVbem-6lxZU1dd@eg$Rw!CYUi~oG}FYUX(YaiQQ%^b%ahj(4E<+alCf*D@@t$j;p zZ_9sM%a{5OQZDhFr16M+u*xOA1J$2gr+!r~^45+UL(iYY-}~xM-XC78;{UX(u`0%5fNqdX`w(4KXzk&2islND|Lh`aI7k{5Sj(yDjc#-mV zadO)phq?UN_W0P<$G*R-tomYKjd%^^lJCRSpYRUKC10Paf8jSMm-^pI_1oR~H>RI= zA8F&OWlq-%EfhYD(?Rk`G)x#mUmUsQeJFFS6`Ufy*Lztc^8YYFR^ zL)E|3yO-8mcpt~{yEc^9IsUj3{bQWIUDtZu#b@i+RO=_>sDZj!U^es$BRs$Fcv-yZ^B5^ox^Q4l2DXx;6OJyU)kx&-{8y+}S!GNM7zw zvwzalH|96bpDnL+n*Q#7zZ3sIXkH|b1(e5f&OQife@OVb)I{e4%Vi!)&!hMqrGBLz zhpJy`k9HbI$n)AbZ+zS9*ckOE_Bm=V**_QG#id;K&J|9Q^8<-;5|=2*XL8c@qCPXKxIBuZhGvF0K6Uz5Zm(YhFB9Z!Dp{6VmLj@XMF_Ug6@i^_iR&&l}|b zP2a!7e}>by?KLH>yd1AQJpb|Raor&Q<2=zHPV+DMJ6r8V zzD(soG%rW{Pvz|<{yW2epDOm#ojvv!mJr{}GuDy*p z#Pg5uC-As!uQSNsUFuK#-$VR<5urXEdPE`%6~}x z34d65IMcJY`FcX-65j|{zA@+d^%sBNJGsrrS&kc1gU0pczPPr35(jLxr* z^oKylliUv@9a4*EE*c{flJY~n`v7BhxAUfGMgNty{v8j!`!ZZtym?68cS2YF$KTH% zmmkF6A8HJ~M;7N)FN@-sDerUjK6Y#Dp~!n*Ys^*N`(a}~^yY12I*|M^Z@tWzQgod- z+q-Wt<_og_lK6|H|2X+SLHuhylFy0a`A<}Tm)D1F{T*-QT`w@^EO+t;C|`A`A5|ef zo%F9F{uNzMJCgi5;@4a5;@QpS#qrh@e;bOwKIL&guODOI6Y;X7-;3JqS8v>)e^GtT zAo+H(|B>WBS?=o7iR#;x>er3xH;nRiI^`#z_9>?NRVVwpRG+mp?sld7w;p7lOMET8 z-`YUWA1B)QT>S@9eNUkJenj?1k$e)>cLBxoH1QtP{%gH;U1P2$f7cOjLHX)Q@>w)a zvuGUOLHhGN9)tsA=<576%I4qYtD0>e$H!9s#(O+S)gga-i>1yF4XC}hQvF`=;=}%1 zuYTCYK%Yyr+?aE``#0S8lAqtG9YTtuJ;iYo>6a$`GL)BRYmmzFdzKOo#Nu zApLp~g!a7V|6J;CPg6Y#DUOFJKO0caCTy&-fdrxD^1b*tr{(04pH{Y=Vmo|Sws(Jv z&*4)XZxQcB`I|}dhlnpBo~4qWV5X(lP|9npJ$z(s3_)MzL*VI1K zNdFAtuTuOgM6ToNqj+2$BsYyozY9WpKH>OYAM#t1`r$gDVf0y)eeZpT-zo0blBRk)l|AO#S303oEIew$2 zV*2$1?}MnEb#y=UAF9V$G=5L=t{=vHL*u2E_}4f##VH&v?WgCzj?a&wcD3h|dK$w^e{Lyz zKO$Dpi#gWJ@L^ZA!#X&XTZ_t>L2+C_yd~*>>G=x+T&M7-?eTFOBCe}xaRi|~pVS8? zUj6WU?$nR>7OsAi{m9q{nC2Ish4Acxz`w5y!i^N4A{viC7;Sup*U#;`Sp#>SvixY`FDaMu4p)DYpWzz6@K(eR zP%icz)LwW;-_IIeVd7- zh3X6cQn~0K;`H(SwuF3dQhl-iTDjyeSGmYHD;NK#I{&u)wy0d}`zV+8yII>$QCfnt6b{WPvxQ?>T?R=DdJhm#oxK= zPxMQvTzF~a68~zAU-&D^MZb*G$8(Dk`eRuqx7VBQYA^NaPxUEJ`jb>&;-60OS5$q8 zr;>8fpP~A~+bS3RDylE>40Q1rGsXWrkI0XAa@+n@)n5EnQ!e>huknlhAhO?;^bc2k z@mE9T!fPs*`n0F|?51+jucch{XOjLNDi{6Q#Oo**`y8_0ljIkYydKFfR=MOOU-KdP z`jG0sm)c8w4IRh#zDHz$8k$oeTOT5E0Ua{Yg z`(e9t6a((r{#%$Q`HyV zjCgb6Er_>NF7b@f^2FZ(Dwpy%Quzm}T=Wkjez0=sf0t4F9inovZ$tc0;)f|u6`?)$ zq4sX4a*21c#w+D_(ei~~sa(p>arXG0;}ZH~2Pe1v@hY{K{1sCEI;p<+?@as%;$4(W z`~x(8u|JaJCzHIJ%0<6B@uQSWyyG=qDen{V*MsyYs=nA4DVOqklKv!>i~eNglK*Qo ze`4QT?S<)`5x&w z?gzZ*t5$xplUqKT_!#12l}mlj(E12Jllb1sr9OpfFMK@l3B)HV7yrfNuSn(MZ<2D! z=k1iwDJmEJQ;1I`ek$?Ph@Vb;nsOQZDg#*Z76cCw{kbiT8Mo zSM={yx$ygxOTNybd@UgPxhfa`^VPrXqq?5vx4Ts?Wlqi<#Ih8tX%5%3fV7Jx!6CfT=W~NzVJ25MgMWq-;?A|s$BG+QZD}9 zRDG%Mn_6Gde^&K{Kc`$iA9av&@%N7U6aFso_mqpjm(*U$KU2#WeyMWNU#uRWAA;Dwp!#RR0p+0~(*`Z&ZD0{~@X`@=sJQ z{@zu&_$wxVpOO9tsxS6ym5cr7YA^DSR4(OzuKt97LHtYQlAjATKjQCm^(XvG<)VL) z>WlwP&Yv;I`}aR$zgg`?|7)jj$Md%;7ya*)i~eTS7rvG1|C8!Vej1T{yUNA?uf%^- zF7|n351RBhu}3%wmw0|qE^=Hh6S??XLVT%m$>$}SPvMs;7k_0`U&`A?e7kbdFHgLJ za`8XQ`8Q^cKfg-6XRE&S?@^i`DgPIh3-7J%BmOUU{_Xh8Rk`@TQSC+lD$@T|<)S}Y zx#(Z5`XYZ=Jr&esnPC*GcTj?cwk(=>k_ ze7Tf=JC#2mP5;mm^zTr8vA>h}JmPl|Z>>BPtsm~D`Iq+TtX%rf8Lt1}cRaoM82j+O z{nYmT_}%JX>R(RlBmSRM{~|x0lo0=+>QC%{Q+?rv;QGmgo>~7yHs`FT9L$ zv44*A%c)%S%M-7lTbd@bl3J5c{7!Zzlv%v{1N3+|C(BV;kzjp{VJ-TnuPL> z((*)JRpnCt3snB2Di{4-i8mtt81d@L#eZw^Uz6k~IXS*(riA(Eai?$0W^X@^9bc=Q zy}f_D(bX6Gq`dKO%n7tVbU5w1EKB>)26^KP*E;g|v$sBn^*)k+;g65-7Wlh7Exw<; z{T0UCNA@?6|F39YXeC2q8S zsr<@R-|b#|;&<36-&-l39^}6|mEVx^RfWoHPvv!@d~foezZ!EX$rn(0T}j@TcwK6* zgFShWx*GM(P3sTsDE?{GU$d$F3Y4!0sC_Q+`~|^Tq@PRqIFRh`q0V_o8jZLGt4%-z!N!{#|sbWfa;O-uMW@==#9uluNe zH&A|R(tP>@$qmiVtBJo&{u@#M`Ih?M7oPthc#h(Ig8J{H zt48we)Lv&$`;VsbcJbzeAQiP&MR&i0-#?)C8Bg}jym*5$XHY(-cyjC;r}|GO|Az8? z2-&Zv`hH2{X9?Lq=k-TpT2XvCUVGwmeWZUg<+~#FkN2oPx0C#7J04}!M*Dcqrt(Ko z{XU`kU1H_2JwA6w@ecCZ55Fr)?QK6F@7@oViu!A%wDCBR;vYoqQI6)TW;DM%N%7oI z@@~{VM^OFqDE=kh^(P32lKu$t7f}APsr?V~{NdRm=~wjX8-#mOd3jX-!IZBmkka|2UiSF^T4*kob#| zPdDA~@CJD_PGa1NaAd`Vi z29SX=JH0NH-l-&$xJ(8z8OUTHlYvYIG8xEZAd`Vi1~M7=Z_U8(tuOtz)+rNrCIgua zWHOM+Kqdp33}iBp$v`FpnG9qykjX$M1DOnDGLXqYCIguaWHRvAGf*zGE8?#wEn|_% zKqdp33}iBp$v`FpnG9qykjX$M1DOnDGLXqYCIguaWHOM+Kqdp33}iBp$v`FpnG9qy zkjX$M1DOnDGLXqYCIguaWHOM+Kqdp33}iBp$v`FpnG9qykjX$M1DOnDGLXqYCIgua zWHOM+Kqdp33}iBp$v`FpnG9qykjX$M1DOnDGO$Ai>YKg7y-m$eF)hO5 z%?H6Cvo<)rPfZQ7^C0lB73st`EZd=^dwjxkMAML<8ZOKJ)* zz-$bs0u52)2pxcdKwgY|98U%2$9NFO2oJ|tj^i7^Tfq0gkHC}otp7^j6<{6k5%6V< zO*lp<#IH>j0h56#z^TAA;LI53;}~HEFcY{a#w9r30^9~{1%3d|!Y?__1e)U)Nm~NP z0Rv(T#&HI)8u%Re8rTBV!>ZLq%mo(4cmc=Hf$xB=z_u6$zxr4m*gZx=93wP}k%MD@U@$NWCgfUAM)frY?g;1S@l7|U^72?Y36%oac^-~b>8=mMMtoDG~C<9r-v0v7?d0dr&A ziQ@ub5wI9|EXHyiqhGjR8RI=1*8=!SWI+y&U4d@EXkZ3#5n%AEoQ;9@F>-M{78nQ& z0`g-N;5Zx@3lsvAfU|&0V$8wu8Q|F%t8k348rTN>3>=AH*zOMW1ag7nfc`NC;y4Hx z49oy#0v7|bfCa!J;6Y$1@HntM##1;x13U-30lWoN#xK)W1*!wP0Rw?z;8I`?uod_b z_yvf5WqEWB%!$C6z*)fcz#QOn;2Ypaz|=IR3Q!kl3FH8MfWg3MU@TAw6a$NaH)Fhq zV}yFU8FLCy44ey02j&6uV=TaND`09FvnP-Xi~$OPBA^(!8(085518GJsR7gjjsfnB zk-Z1{6>tR512_km1KbDP4?GNf44B%+>;?1$dIJN2X+SYB6PN`&3_J!r0el9032Xws z1-1g;1KVPlI?w~mp2&M$dKq z@fc6xxB^%Sya=oY)&Oq+?*i+9FM%z0UE~G2geAFVl>9FDbO5f1GEL&14jVefL<}q!SP(c?2r2c;0s_Aum$)QFinlw z8`w8SQye3-07d}gVie=wq90$KtG0fzx?feygcz--`V;1*yT@H6lmklhmYKuh2fU=HvEuo?IbFb9J7#IYCV zncGo5@C#t(VxGMNV-%-F|Y;r0oWen7aV^D%H4(b09pWDfWg4&z`4L8 z;N=+WaQq0^2z(7}1AYaf8^}gL4$u+k3>*av1||ci#yA7V`+nn>U>Wcjusp_7 zI7WCEcpq2?d=6{@z5{~0(T+e_pdwHOr~%Xi_5m6J&43obK;Q&mBv1%!0L(qO&b*0! z1gr%918fJ(Pnd_cK@WHvFxycMPz|UF)QM3S$3{S7;9%eope=BCj2s+00G)u&Ko?*k zum))N3+4sjQs8pnSzt4;9Vq-2^B*u7_!+4G8?MVh2VfvD9C#df3V0TH0eBgB6?hYP z2Y3%ahD>>27hoTt5pXEb7H9{w2YLdzz#yO)*cKhbz}yJT0agPh6_~m}Qy>TE2y_E- zfk{9yFdLWyJPkYtybPEuoCg*FYk;?a?SRP+%)USiU?@-soC=%{%mgk1E(fjzt^%$B zZUJrs76OZbWxylAqrh_DTfmeG%)zA*BXBG*7#IN*1LpzLfd#-K;9q9tWNPOgW3nI93Cy z12utKz(K%Z;B=rExDi+mJPSMzd<2;C&;xRSV}ZfI1fUqW3@{Y}b0km|i#W)AY`+?QKr$DL-`XSIcMpqmo~2vW$5z0hF>-N?Z~|}vFgwNq9Df9s z?}0uAnA#YVKslfpkP~A9j+X+a4&nyN0A+#lKntKtjKMe-03(2tfKk8&z_l^f?TK*# zgmo>laI6ee1r7if#4z;&bKPEOkA{Kiv^Uzbd0;jJrUmkHAaVh80R{uxI^le0@Gdy! z2c`~SPQpAg3h@Ic0)@ciz-r(tz?=*}Kn~Ce7z#`QrU91%Ib#Ad8ps(Nm@@%04*dkk zjd2BzHv{W{^}vTQOkrStm=66JfqDHRv@=lVV#Izw=1E{HupRgX_!Te<0@Gk2+A2ma zj(ve+V+_M_1W*WUUj+R}kyD@$I2|YkW&pE*>j3jwV2%Nf18xLv0&WIwjWHL;JAk`@ zdw~0ZWxyjb9>eiz;29wM^}v({$^p9oy8<41P%sz0lC0fpb(e=%mn5E^MR*;6~KQ0Ec2N?fxUso zK#O&O83SPX(CiPi2HF9=V$9kQn0tZcz!$*kk8lK5e~f+sY>u(+lfY~QJ_Wu2z5+G@ zn}J^e^C@Bg%xCC7z)>;GCd{=!Hc%I+4>SN8#@H9f2>Su8fCGWnK${qc;TWM~jIKCF z=oaHB93%7udINoczQ8dt`r#O1K#b#Yj4&uh9*z<6fg!-K7$a~T1&jtJ07bwQU@CAr za7K(`94`Pa1a1Is0d5240(Sv-1CIcBmt)r6frZFBL(^tSXmWr$OG8r+xaFnLECAMh z5t_}wplHGJN65F~Xi}zowG`&~l(~N|EI!76^~}1Uz8P$iHR5P}I9VG`Ul(p`e!_b2 zM_3Qu8bs^C(OPh{4jiokCu_NpOZ8U+YtEHry}7X|A2u&x5VFW($) zzEAVFYrL*p&G}@1f9$JX9NVslP5taxUmIV#zvhPHsu!MUte?c*uBThueN7JTKi9|W z>9&q`Jw2-De}c%LuBS)!9TL~q#%R~lwa&>}da`DoM#loj;7+v&NMebO^-Tk; z>uVfQp8XiQn`k{hCvE*cTD$+VWu^PqHjL`#`;DFfBysZ^KgZwCR7y<&Z2a2y_B9>; z!t;r!KSs|dY=2CzA3vW+^2p_B+x^kAkUw7*kEP#x)>6`#N}jJo73t`9G15-iR@Y)B4kUA$vXGdxhxP`_Aqa?7db=_X$eYyQdjlQ}Fs-oHL~?fiXC(r5oI|0VUu^!Rr^ zw*8o+_mDgXCb4th;r##e<@tT--zqP?UOQ`_|4IHz%Gu^8Bacsf5V=oh}V@CG`Ne*{r-`4zq*tZ19 zI#XnmjNQaGI${kATR>LH`dCzE2eTBboJ&nd^CDLNUNl|I*=9Jye5~d!A1TOACXPE zZlaTv9Uar#CK`*{j%TAC&rY>5$D)qagW*6=(>@pj^fKd7$ML3*nIDV?`kA$63NXNY zjk}$Y22lhE>_IJbnZrE>t{RY^71N(10`_5*D83uGQmEof@e6)p+ zwm~0r7i{l>?Yppj7q**VyUBDm*Fpa}=NvFZAz){uj{y0{Y)V|6AzQ zgkDYPb%0(6=-mUod!Y9r^ge{%7U*qpF*QJc*c*uYMMt0u&k!%s z`!|4rKwgY|98U$Xl|}IXw|&=xOJTna@Mrd4|CN2$%S->?-FH2_EFQ%I|JMHNjqv?% z?7tpf4siqj^gis3@cA|HPw&SbULNrR|MtG@jVR-5;P39w9$o?Q0{_%L?TzsDHSl-$ zYY*QAaRGmI-}Xk>d=2bu|8_3+S`PsJ>3!U*;qz^P_jA|7-tGN>9N>@kb$6?b{dK_q zWMB6z*j)!?_IG11VomgCprrlX>u~-vpfdJw*8=|Pe(x^W)BStQ{f#>dl{t2Y-2T$Jzo`Zed-GFF6cxE4XW*_+f$$jAeH}`+9#$NBYft~FG zH+TKa_knM|8}}~2f6IRG%Gldo3;1u}7d|Ho`?Y|~ z{_y`D`@>scPk0+32lzMli4VtK@NvK&?HAt+ou7bY-}u2*uooHltNX`S!zS88{!i~8 z-;6!vKm9M38;_=hj9Xz@OcZo{N3w1Asr;mp%tNcL9I2KRvfD z`~m;eKJ^y)XfJ^Gs}IH=^^ribZ+$slKM(9||9UR=tPcQowvWAV4EFK@|84u(H@}Gf z0Q|qUul*(LZU5~r>~GImk3HhR&i1))-hey;$$t0E*z^7q?R(#bz3>0ieeb#0|2_c7 z?0>iW-#2eZet~~#AAB=2H!2+O%xd`7!a#5Iz*M&f5b8D&#Fbo(Dv@y3} zpK}$wu9E6$4o-~$dYQY!u|OYlUTQqh&wLk70S1_@_>PjT?%5K8#+v!9u&)aHs<3Yj z`_^gp=fnPd*#7|gA7K9z?0@p?JDUf?VL%sC5k4xyM|1dSp6X-Hh3&bp-3;5!u>BUc z--eyd3h1wZel_SHg*F*XB zQGR{+Zvg)daDE@0-v@E-i#Yd%zee!a2<7gFa`!X+O=EKkkoLdV@^A?9a0u$# z2K8-&=RSwxxzC}dxs9a;pRwMLJ_BM$dut!j0wv*HQu zWm)oZaI~f|#V1D^c)$F7mT7VBuBNa@4YS~w8YZW5wwcu++qAeg+YG)b+njo9w%L4D zbyJLE^cRiX2*3BYxn3!=;wbAs(!-+>Gh=8eGY6=QazpD%T;v{K$}G$+WnRJYWngWu zQs#W3d=+Q>K3@^T5DT=8Jx%%;e}CbjuxA%1njM6ySB}l<)o5umU!30V{!5 zfR}*hf!BbifmOhn@Vy)Auney!;`LZy5-<`d25LdJ3h|ze*Kb1SG2l_)a>V&Cj_(2I zLbfaPCg3;*cpa}##<3OZSPREKh`SKShf%+^$D$0>uN8QG`1lBX59rqbKEdnD29z@I zz~>jJ|9#L8p>q%LJ^0JesRJ|u?}p=S9G`;k4Jc;`Y`%m2Gtip}{|%AP0GNi?HF5k7 zx*r3Zkkgf@PZQub_&*=V&vC2-o&J!0)U%X%0_WD@^$mD^5^VYdlYmE2P6{Xo`Eryu z633qr@8vkx59O{xSx*3O!|qk!3g}!isFb<+1k?e?1;AvSD+KcKdKz+&jdGfThd^au zU*IgrI>6>WynYC;7o(iM;MEXAA^0!AK=4tJ&w^|^&Yz1q3_~3Ck(Xvb7x*0sy|?lD zTIl5fvw^E|?sM1_))*84Ty05|a2f#gey#fAq#qn&E zbq%lvuSYZ_*# zGZD|#kX;OX3;SPy6kb1v^REJr1D^m}fcJnYkc|SK1s(?O1sdY~?m%VWXYfyf*MMB` z_CPaW4f1p+jw^7y7j3sOY7g{<3sB#|cs(9C4efL!unl#8E$X9v(bmV5GG(EYAR5O_ zV8`S5Dd;3)xyI3G7homq>%q@r9B&1V#OqP$$8X_v3-~PnzD92E#rat%zdLw6@I8P= z(5Z;yARMcq%(D=|GWS?KjZb`IMxG>1`2_uz^Cx> z4)6_PZv_m+xpRQ3Kw02N$a?iby>NUG{pM@__W}!{_j}{- zTIdf%ypJN*zcUuQ!$&9hI2iq+DPAuGx}ogT;lCWt7bBKa5$AO9c8GO8&eg#2E1bUz zy7%M!0KBdbo6Dg$7JgRZ_$jarI0gAT7H9+X2L{1@1ddlDpG7#X0>1-#hrm}WynYqF zQt+S51&6`!wK#VI${7utmyz4=aJ&}hJD{vR@p=>NR=|D~+N>G!+7YOL^Et4Yh4y?L zd0h$FdwBgFa02>HB^;}w{Ey*pH1rO_xy$jo3hV{|jUamjJRdj({4Cfv$MG)M4aDm{ zIR6FWT!7;fIR7h-Zv#b$44+rx+{ZXB z1&U#N3XT^7Re{IBUxw~+IL-#Xgzn2YKNxroydLlgBNymMFkU@ z<`)*6(rilp#4*7L*yZI#FY|`xj~<;jv}oLfiNS91sr&q)HV{%o|;BN>+u51x0y7$Biw@A31hnb|rf@@8p81Q^rjgHnDW`l&O@L zH?b&x=*fA7<3^4}7{M-id1DI3jGHhuZ%F>cg0MnfUQzy#(FMZFmcb{yn?*&NGs_lE z7&mOv&;mqO0WXIZOq^IStm%-cLH5wm`C~`qwQAX{WwQgDq81~YP8@b}y+$V$6%|fA zw0ZLpBa2R&G^E+kabuc~9zEIq*AyN`6$~w^*Q!;k;X_-t9NuckA;Vi8H2mQF7Q+v0 z)B506ty>igZ#iU0>mi^AwQ4zRKXYYJsVINK2-I(QL4MJs2?Z0&G$}u1(&&?$+VGoH zN+V6j6&5wA5hb(f$g#slPC!vj$4xGnFnZkB5lzaCnKZg+4M9Ol(qS;>ZzWn--i> G^#1`Y)E}Dw literal 0 HcmV?d00001 diff --git a/src/resolution/frameworks/index.ts b/src/resolution/frameworks/index.ts index 88bf205e6..2a2100bcf 100644 --- a/src/resolution/frameworks/index.ts +++ b/src/resolution/frameworks/index.ts @@ -25,6 +25,7 @@ import { swiftObjcBridgeResolver } from './swift-objc'; import { reactNativeBridgeResolver } from './react-native'; import { expoModulesResolver } from './expo-modules'; import { fabricViewResolver } from './fabric'; +import { salesforceResolver } from './salesforce'; /** * All registered framework resolvers @@ -66,6 +67,8 @@ const FRAMEWORK_RESOLVERS: FrameworkResolver[] = [ expoModulesResolver, // React Native Fabric / Codegen view components — TS spec → component nodes fabricViewResolver, + // Salesforce — LWC/Aura JS → Apex method (@salesforce/apex import scheme) + salesforceResolver, ]; /** @@ -140,3 +143,4 @@ export { swiftObjcBridgeResolver } from './swift-objc'; export { reactNativeBridgeResolver } from './react-native'; export { expoModulesResolver } from './expo-modules'; export { fabricViewResolver } from './fabric'; +export { salesforceResolver } from './salesforce'; diff --git a/src/resolution/frameworks/salesforce.ts b/src/resolution/frameworks/salesforce.ts new file mode 100644 index 000000000..7d2816477 --- /dev/null +++ b/src/resolution/frameworks/salesforce.ts @@ -0,0 +1,153 @@ +/** + * Salesforce Framework Resolver + * + * Links Lightning Web Component / Aura JavaScript to the Apex methods they + * invoke. LWC imports Apex via a special module scheme: + * + * import getAccounts from '@salesforce/apex/AccountController.getAccounts'; + * @wire(getAccounts) accounts; // or getAccounts({ ... }) + * + * The JS extractor already indexes the LWC class/methods and records the + * import, but the `@salesforce/apex/...` specifier is external, so the import + * binding dangles. This resolver maps that binding to the existing Apex method + * node (qualifiedName `Class::method`), producing a cross-language edge that + * `getCallers`/`getFileDependents` can traverse ("which LWC calls this Apex + * method"). + * + * Cross-language note: Apex is not in any LANGUAGE_FAMILY, so the framework + * gate (`gateFrameworkLanguage`) never drops these calls/imports edges — see + * src/resolution/index.ts resolveOne, Strategy 1. + */ + +import { FrameworkResolver, UnresolvedRef, ResolvedRef, ResolutionContext } from '../types'; + +const APEX_PREFIX = '@salesforce/apex/'; + +/** + * Map a `@salesforce/apex/...` module specifier to the Apex method's + * qualifiedName `Class::method`. Handles managed-package namespaces + * (`ns.Class.method`) by taking the last two dotted segments — repo-local + * Apex nodes carry no namespace in their qualifiedName. + */ +function parseApexQualifiedName(source: string): string | null { + if (!source.startsWith(APEX_PREFIX)) return null; + const parts = source.slice(APEX_PREFIX.length).split('.'); + if (parts.length < 2) return null; + const method = parts[parts.length - 1]; + const className = parts[parts.length - 2]; + if (!method || !className) return null; + return `${className}::${method}`; +} + +/** + * Resolve a Visualforce markup reference. `controller=`/`extensions=` name an + * Apex class; `` names a Visualforce or LWC component. Class is tried + * first (controller refs), then component (custom-tag refs) — names rarely + * collide across the two. + */ +function resolveVisualforceRef(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null { + if (ref.referenceKind !== 'references') return null; + const named = context.getNodesByName(ref.referenceName); + const apexClass = named.find((n) => n.kind === 'class' && n.language === 'apex'); + const component = named.find((n) => n.kind === 'component'); + const target = apexClass ?? component; + if (!target) return null; + return { + original: ref, + targetNodeId: target.id, + confidence: 0.9, + resolvedBy: 'framework', + }; +} + +/** + * Resolve an LWC template `` reference. The extractor pascalized the + * kebab tag (`c-acct-tile` → `AcctTile`); the child component is its `.js` + * default-export class (Lightning convention names it after the bundle) or a + * component node. Same-bundle proximity isn't needed — child names are unique. + */ +function resolveLwcTemplateRef(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null { + if (ref.referenceKind !== 'references') return null; + const named = context.getNodesByName(ref.referenceName); + const childClass = named.find( + (n) => n.kind === 'class' && (n.language === 'javascript' || n.language === 'typescript') && /(^|\/)lwc\//.test(n.filePath) + ); + const component = named.find((n) => n.kind === 'component'); + const target = childClass ?? component; + if (!target) return null; + return { + original: ref, + targetNodeId: target.id, + confidence: 0.9, + resolvedBy: 'framework', + }; +} + +export const salesforceResolver: FrameworkResolver = { + name: 'salesforce', + languages: ['javascript', 'typescript', 'visualforce', 'lwc', 'aura'], + + detect(context: ResolutionContext): boolean { + // Salesforce DX project: Apex classes present, or an lwc/aura bundle dir. + const files = context.getAllFiles(); + return files.some( + (f) => f.endsWith('.cls') || f.endsWith('.page') || f.endsWith('.component') || /(^|\/)(lwc|aura)\//.test(f) + ); + }, + + resolve(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null { + // Visualforce markup → Apex controller/extension class or custom component. + // Resolved through the framework path so the cross-language edge survives the + // gate (Apex is its own language family — `gateFrameworkLanguage` keeps it). + if (ref.language === 'visualforce') { + return resolveVisualforceRef(ref, context); + } + + // LWC HTML template → child LWC component. + if (ref.language === 'lwc') { + return resolveLwcTemplateRef(ref, context); + } + + // Aura markup (references) → child component. The {!c.handler} + // `calls` refs resolve through the generic name-matcher (calls aren't gated). + if (ref.language === 'aura') { + if (ref.referenceKind !== 'references') return null; + const target = context.getNodesByName(ref.referenceName).find((n) => n.kind === 'component'); + if (!target) return null; + return { original: ref, targetNodeId: target.id, confidence: 0.9, resolvedBy: 'framework' }; + } + + // LWC/Aura JS: only the import binding and its call sites link to Apex. + if (ref.referenceKind !== 'calls' && ref.referenceKind !== 'imports') return null; + + // Find the `@salesforce/apex/...` specifier this reference binds to: + // either the import-source ref itself, or a call/binding whose local name + // maps to such an import in this file. + let apexSource: string | null = null; + if (ref.referenceName.startsWith(APEX_PREFIX)) { + apexSource = ref.referenceName; + } else { + const mappings = context.getImportMappings(ref.filePath, ref.language); + const match = mappings.find( + (im) => im.localName === ref.referenceName && im.source.startsWith(APEX_PREFIX) + ); + if (match) apexSource = match.source; + } + if (!apexSource) return null; + + const qualifiedName = parseApexQualifiedName(apexSource); + if (!qualifiedName) return null; + + const target = context + .getNodesByQualifiedName(qualifiedName) + .find((n) => n.kind === 'method'); + if (!target) return null; + + return { + original: ref, + targetNodeId: target.id, + confidence: 0.95, + resolvedBy: 'framework', + }; + }, +}; diff --git a/src/types.ts b/src/types.ts index 01aadae02..b0786238e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -81,6 +81,10 @@ export const LANGUAGES = [ 'swift', 'kotlin', 'dart', + 'apex', + 'visualforce', + 'lwc', + 'aura', 'svelte', 'vue', 'liquid', From cbfeffa2de9dfaabdf31f322a18ba67e524138e6 Mon Sep 17 00:00:00 2001 From: Dormon Zhou Date: Sun, 7 Jun 2026 18:26:07 +0800 Subject: [PATCH 2/3] fix: stop known-family bare calls binding cross-family by name collision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A JS/TS bare method call (`.replace()`, `.resolve()`) was exact-matched to a single same-named method in another language at confidence 0.5, since `calls` edges are intentionally left ungated for cross-layer bridges. This inflated an Apex method's dependents with false JS callers (e.g. CurrencyTokenReplacer:: replace picking up every String.replace in a React app). Gate `calls` only when the CALLER is in a known multi-language family (web, jvm, apple, c, dotnet): such a language is self-sufficient, so a genuine cross-family call goes through a framework/import resolver, never a bare name. Singleton/unknown-family callers (aura/visualforce → apex, config↔code) stay ungated. The deliberate Aura cmp.get("c.method") → Apex dispatch, whose JS file is a known-family caller, is re-routed through the salesforce framework resolver (Strategy 1, ungated) so it still connects. --- CHANGELOG.md | 1 + __tests__/resolution.test.ts | 69 +++++++++++++++++++++++++ src/resolution/frameworks/salesforce.ts | 25 +++++++++ src/resolution/name-matcher.ts | 14 ++++- 4 files changed, 108 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 310c82dec..a8ee70d51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - React Native native→JS events now connect through the common `sendEvent(context, "X", body)` wrapper. Many libraries (react-native-device-info and others) wrap the event emitter behind a helper whose `.emit(eventName, …)` takes a *variable*, so the matcher — which looked for `.emit("literal", …)` — missed it; the literal event name actually lives in the wrapper call. Now a native method that fires `sendEvent(…, "batteryLevelChanged", …)` links to the JS `addListener('batteryLevelChanged', …)` handler, so editing the native emitter surfaces the JS subscriber. (React Native) - React Native / Expo cross-language bridges are more complete and more precise. An Expo Module method declared with a generic type — Android's `AsyncFunction("getBatteryLevelAsync")` — is now indexed (the `` used to defeat the matcher, so every Android Expo method was dropped and a JS call resolved only to the iOS Swift impl). The iOS and Android implementations of the same JS-visible method — both Expo Modules and classic NativeModules (`@ReactMethod` on Android, the matching method on iOS) — are now linked to each other, so a JS call that resolves to one platform still reaches the other and editing either platform's native code surfaces the JS caller. And a `Type.member` static read in native code (e.g. Android's `BatteryManager.EXTRA_LEVEL`) no longer falsely links to a coincidentally same-named class in another language (a web `BatteryManager`) — type references stay within a language family, while genuine cross-language bridges (config→code, JS↔native calls) are unaffected. (React Native, Expo) - A TypeScript/JavaScript reference or import no longer gets mis-linked to a same-named class in a native language. In a React Native / Expo repo that has both a TypeScript `TestRunner` type and a Kotlin `TestRunner` class, a TS reference to `TestRunner` — or an `import React` sitting next to a Swift `React` — used to resolve onto the native symbol (the component resolver matched any same-named class regardless of language, and import statements weren't language-checked at all). References and imports now stay within their language family, so they land on the right symbol while genuine cross-language bridges (JS↔native calls, config→code) are untouched. A C/C++ `#include "Foo.h"` likewise no longer resolves to a same-named header from another platform (an iOS Objective-C `Foo.h`). (React Native, Expo, TypeScript, C/C++) +- A JavaScript or TypeScript method call no longer gets mis-linked to an unrelated same-named method in another language. A built-in or local call like `.replace(...)` or `.resolve(...)` used to bind to an Apex `CurrencyTokenReplacer::replace` or `…::resolve` just because the names matched — so a React file could look like it depended on Apex it never calls, and an Apex method's dependents were inflated with false callers. Calls from a self-contained language (JS/TS, Java/Kotlin, Swift/Objective-C, C/C++) now stay within their language family, while genuine cross-layer calls still connect — a Salesforce Aura controller's `cmp.get("c.method")` reaches its Apex method, and JS↔native bridges are unaffected. (Apex, LWC, Aura, Visualforce, TypeScript/JavaScript) - Native includes and Kotlin Multiplatform imports now resolve to the correct file in multi-platform projects. A C/C++ `#include "Foo.h"` now resolves to the header in the including file's own directory first (the C quoted-include rule), so when a module ships a same-named header per platform (a Windows, an Apple, and an Android `Foo.h` side by side) the local one correctly shows its dependents instead of an arbitrary other-platform header looking like the dependency. And a Kotlin Multiplatform `expect` declaration is no longer reported as having no dependents: a `commonMain` import now resolves to the `commonMain` `expect` (matched within the importing source set) rather than being absorbed by one platform's `actual`. (C/C++, Kotlin) - `codegraph affected` now reports the tests and files that actually depend on your changes. It used to follow only `import` statements — but those never cross file boundaries in CodeGraph's graph — so it returned **no affected tests for any change, in every language**. It now traces the real cross-file usage graph (calls, references, instantiations, and class `extends` / `implements`), so `git diff --name-only | codegraph affected` surfaces the test files that exercise the changed code. Circular-dependency detection, which had the same blind spot, now works too. - Blast radius, callers, and `codegraph affected` now recognize far more of the dependencies that were already in your code. A symbol now counts as a dependency whether it's called, used only in a type annotation inside a function body (`const items: Foo[] = []`), imported and placed in a registry array or passed as an argument, used as a JSX component, simply re-exported from a barrel (`export { X } from './x'`), or pulled in as a namespace (`import * as ns from '@/x'`) — including through tsconfig path aliases like `@/`. Previously only called, instantiated, or signature-typed symbols created a cross-file link, so a file that used a dependency in any other way could look like it depended on nothing — and the file that defined a widely-used symbol could look like nothing depended on it. The graph still indexes exactly the same symbols; it just connects the ones that were already there. (TypeScript/JavaScript) diff --git a/__tests__/resolution.test.ts b/__tests__/resolution.test.ts index 9d0788fc7..b310d9b3b 100644 --- a/__tests__/resolution.test.ts +++ b/__tests__/resolution.test.ts @@ -1115,6 +1115,75 @@ func main() { }); }); + describe('Name Matcher: cross-family `calls` gate', () => { + const baseContext = (candidates: Node[]): ResolutionContext => ({ + getNodesInFile: () => [], + getNodesByName: (name) => candidates.filter((c) => c.name === name), + getNodesByQualifiedName: () => [], + getNodesByKind: () => [], + fileExists: () => true, + readFile: () => null, + getProjectRoot: () => '/test', + getAllFiles: () => [], + getNodesByLowerName: () => [], + getImportMappings: () => [], + }); + + const apexReplace: Node = { + id: 'apex:CurrencyTokenReplacer.cls:replace:10', kind: 'method', name: 'replace', + qualifiedName: 'CurrencyTokenReplacer::replace', filePath: 'classes/CurrencyTokenReplacer.cls', + language: 'apex', startLine: 10, endLine: 20, startColumn: 0, endColumn: 0, updatedAt: Date.now(), + }; + + it('drops a JS bare call that only collides with a foreign-language method name', () => { + // A TS file calling `someString.replace(...)` emits a bare `replace` + // call ref. The graph has no JS `replace` node (it's a String builtin), + // only an Apex `CurrencyTokenReplacer::replace`. A known-family caller + // (web) must NOT bind to a different family by bare coincidental name. + const ref = { + fromNodeId: 'func:DataTransformer.ts:cleanText:1', + referenceName: 'replace', + referenceKind: 'calls' as const, + line: 5, column: 0, filePath: 'src/utils/DataTransformer.ts', language: 'typescript' as const, + }; + const result = matchReference(ref, baseContext([apexReplace])); + expect(result).toBeNull(); + }); + + it('still resolves a same-language call when a same-family candidate exists', () => { + // If a real TS `replace` method exists, the cross-family Apex one is + // dropped but the same-language one is kept. + const tsReplace: Node = { + id: 'ts:tokens.ts:replace:3', kind: 'method', name: 'replace', + qualifiedName: 'tokens.ts::TokenReplacer.replace', filePath: 'src/tokens.ts', + language: 'typescript', startLine: 3, endLine: 6, startColumn: 0, endColumn: 0, updatedAt: Date.now(), + }; + const ref = { + fromNodeId: 'func:main.ts:run:1', + referenceName: 'replace', + referenceKind: 'calls' as const, + line: 5, column: 0, filePath: 'src/main.ts', language: 'typescript' as const, + }; + const result = matchReference(ref, baseContext([apexReplace, tsReplace])); + expect(result?.targetNodeId).toBe('ts:tokens.ts:replace:3'); + }); + + it('keeps a cross-layer call from a singleton-family caller (Aura → Apex)', () => { + // Aura is not in LANGUAGE_FAMILY, so it stays ungated: a genuine + // cross-layer server call (`cmp.get("c.replace")`) with no same-language + // target survives — the gate only fences off self-sufficient known + // families (js/ts, java/kotlin, …), not config↔code bridges. + const ref = { + fromNodeId: 'aura:Foo.cmp:Foo:1', + referenceName: 'replace', + referenceKind: 'calls' as const, + line: 5, column: 0, filePath: 'aura/Foo/FooController.js', language: 'aura' as const, + }; + const result = matchReference(ref, baseContext([apexReplace])); + expect(result?.targetNodeId).toBe('apex:CurrencyTokenReplacer.cls:replace:10'); + }); + }); + describe('tsconfig path aliases', () => { it('resolves an aliased import to the alias-mapped file (not a same-named file elsewhere)', async () => { // Two same-named exports in different directories. Without alias diff --git a/src/resolution/frameworks/salesforce.ts b/src/resolution/frameworks/salesforce.ts index 7d2816477..a7a094280 100644 --- a/src/resolution/frameworks/salesforce.ts +++ b/src/resolution/frameworks/salesforce.ts @@ -83,6 +83,27 @@ function resolveLwcTemplateRef(ref: UnresolvedRef, context: ResolutionContext): }; } +/** + * Resolve an Aura controller's server call to Apex. An Aura JS controller + * (`aura//Controller|Helper|Renderer.js`) invokes a server + * method as `cmp.get("c.method")`; the extractor emits a bare `method` `calls` + * ref. The file is plain `javascript`, so the generic name-matcher's + * cross-family `calls` gate would (correctly, for coincidental collisions) drop + * it — but this IS a deliberate cross-layer dispatch, so the framework resolver + * binds it to the same-named Apex method here (Strategy 1, ungated). Scoped to + * the `aura/` bundle path so ordinary app JS never reaches it. + */ +function resolveAuraApexCall(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null { + if (ref.referenceKind !== 'calls') return null; + if (ref.language !== 'javascript' && ref.language !== 'typescript') return null; + if (!/(^|\/)aura\/[^/]+\/[^/]+\.js$/i.test(ref.filePath)) return null; + const target = context + .getNodesByName(ref.referenceName) + .find((n) => n.kind === 'method' && n.language === 'apex'); + if (!target) return null; + return { original: ref, targetNodeId: target.id, confidence: 0.9, resolvedBy: 'framework' }; +} + export const salesforceResolver: FrameworkResolver = { name: 'salesforce', languages: ['javascript', 'typescript', 'visualforce', 'lwc', 'aura'], @@ -117,6 +138,10 @@ export const salesforceResolver: FrameworkResolver = { return { original: ref, targetNodeId: target.id, confidence: 0.9, resolvedBy: 'framework' }; } + // Aura controller JS `cmp.get("c.method")` → same-named Apex method. + const auraCall = resolveAuraApexCall(ref, context); + if (auraCall) return auraCall; + // LWC/Aura JS: only the import binding and its call sites link to Apex. if (ref.referenceKind !== 'calls' && ref.referenceKind !== 'imports') return null; diff --git a/src/resolution/name-matcher.ts b/src/resolution/name-matcher.ts index d6bce5659..ee5526b22 100644 --- a/src/resolution/name-matcher.ts +++ b/src/resolution/name-matcher.ts @@ -148,7 +148,7 @@ export function crossesKnownFamily(a: string, b: string): boolean { return isKnownLanguageFamily(a) && isKnownLanguageFamily(b) && !sameLanguageFamily(a, b); } /** - * Drop cross-language candidates from a name lookup. Two regimes: + * Drop cross-language candidates from a name lookup. Three regimes: * - `references` (type-usage): a type named in language X resolves to a * SAME-family type, never a coincidentally same-named symbol in another * language (the Android `BatteryManager` system class vs a JS one). Strict @@ -156,6 +156,15 @@ export function crossesKnownFamily(a: string, b: string): boolean { * - `imports` (import binding): an `import`/`#include` never crosses two * KNOWN families (TS `import React` ↮ Swift `import React`). Weaker * both-known filter so `.vue`/`.svelte` (own tag) importing `.ts` survives. + * - `calls`: left ungated for callers in a SINGLETON/unknown family + * (`aura`/`visualforce` → `apex`, and other config↔code bridges) so genuine + * cross-layer calls with no same-language target survive. But a caller in a + * KNOWN multi-language family (js/ts, java/kotlin, swift/objc, c/cpp, …) is + * self-sufficient: a real cross-family call from it goes through a framework + * or import resolver, never a bare coincidental name. So for those callers we + * keep only same-family candidates — otherwise a JS `String.replace()` binds + * to an Apex `CurrencyTokenReplacer::replace`, a JS `.resolve()` to an Apex + * `…::resolve`, etc. (a name collision, not a call). */ function applyLanguageGate(candidates: Node[], ref: UnresolvedRef): Node[] { if (ref.referenceKind === 'references') { @@ -164,6 +173,9 @@ function applyLanguageGate(candidates: Node[], ref: UnresolvedRef): Node[] { if (ref.referenceKind === 'imports') { return candidates.filter((c) => !crossesKnownFamily(c.language, ref.language)); } + if (ref.referenceKind === 'calls' && isKnownLanguageFamily(ref.language)) { + return candidates.filter((c) => sameLanguageFamily(c.language, ref.language)); + } return candidates; } From ece1a8eca518f677d55c6668988464680b923884 Mon Sep 17 00:00:00 2001 From: Dormon Zhou Date: Sun, 7 Jun 2026 18:42:51 +0800 Subject: [PATCH 3/3] fix: extend cross-family calls gate to standalone programming languages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first pass gated only known multi-language families (web/jvm/apple/c/ dotnet). Singleton-family languages that are nonetheless self-sufficient programming languages (python/go/rust/php/ruby/dart/lua/pascal) were left ungated, so a Python `str.replace()` still bound to an Apex `…::replace` by name collision. Gate the calls of any self-sufficient programming-language caller; markup/template/config callers (visualforce/lwc/aura/svelte/vue/liquid/ twig/xml/yaml) stay ungated to preserve config->code bridges. --- CHANGELOG.md | 2 +- __tests__/resolution.test.ts | 15 +++++++++++- src/resolution/name-matcher.ts | 45 ++++++++++++++++++++++++++-------- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8ee70d51..b24ce660b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - React Native native→JS events now connect through the common `sendEvent(context, "X", body)` wrapper. Many libraries (react-native-device-info and others) wrap the event emitter behind a helper whose `.emit(eventName, …)` takes a *variable*, so the matcher — which looked for `.emit("literal", …)` — missed it; the literal event name actually lives in the wrapper call. Now a native method that fires `sendEvent(…, "batteryLevelChanged", …)` links to the JS `addListener('batteryLevelChanged', …)` handler, so editing the native emitter surfaces the JS subscriber. (React Native) - React Native / Expo cross-language bridges are more complete and more precise. An Expo Module method declared with a generic type — Android's `AsyncFunction("getBatteryLevelAsync")` — is now indexed (the `` used to defeat the matcher, so every Android Expo method was dropped and a JS call resolved only to the iOS Swift impl). The iOS and Android implementations of the same JS-visible method — both Expo Modules and classic NativeModules (`@ReactMethod` on Android, the matching method on iOS) — are now linked to each other, so a JS call that resolves to one platform still reaches the other and editing either platform's native code surfaces the JS caller. And a `Type.member` static read in native code (e.g. Android's `BatteryManager.EXTRA_LEVEL`) no longer falsely links to a coincidentally same-named class in another language (a web `BatteryManager`) — type references stay within a language family, while genuine cross-language bridges (config→code, JS↔native calls) are unaffected. (React Native, Expo) - A TypeScript/JavaScript reference or import no longer gets mis-linked to a same-named class in a native language. In a React Native / Expo repo that has both a TypeScript `TestRunner` type and a Kotlin `TestRunner` class, a TS reference to `TestRunner` — or an `import React` sitting next to a Swift `React` — used to resolve onto the native symbol (the component resolver matched any same-named class regardless of language, and import statements weren't language-checked at all). References and imports now stay within their language family, so they land on the right symbol while genuine cross-language bridges (JS↔native calls, config→code) are untouched. A C/C++ `#include "Foo.h"` likewise no longer resolves to a same-named header from another platform (an iOS Objective-C `Foo.h`). (React Native, Expo, TypeScript, C/C++) -- A JavaScript or TypeScript method call no longer gets mis-linked to an unrelated same-named method in another language. A built-in or local call like `.replace(...)` or `.resolve(...)` used to bind to an Apex `CurrencyTokenReplacer::replace` or `…::resolve` just because the names matched — so a React file could look like it depended on Apex it never calls, and an Apex method's dependents were inflated with false callers. Calls from a self-contained language (JS/TS, Java/Kotlin, Swift/Objective-C, C/C++) now stay within their language family, while genuine cross-layer calls still connect — a Salesforce Aura controller's `cmp.get("c.method")` reaches its Apex method, and JS↔native bridges are unaffected. (Apex, LWC, Aura, Visualforce, TypeScript/JavaScript) +- A method call in one programming language no longer gets mis-linked to an unrelated same-named method in another. A built-in or local call like `.replace(...)` or `.resolve(...)` — in JavaScript, or a Python `str.replace(...)` — used to bind to an Apex `CurrencyTokenReplacer::replace` or `…::resolve` just because the names matched, so a React or script file could look like it depended on Apex it never calls and an Apex method's dependents were inflated with false callers. Calls from a self-contained programming language (JS/TS, Java/Kotlin, Swift/Objective-C, C/C++, and Python, Go, Rust, PHP, Ruby, Dart, Lua) now stay within their language family, while genuine cross-layer calls still connect — a Salesforce Aura controller's `cmp.get("c.method")` reaches its Apex method, and JS↔native bridges are unaffected. (Apex, LWC, Aura, Visualforce, TypeScript/JavaScript, Python) - Native includes and Kotlin Multiplatform imports now resolve to the correct file in multi-platform projects. A C/C++ `#include "Foo.h"` now resolves to the header in the including file's own directory first (the C quoted-include rule), so when a module ships a same-named header per platform (a Windows, an Apple, and an Android `Foo.h` side by side) the local one correctly shows its dependents instead of an arbitrary other-platform header looking like the dependency. And a Kotlin Multiplatform `expect` declaration is no longer reported as having no dependents: a `commonMain` import now resolves to the `commonMain` `expect` (matched within the importing source set) rather than being absorbed by one platform's `actual`. (C/C++, Kotlin) - `codegraph affected` now reports the tests and files that actually depend on your changes. It used to follow only `import` statements — but those never cross file boundaries in CodeGraph's graph — so it returned **no affected tests for any change, in every language**. It now traces the real cross-file usage graph (calls, references, instantiations, and class `extends` / `implements`), so `git diff --name-only | codegraph affected` surfaces the test files that exercise the changed code. Circular-dependency detection, which had the same blind spot, now works too. - Blast radius, callers, and `codegraph affected` now recognize far more of the dependencies that were already in your code. A symbol now counts as a dependency whether it's called, used only in a type annotation inside a function body (`const items: Foo[] = []`), imported and placed in a registry array or passed as an argument, used as a JSX component, simply re-exported from a barrel (`export { X } from './x'`), or pulled in as a namespace (`import * as ns from '@/x'`) — including through tsconfig path aliases like `@/`. Previously only called, instantiated, or signature-typed symbols created a cross-file link, so a file that used a dependency in any other way could look like it depended on nothing — and the file that defined a widely-used symbol could look like nothing depended on it. The graph still indexes exactly the same symbols; it just connects the ones that were already there. (TypeScript/JavaScript) diff --git a/__tests__/resolution.test.ts b/__tests__/resolution.test.ts index b310d9b3b..fc8283e61 100644 --- a/__tests__/resolution.test.ts +++ b/__tests__/resolution.test.ts @@ -1168,7 +1168,20 @@ func main() { expect(result?.targetNodeId).toBe('ts:tokens.ts:replace:3'); }); - it('keeps a cross-layer call from a singleton-family caller (Aura → Apex)', () => { + it('drops a Python bare call that only collides with a foreign-language method name', () => { + // Python is a singleton family but a self-sufficient programming language: + // a `str.replace(...)` builtin must NOT bind to the Apex `replace`. + const ref = { + fromNodeId: 'func:tokens.py:clean:1', + referenceName: 'replace', + referenceKind: 'calls' as const, + line: 5, column: 0, filePath: 'scripts/tokens.py', language: 'python' as const, + }; + const result = matchReference(ref, baseContext([apexReplace])); + expect(result).toBeNull(); + }); + + it('keeps a cross-layer call from a markup/template caller (Aura → Apex)', () => { // Aura is not in LANGUAGE_FAMILY, so it stays ungated: a genuine // cross-layer server call (`cmp.get("c.replace")`) with no same-language // target survives — the gate only fences off self-sufficient known diff --git a/src/resolution/name-matcher.ts b/src/resolution/name-matcher.ts index ee5526b22..35b1d6436 100644 --- a/src/resolution/name-matcher.ts +++ b/src/resolution/name-matcher.ts @@ -134,6 +134,29 @@ export function sameLanguageFamily(a: string, b: string): boolean { export function isKnownLanguageFamily(lang: string): boolean { return LANGUAGE_FAMILY[lang] !== undefined; } +/** + * Singleton-family languages that are nonetheless self-sufficient, + * general-purpose PROGRAMMING languages (their own runtime + builtins). Like + * the known-family ones, they never invoke another language by a bare + * coincidental name — a real FFI/cross-layer call goes through a framework or + * import resolver. They are NOT in {@link LANGUAGE_FAMILY} (no sibling shares + * their runtime), so this set carries the same "self-sufficient caller" signal + * for the cross-family `calls` gate. Markup/template/config languages + * (visualforce/lwc/aura/svelte/vue/liquid/twig/xml/yaml/…) are deliberately + * excluded — they legitimately dispatch to code in another language by name + * (config↔code bridges), so they stay ungated. + */ +const STANDALONE_CODE_LANGUAGES = new Set([ + 'python', 'go', 'rust', 'php', 'ruby', 'dart', 'lua', 'luau', 'pascal', +]); +/** + * True when a CALLER in `lang` is a self-sufficient programming language — + * either a known multi-language family member or a standalone language above. + * Such a caller's bare cross-family `calls` are name collisions, not calls. + */ +export function isSelfSufficientCaller(lang: string): boolean { + return isKnownLanguageFamily(lang) || STANDALONE_CODE_LANGUAGES.has(lang); +} /** * True when `a` and `b` are two DIFFERENT *known* language families — the * signature of a coincidental cross-language name collision (a TS `import @@ -156,15 +179,17 @@ export function crossesKnownFamily(a: string, b: string): boolean { * - `imports` (import binding): an `import`/`#include` never crosses two * KNOWN families (TS `import React` ↮ Swift `import React`). Weaker * both-known filter so `.vue`/`.svelte` (own tag) importing `.ts` survives. - * - `calls`: left ungated for callers in a SINGLETON/unknown family - * (`aura`/`visualforce` → `apex`, and other config↔code bridges) so genuine - * cross-layer calls with no same-language target survive. But a caller in a - * KNOWN multi-language family (js/ts, java/kotlin, swift/objc, c/cpp, …) is - * self-sufficient: a real cross-family call from it goes through a framework - * or import resolver, never a bare coincidental name. So for those callers we - * keep only same-family candidates — otherwise a JS `String.replace()` binds - * to an Apex `CurrencyTokenReplacer::replace`, a JS `.resolve()` to an Apex - * `…::resolve`, etc. (a name collision, not a call). + * - `calls`: left ungated for callers in a MARKUP/TEMPLATE/CONFIG language + * (`aura`/`visualforce`/`liquid`/`yaml` → code, and other config↔code + * bridges) so genuine cross-layer calls with no same-language target survive. + * But a caller in a self-sufficient PROGRAMMING language (js/ts, java/kotlin, + * swift/objc, c/cpp, and standalone python/go/rust/php/ruby/dart/lua/pascal) + * has its own runtime + builtins: a real cross-family call from it goes + * through a framework or import resolver, never a bare coincidental name. So + * for those callers we keep only same-family candidates — otherwise a JS + * `String.replace()` (or a Python `str.replace()`) binds to an Apex + * `CurrencyTokenReplacer::replace`, a JS `.resolve()` to an Apex `…::resolve`, + * etc. (a name collision, not a call). */ function applyLanguageGate(candidates: Node[], ref: UnresolvedRef): Node[] { if (ref.referenceKind === 'references') { @@ -173,7 +198,7 @@ function applyLanguageGate(candidates: Node[], ref: UnresolvedRef): Node[] { if (ref.referenceKind === 'imports') { return candidates.filter((c) => !crossesKnownFamily(c.language, ref.language)); } - if (ref.referenceKind === 'calls' && isKnownLanguageFamily(ref.language)) { + if (ref.referenceKind === 'calls' && isSelfSufficientCaller(ref.language)) { return candidates.filter((c) => sameLanguageFamily(c.language, ref.language)); } return candidates;