From 5b6efd9e612dfa5ebb0a4aeeb14257e84c6bbba5 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 29 May 2026 11:17:32 +0300 Subject: [PATCH 1/8] Blog: build-time codegen (router, ORM, mappers, binder, SVG/Lottie) Final consolidated follow-up to the May 29 weekly index. Pulls together six PRs that share the same architectural shape: emit Java at build time, validate at build time, fail fast, and let R8 / ParparVM rename the generated code together with the rest of the app. - PR #5037: bytecode AnnotationProcessor SPI in the Maven plugin, the declarative router that is its first consumer (@Route with guards, redirects, per-tab navigation shell, location listeners), the unified cold + warm DeepLink API, iOS Universal Links / Android App Links JSON generators, and the JavaScript-port window.history bridge. - PR #5047: three more processors on the same SPI -- SQLite ORM (@Entity / @Id / @Column), JSON / XML mapping (@Mapped / @JsonProperty / @XmlElement), and component binding (@Bindable / @Bind with the new BindAttr enum). - PR #5062: validation annotations (@Required, @Length, @Regex, @Email, @Url, @Numeric, @ExistIn, @Validate) that compose with @Bind and surface through Binding.getValidator(). - PR #5055: the Immich-port baseline -- Map default methods, BiFunction, atomics, Rest.fetchAsJsonList / fetchAsMapped(List), URLImage.RequestDecorator / setDefaultBearerToken, JSONWriter, modern animated tab indicator + arc-spinner pull-to-refresh, MorphTransition.snapshotMode, WebSocket in core, and the new cn1:generate-openapi-client mojo. - PR #5042: build-time SVG transcoder that lowers SVG (and SMIL animations) into Codename One Image subclasses via the shape API. - PR #5066: Lottie / Bodymovin transcoder reusing the same SVGDocument model, JavaCodeGenerator, and SVGRegistry. - PR #5049: the iOS Metal stencil-clip + drawString and Android LinearGradientPaint fixes the SVG screenshot tests exposed. Calls out the Metal-only caveat on iOS for SVG / Lottie (the GL ES 2 path does not have the shape coverage) -- a non-issue on most apps now that Metal is the default. --- .../content/blog/build-time-codegen.md | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 docs/website/content/blog/build-time-codegen.md diff --git a/docs/website/content/blog/build-time-codegen.md b/docs/website/content/blog/build-time-codegen.md new file mode 100644 index 0000000000..a76299e5f6 --- /dev/null +++ b/docs/website/content/blog/build-time-codegen.md @@ -0,0 +1,211 @@ +--- +title: Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie +slug: build-time-codegen +url: /blog/build-time-codegen/ +date: '2026-06-03' +author: Shai Almog +description: A reusable bytecode AnnotationProcessor SPI in the Maven plugin, the declarative router that is its first consumer, a SQLite ORM, JSON / XML mappers, a component binder with validation, the Immich-port baseline that drove the ORM design, and a build-time SVG / Lottie transcoder that emits Codename One Image subclasses for every asset. +feed_html: 'Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie A reusable bytecode AnnotationProcessor SPI, the declarative router that is its first consumer, ORM + mappers + binder + validation, the Immich-port baseline, and a build-time SVG / Lottie transcoder.' +--- + +![Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie](/blog/build-time-codegen.jpg) + +This is the architectural post for the week. The Saturday post was about how you iterate; Monday's post was about new platform APIs; today's post is about a shape of code that several PRs in this release share, that explains why a lot of the new APIs work the way they do, and that I think will shape how Codename One projects look over the next few years. + +The shape is **build-time codegen**. A reusable bytecode `AnnotationProcessor` SPI in the Maven plugin, the declarative router that is its first concrete consumer, then a SQLite ORM, JSON / XML mappers, and a component binder (all built on the same SPI), plus the build-time SVG / Lottie transcoders that ship in the same release for related reasons. The grab-bag PR from the Immich Flutter port lives here too because the ORM and mapping work share the porting exercise that drove it. + +Six PRs make up this post: [#5037](https://github.com/codenameone/CodenameOne/pull/5037) (router + annotation SPI), [#5047](https://github.com/codenameone/CodenameOne/pull/5047) (ORM + mappers + binder), [#5062](https://github.com/codenameone/CodenameOne/pull/5062) (validation), [#5055](https://github.com/codenameone/CodenameOne/pull/5055) (Immich-port baseline), [#5042](https://github.com/codenameone/CodenameOne/pull/5042) and [#5066](https://github.com/codenameone/CodenameOne/pull/5066) (SVG / Lottie), plus [#5049](https://github.com/codenameone/CodenameOne/pull/5049) (Metal / Android rendering fixes that fell out of the SVG screenshot tests). + +## Bytecode codegen, not source-text codegen + +The Maven plugin now has an `AnnotationProcessor` SPI and two new Mojos: `cn1:generate-annotation-stubs` (in `generate-sources`) and `cn1:process-annotations` (in `process-classes`). The orchestrator ASM-scans `target/classes`, dispatches to every registered processor, validates the annotated classes, and emits a typed runtime artifact next to each one plus a tiny `Index` class that registers everything with a public runtime registry. Adding a new processor later is a matter of dropping it into `META-INF/services` with no orchestrator changes. + +The reason this runs against bytecode rather than against source text is that the source-regex prototype was scrapped early. The bytecode pass sees the JVM's view of the project (`extends Form` is a thing the JVM actually knows, not a pattern we have to hope the user wrote a specific way), rule violations come back with class names and reasons, and the build fails fast before any generated `.class` lands on disk. The infrastructure shares the ASM passes that the `BytecodeComplianceMojo`'s existing String rewrites already use. + +A small stub source is emitted under `target/generated-sources/cn1-annotations/` during `generate-sources` so application code that references the generated registry resolves at compile time. The real `.class` overwrites the stub later in `process-classes`. Standard "compile against a stub, link against the real thing" pattern; it just works inside a single Maven build instead of needing a multi-module split. + +Three non-negotiable rules across every processor in this batch: **no `Class.forName`, no service loader, no field reflection**. Every read and write in the generated code is a direct symbol reference that ParparVM rename and R8 obfuscation rewrite together with the class they target. Anything that worked in the simulator and broke in production because R8 renamed a class or a field; that whole shape of bug is structurally absent. + +cn1-core ships a no-op stub of each generated index (`RoutesIndex`, `MappersIndex`, `BindersIndex`, `DaosIndex`) so application code compiles even when the project has no annotated classes. The build-time processor shadows each stub with the real implementation before packaging. + +## The router + +The first concrete consumer is the declarative router in `com.codename1.router`. The API is opt-in; the existing `Form.show()` / `Form.showBack()` flow keeps working unchanged. + +```java +@Route("/") +public class HomeForm extends Form { /* ... */ } + +@Route("/users/:id") +public class UserDetailForm extends Form { + public UserDetailForm(RouteMatch match) { + String id = match.param("id"); + // build UI for user `id` + } +} +``` + +`Router.navigate("/users/42")` resolves the path, instantiates `UserDetailForm`, and shows it. The build-time processor validates that the annotated class extends `Form`, that the path starts with `/`, that the constructor is accessible, that there are no duplicate patterns. Anything off the rails fails the build with a class name and a reason, not at runtime with a stack trace. + +The rest of the router surface is what has become table stakes in modern client routing: route guards (run before navigation completes; can cancel or redirect), redirects, per-tab navigation stacks (`TabsForm`, where each tab keeps its own back stack), location listeners (anything in the app can subscribe to "the route changed"), and a `Form.setPopGuard(PopGuard)` analogue to Flutter's `PopScope` (intercept hardware back, toolbar back, or `Router.pop()` with a chance to ask "are you sure?"). `Sheet.showForResult()` returns an `AsyncResource` that auto-cancels with `null` if the user dismisses the sheet. + +### Deep links + +`Display.setDeepLinkHandler(LinkHandler)` registers a handler that receives a normalised `DeepLink` (scheme, host, path, segments, query, fragment). The same handler is invoked for cold launches (the app was not running; the OS started it because of a link) and warm launches (the app was already running and got the URL via app-resume). iOS and Android need no port changes for this to work; the existing platform plumbing already writes URL-shaped values into `Display.setProperty("AppArg", url)` and the new handler intercepts those. + +For the link-publishing side, an `AasaBuilder` emits the iOS `apple-app-site-association` JSON, and an `AssetLinksBuilder` emits the Android `assetlinks.json`. The full setup walk-through (entitlements, `intent-filter`, the `.well-known/` upload) is at [Routing-And-Deep-Links.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Routing-And-Deep-Links.asciidoc), with an end-to-end tutorial at [Tutorial-Routing-And-Deep-Links.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Tutorial-Routing-And-Deep-Links.asciidoc). + +The JavaScript port bridges the router into `window.history` so navigating the in-app router pushes a real entry into the browser history. Back and forward buttons in the browser drive the router; reloading the page lands at the deep-link URL. The Initializr, the Playground, the Skin Designer, and the new Build Cloud console all benefit. + +## ORM, mappers, and binder (with validation) + +[PR #5047](https://github.com/codenameone/CodenameOne/pull/5047) lands three more processors on the same SPI. [PR #5062](https://github.com/codenameone/CodenameOne/pull/5062) layers validation on the binder. + +### SQLite ORM + +`@Entity`, `@Id`, `@Column`, `@DbTransient` for the schema; `EntityManager` and `Dao` for the runtime: + +```java +@Entity +public class TodoItem { + @Id @Column long id; + @Column String title; + @Column(name = "completed_at") Date completedAt; + @DbTransient Object cachedView; +} + +Dao dao = EntityManager.open("todos.db").dao(TodoItem.class); +dao.createTable(); +dao.insert(new TodoItem(0, "Read the post", null)); +List open = dao.find("completed_at IS NULL", new Object[] {}); +``` + +The generated DAO does the typed work underneath. No reflection in `insert`; the generated code calls `setString(1, e.title)` and `setLong(2, e.id)` directly. Validation at build time catches missing `@Id`, fields that look like relationships but are not yet supported, abstract entity classes. + +### JSON / XML mapping + +`@Mapped` is the entry point; `@JsonProperty` and `@XmlElement` (plus `@XmlRoot`, `@XmlAttribute`, `@JsonIgnore`, `@XmlTransient`) shape the wire format: + +```java +@Mapped +public class User { + @JsonProperty("user_id") long id; + @JsonProperty String name; + @JsonProperty("created_at") + Date createdAt; + @JsonIgnore String passwordHash; +} + +String json = Mappers.toJson(user); +User back = Mappers.fromJson(json, User.class); +``` + +The same `@Mapped` POJO is the type the `Rest` helpers from PR #5055 will accept (`Rest.get(url).fetchAsMapped(User.class)`, `fetchAsMappedList(User.class)`). + +### Component binding with validation + +`@Bindable` marks a model class; `@Bind(name = "userField")` ties a field to a component on the form by its name. The build-time binder reads the field types and the components, generates the bidirectional wiring at compile time: + +```java +@Bindable +public class SignupModel { + @Bind(name = "userField") @Required @Length(min = 3) private String user; + @Bind(name = "emailField") @Required @Email private String email; + @Bind(name = "ageField") @Numeric(min = 13, max = 120) private String age; + @Bind(name = "roleField") @ExistIn({ "admin", "editor", + "viewer" }) private String role; +} + +Binding b = Binders.bind(model, form); +b.getValidator().addSubmitButtons(submitBtn); +``` + +`Binding` is the handle: `refresh()` re-reads the model into the components, `commit()` writes the components back, `disconnect()` tears the listeners down. Multiple validation annotations on a single field compose via the existing `Validator.addConstraint(Component, Constraint...)` varargs (`GroupConstraint`, first failure wins). `@Validate(MyClass.class)` is the escape hatch for hand-written `Constraint` implementations. The validation set: `@Required`, `@Length`, `@Regex`, `@Email`, `@Url`, `@Numeric`, `@ExistIn`, `@Validate`. + +The new `BindAttr` enum lets `@Bind` target a specific attribute of the component (`TEXT`, `UIID`, `SELECTED`, ...) when the default is not what you want. The annotation framework reads it at build time and generates the matching `Component#setUiid(...)` / `Component#setSelected(...)` call. + +Three new dev-guide chapters: [Annotation-JSON-XML-Mapping.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Annotation-JSON-XML-Mapping.asciidoc), [Annotation-Component-Binding.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Annotation-Component-Binding.asciidoc), and [Annotation-SQLite-ORM.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Annotation-SQLite-ORM.asciidoc). + +## The Immich-port baseline + +[PR #5055](https://github.com/codenameone/CodenameOne/pull/5055) ships as "Improvements to baseline based on porting exercise" and the porting exercise was real: Immich, the Flutter mobile client, into Codename One. The port is still compiling cleanly through every change in that PR; the additions worth pulling out: + +**Java subset additions.** Eleven Java 8 default methods on `Map` (`getOrDefault`, `putIfAbsent`, `remove(K, V)`, `replace(K, V)` / `replace(K, V, V)`, `forEach`, `replaceAll`, `computeIfAbsent`, `computeIfPresent`, `compute`, `merge`); `BiFunction`; `Iterable.forEach(Consumer)`, `Collection.removeIf(Predicate)`, `List.replaceAll(UnaryOperator)`, `List.sort(Comparator)`. All four primitive atomics: `AtomicReference`, `AtomicInteger`, `AtomicLong`, `AtomicBoolean`. Standard Java 8 surface that was simply missing. + +**`Rest` typed helpers.** `Rest.fetchAsJsonList`, `Rest.fetchAsMapped(Class)`, `Rest.fetchAsMappedList(Class)` (these are the surface the mapper post above mentioned). `Rest.fetchAsJsonList` closes a long-standing rough edge: top-level JSON arrays no longer need the historical `{"root":[...]}` envelope trick. + +**`URLImage.RequestDecorator`** plus `setDefaultRequestDecorator`, `setDefaultBearerToken`, and a per-call decorator overload on `createToStorage`. Authenticated image endpoints no longer require working around the "URLImage does not pass headers" gap; set a bearer token once and the image cache and the `URLImage` machinery use it everywhere. + +**`JSONWriter`** is the complement of `JSONParser`. `JSONWriter.toJson(Object)` for one-shot, fluent `JSONWriter.object().put(...).toJson()` and `JSONWriter.array()` builders, streaming variants for `Writer` and `OutputStream`. + +**`Tabs.setAnimatedIndicator(boolean)`** enables a Material 3 / iOS 26 sliding-underline indicator (gated by `tabsAnimatedIndicatorBool` plus duration / thickness constants and a new `TabIndicator` UIID). Off in the framework defaults; **on by default in the modern native themes** that we landed two weeks ago. + +**`DefaultLookAndFeel.drawModernPullToRefresh`** is a Material 3 arc-spinner painted via `Graphics.drawArc`; sweep grows 0° to 330° as the user pulls, then spins while the task runs. Gated by `pullToRefreshModernBool`; on by default in the modern themes. + +**`MorphTransition.snapshotMode(boolean)`** is the fix for an edge case that has been around forever: a morph from a source inside a scrolling container leaked off-viewport because the source was repainted live. The opt-in path captures source and destination as clipped `Image` snapshots at `initTransition()` and tweens those. Default live-paint path unchanged. + +**`com.codename1.io.websocket`** moves into the core. Per-platform native impls remain in the cn1lib for now. + +**`cn1:generate-openapi-client`** mojo reads an OpenAPI 3.x JSON spec and emits one `@Mapped` POJO per `components.schemas` entry plus one `Api.java` per tag. The Petstore reference spec runs end-to-end. Dev-guide page: [appendix_goal_generate_openapi_client.adoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/appendix_goal_generate_openapi_client.adoc). + +A natural question on this PR is "why is all of that in one PR rather than ten". The honest answer is that the porting exercise was the regression fixture for every single one of those additions, and breaking it up would have meant maintaining a long-lived branch where each split-out item had to be re-verified against the port independently. + +## SVG and Lottie at build time + +The last two PRs in this batch sit on the same "emit Java from declarative input at build time" pattern. [PR #5042](https://github.com/codenameone/CodenameOne/pull/5042) is the SVG transcoder; [PR #5066](https://github.com/codenameone/CodenameOne/pull/5066) is the Lottie / Bodymovin transcoder that reuses the SVG pipeline; [PR #5049](https://github.com/codenameone/CodenameOne/pull/5049) is the small set of iOS Metal and Android rendering fixes the SVG screenshot tests exposed. They share one chapter at [SVG-Transcoder.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/SVG-Transcoder.asciidoc). + +**Important caveat before the details:** this is **Metal-only on iOS**. The GL ES 2 path that was the iOS default until [last Friday's flip](/blog/metal-default-new-build-cloud-and-a-new-format/#metal-is-the-default-on-ios) does not have the shape API coverage the SVG / Lottie pipeline emits. Apps that opted in to Metal pick up the transcoders automatically; apps still on `ios.metal=false` will see placeholders. Now that Metal is the default this stops being a thing most apps notice on their next build. + +The shape: + +``` +src/main/svg/ + home.svg + settings.svg + profile.svg +src/main/lottie/ + spinner.json + pulse.json +``` + +After the next build: + +```java +Image home = Resources.getGlobalResources().getImage("home"); +Image spinner = Resources.getGlobalResources().getImage("spinner"); +form.add(home).add(spinner); +``` + +The SVG transcoder is a `maven/svg-transcoder/` module that parses SVG with `javax.xml` StAX (no Batik, no Flamingo, no external deps) and emits a Codename One `Image` subclass rendering through the `Graphics` shape API. SVG coverage covers what real-world icon SVGs use: rect (rounded corners), circle, ellipse, line, polyline, polygon, the full `path` grammar (M / L / H / V / C / S / Q / T / A / Z plus relative-coordinate and smooth-curve reflection), groups with affine transforms, linear gradients, fill, stroke, opacity. SMIL animations are supported: ``, `` (translate / scale / rotate), ``. Time values interpolate against wall-clock time on every paint. + +The Lottie pipeline reuses everything: each Bodymovin file is parsed into the same `SVGDocument` model the SVG path uses, the same `JavaCodeGenerator` emits the same `GeneratedSVGImage` subclass, the same `SVGRegistry` registers it. No new `Image` base class, no per-port wiring. v1 covers shape layers (`rc` / `el` / `sh`) with solid fills and strokes, layer transforms (anchor / position / scale / rotation / opacity), animated rotation / position / scale collapsed to a 2-keyframe loop, solid-color layers as filled rects. + +Why Java at build time rather than parse SVG at runtime: parsing requires `javax.xml`, which is JVM-only by design; the generated code is allocation-light and deterministic (a path's commands become inlined `g.fillShape(new GeneralPath()...)` calls; an animation becomes a `currentTransform.translate(...)` against a wall-clock variable); and R8 / ParparVM rename and dead-code eliminate the generated code as freely as any other class, so SVGs you do not actually `getImage(...)` get dropped from the final binary. + +### The Metal / Android rendering fixes + +The SVG screenshot tests exercised the shape API harder than anything we had thrown at it before, and three rendering bugs surfaced; the fixes in [PR #5049](https://github.com/codenameone/CodenameOne/pull/5049) affect any code path that uses `setClip(GeneralPath)`, gradient paint, or text under a transform, not just the SVG pipeline: + +1. **iOS Metal `setClip(GeneralPath)` triangle.** Metal's stencil clip's triangle fan was treating every Bezier control point as a polygon vertex. Non-rect `ClipShape`s are now midpoint-flattened into a polyline before reaching native. +2. **iOS Metal `drawString` skips the affine scale.** Text under a viewBox scale was rasterised at `font.pointSize` and stretched on the GPU. `CN1MetalDrawString` now reads the effective scale from `currentTransform`, picks an atlas font at `pointSize * scale`, and divides glyph metrics back into caller-side coords. +3. **Android and iOS Metal `gradient_circle.svg` double-circle.** `LinearGradientPaint.paint` was baking `getTranslateX/Y()` into a translate that sat before the SVG scale, sending the cell offset through the scale twice. The "translate dance" is dropped. + +If your app uses `setClip(GeneralPath)` or paints text under a non-uniform transform anywhere, you pick these fixes up on next rebuild. + +## What ties this together + +The thread across all six PRs is the same pattern: **emit Java at build time, validate at build time, fail fast with a class name and a reason, R8 / ParparVM rename the generated code together with the rest of the app**. The router uses it to register `@Route` classes. The ORM uses it to generate typed DAOs. The mappers use it to generate typed JSON / XML readers and writers. The binder uses it to wire fields to components. The SVG and Lottie transcoders use it to turn declarative graphics into Java classes that render through the shape API. + +The practical effect is that the kind of code that historically required reflection at runtime (with all the obfuscation hazards and surprise allocations that come with that) now happens once at build time and produces direct, dead-code-eliminable, rename-safe symbol references. That is the shape I think Codename One projects are going to look more and more like over the next year. + +## Wrapping up + +That closes out the post series for this release cycle. The May 29 weekly index is [here](/blog/metal-default-new-build-cloud-and-a-new-format/); the next weekly index is the one I will publish on Friday in the same short format. + +--- + +## Discussion + +_Join the conversation via GitHub Discussions._ + +{{< giscus >}} From b50152c9813c4c1a8d1a37a95abf4bacfe8a761c Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 29 May 2026 11:42:14 +0300 Subject: [PATCH 2/8] Build-time-codegen post: style pass - "I" voice replaced with "we" / team-flavoured phrasing. - Front matter description and feed_html no longer name the Immich Flutter port; the porting exercise is described generically as "a substantial mobile client app". - Section heading renamed from "The Immich-port baseline" to "The porting-exercise baseline". - Body prose no longer names the Flutter source; the porting exercise is described in generic terms ("a substantial third-party mobile client onto Codename One"). - "Form.setPopGuard analogue to Flutter's PopScope" rephrased so the Flutter analogy is gone and the hook is described directly. - Wrap-up rephrased so the "next index lands on Friday" line reads as a fact rather than a personal commitment. --- .../content/blog/build-time-codegen.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/website/content/blog/build-time-codegen.md b/docs/website/content/blog/build-time-codegen.md index a76299e5f6..ee89444641 100644 --- a/docs/website/content/blog/build-time-codegen.md +++ b/docs/website/content/blog/build-time-codegen.md @@ -4,17 +4,17 @@ slug: build-time-codegen url: /blog/build-time-codegen/ date: '2026-06-03' author: Shai Almog -description: A reusable bytecode AnnotationProcessor SPI in the Maven plugin, the declarative router that is its first consumer, a SQLite ORM, JSON / XML mappers, a component binder with validation, the Immich-port baseline that drove the ORM design, and a build-time SVG / Lottie transcoder that emits Codename One Image subclasses for every asset. -feed_html: 'Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie A reusable bytecode AnnotationProcessor SPI, the declarative router that is its first consumer, ORM + mappers + binder + validation, the Immich-port baseline, and a build-time SVG / Lottie transcoder.' +description: A reusable bytecode AnnotationProcessor SPI in the Maven plugin, the declarative router that is its first consumer, a SQLite ORM, JSON / XML mappers, a component binder with validation, the baseline additions surfaced by porting a substantial mobile client app onto Codename One, and a build-time SVG / Lottie transcoder that emits Codename One Image subclasses for every asset. +feed_html: 'Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie A reusable bytecode AnnotationProcessor SPI, the declarative router that is its first consumer, ORM + mappers + binder + validation, the porting-exercise baseline additions, and a build-time SVG / Lottie transcoder.' --- ![Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie](/blog/build-time-codegen.jpg) -This is the architectural post for the week. The Saturday post was about how you iterate; Monday's post was about new platform APIs; today's post is about a shape of code that several PRs in this release share, that explains why a lot of the new APIs work the way they do, and that I think will shape how Codename One projects look over the next few years. +This is the architectural post for the week. The Saturday post was about how you iterate; Monday's post was about new platform APIs; today's post is about a shape of code that several PRs in this release share, that explains why a lot of the new APIs work the way they do, and that should shape how Codename One projects look over the next few years. -The shape is **build-time codegen**. A reusable bytecode `AnnotationProcessor` SPI in the Maven plugin, the declarative router that is its first concrete consumer, then a SQLite ORM, JSON / XML mappers, and a component binder (all built on the same SPI), plus the build-time SVG / Lottie transcoders that ship in the same release for related reasons. The grab-bag PR from the Immich Flutter port lives here too because the ORM and mapping work share the porting exercise that drove it. +The shape is **build-time codegen**. A reusable bytecode `AnnotationProcessor` SPI in the Maven plugin, the declarative router that is its first concrete consumer, then a SQLite ORM, JSON / XML mappers, and a component binder (all built on the same SPI), plus the build-time SVG / Lottie transcoders that ship in the same release for related reasons. The grab-bag PR from a recent porting exercise (a substantial mobile client app ported onto Codename One) lives here too because the ORM and mapping work share the porting exercise that drove it. -Six PRs make up this post: [#5037](https://github.com/codenameone/CodenameOne/pull/5037) (router + annotation SPI), [#5047](https://github.com/codenameone/CodenameOne/pull/5047) (ORM + mappers + binder), [#5062](https://github.com/codenameone/CodenameOne/pull/5062) (validation), [#5055](https://github.com/codenameone/CodenameOne/pull/5055) (Immich-port baseline), [#5042](https://github.com/codenameone/CodenameOne/pull/5042) and [#5066](https://github.com/codenameone/CodenameOne/pull/5066) (SVG / Lottie), plus [#5049](https://github.com/codenameone/CodenameOne/pull/5049) (Metal / Android rendering fixes that fell out of the SVG screenshot tests). +Six PRs make up this post: [#5037](https://github.com/codenameone/CodenameOne/pull/5037) (router + annotation SPI), [#5047](https://github.com/codenameone/CodenameOne/pull/5047) (ORM + mappers + binder), [#5062](https://github.com/codenameone/CodenameOne/pull/5062) (validation), [#5055](https://github.com/codenameone/CodenameOne/pull/5055) (porting-exercise baseline additions), [#5042](https://github.com/codenameone/CodenameOne/pull/5042) and [#5066](https://github.com/codenameone/CodenameOne/pull/5066) (SVG / Lottie), plus [#5049](https://github.com/codenameone/CodenameOne/pull/5049) (Metal / Android rendering fixes that fell out of the SVG screenshot tests). ## Bytecode codegen, not source-text codegen @@ -47,7 +47,7 @@ public class UserDetailForm extends Form { `Router.navigate("/users/42")` resolves the path, instantiates `UserDetailForm`, and shows it. The build-time processor validates that the annotated class extends `Form`, that the path starts with `/`, that the constructor is accessible, that there are no duplicate patterns. Anything off the rails fails the build with a class name and a reason, not at runtime with a stack trace. -The rest of the router surface is what has become table stakes in modern client routing: route guards (run before navigation completes; can cancel or redirect), redirects, per-tab navigation stacks (`TabsForm`, where each tab keeps its own back stack), location listeners (anything in the app can subscribe to "the route changed"), and a `Form.setPopGuard(PopGuard)` analogue to Flutter's `PopScope` (intercept hardware back, toolbar back, or `Router.pop()` with a chance to ask "are you sure?"). `Sheet.showForResult()` returns an `AsyncResource` that auto-cancels with `null` if the user dismisses the sheet. +The rest of the router surface is the kind of thing that has become table stakes in modern client routing: route guards (run before navigation completes; can cancel or redirect), redirects, per-tab navigation stacks (`TabsForm`, where each tab keeps its own back stack), location listeners (anything in the app can subscribe to "the route changed"), and a `Form.setPopGuard(PopGuard)` hook to intercept hardware back, toolbar back, or `Router.pop()` with a chance to ask "are you sure?". `Sheet.showForResult()` returns an `AsyncResource` that auto-cancels with `null` if the user dismisses the sheet. ### Deep links @@ -126,9 +126,9 @@ The new `BindAttr` enum lets `@Bind` target a specific attribute of the componen Three new dev-guide chapters: [Annotation-JSON-XML-Mapping.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Annotation-JSON-XML-Mapping.asciidoc), [Annotation-Component-Binding.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Annotation-Component-Binding.asciidoc), and [Annotation-SQLite-ORM.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Annotation-SQLite-ORM.asciidoc). -## The Immich-port baseline +## The porting-exercise baseline -[PR #5055](https://github.com/codenameone/CodenameOne/pull/5055) ships as "Improvements to baseline based on porting exercise" and the porting exercise was real: Immich, the Flutter mobile client, into Codename One. The port is still compiling cleanly through every change in that PR; the additions worth pulling out: +[PR #5055](https://github.com/codenameone/CodenameOne/pull/5055) ships as "Improvements to baseline based on porting exercise". The porting exercise was real: a substantial third-party mobile client onto Codename One. The port is still compiling cleanly through every change in that PR; the additions worth pulling out: **Java subset additions.** Eleven Java 8 default methods on `Map` (`getOrDefault`, `putIfAbsent`, `remove(K, V)`, `replace(K, V)` / `replace(K, V, V)`, `forEach`, `replaceAll`, `computeIfAbsent`, `computeIfPresent`, `compute`, `merge`); `BiFunction`; `Iterable.forEach(Consumer)`, `Collection.removeIf(Predicate)`, `List.replaceAll(UnaryOperator)`, `List.sort(Comparator)`. All four primitive atomics: `AtomicReference`, `AtomicInteger`, `AtomicLong`, `AtomicBoolean`. Standard Java 8 surface that was simply missing. @@ -196,11 +196,11 @@ If your app uses `setClip(GeneralPath)` or paints text under a non-uniform trans The thread across all six PRs is the same pattern: **emit Java at build time, validate at build time, fail fast with a class name and a reason, R8 / ParparVM rename the generated code together with the rest of the app**. The router uses it to register `@Route` classes. The ORM uses it to generate typed DAOs. The mappers use it to generate typed JSON / XML readers and writers. The binder uses it to wire fields to components. The SVG and Lottie transcoders use it to turn declarative graphics into Java classes that render through the shape API. -The practical effect is that the kind of code that historically required reflection at runtime (with all the obfuscation hazards and surprise allocations that come with that) now happens once at build time and produces direct, dead-code-eliminable, rename-safe symbol references. That is the shape I think Codename One projects are going to look more and more like over the next year. +The practical effect is that the kind of code that historically required reflection at runtime (with all the obfuscation hazards and surprise allocations that come with that) now happens once at build time and produces direct, dead-code-eliminable, rename-safe symbol references. That is the shape Codename One projects are going to look more and more like over the next year. ## Wrapping up -That closes out the post series for this release cycle. The May 29 weekly index is [here](/blog/metal-default-new-build-cloud-and-a-new-format/); the next weekly index is the one I will publish on Friday in the same short format. +That closes out the post series for this release cycle. The May 29 weekly index is [here](/blog/metal-default-new-build-cloud-and-a-new-format/); the next weekly index lands on Friday in the same short format. --- From 5fba280babb170e500ea78402de0ba79816ca96c Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 29 May 2026 14:34:51 +0300 Subject: [PATCH 3/8] Build-time-codegen post: hero image + cross-post linking - Hero image lands at /blog/build-time-codegen.jpg. - Wrap-up reworded so the "back to the weekly index" link uses the same shape as the workflow and platform-APIs posts. - Platform-APIs post (rebased on top) updated so its wrap-up forward-links to this post by URL rather than by date prose. --- docs/website/content/blog/build-time-codegen.md | 4 +++- docs/website/static/blog/build-time-codegen.jpg | Bin 0 -> 27693 bytes 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 docs/website/static/blog/build-time-codegen.jpg diff --git a/docs/website/content/blog/build-time-codegen.md b/docs/website/content/blog/build-time-codegen.md index ee89444641..6ebc30e9a9 100644 --- a/docs/website/content/blog/build-time-codegen.md +++ b/docs/website/content/blog/build-time-codegen.md @@ -200,7 +200,9 @@ The practical effect is that the kind of code that historically required reflect ## Wrapping up -That closes out the post series for this release cycle. The May 29 weekly index is [here](/blog/metal-default-new-build-cloud-and-a-new-format/); the next weekly index lands on Friday in the same short format. +That closes out the post series for this release cycle. The next weekly index lands on Friday in the same short format. + +Back to the [weekly index](/blog/metal-default-new-build-cloud-and-a-new-format/). --- diff --git a/docs/website/static/blog/build-time-codegen.jpg b/docs/website/static/blog/build-time-codegen.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9e1be3b3b813dae06e735d01f881d6b72247d0c4 GIT binary patch literal 27693 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 F{{hGnCrAJQ literal 0 HcmV?d00001 From 9028daa27b092744fe487d54482664a6e633af86 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 29 May 2026 18:54:00 +0300 Subject: [PATCH 4/8] Build-time-codegen post: quote YAML title to dodge colon parse error The post failed CI with: error building site: assemble: failed to create page from pageMetaSource /blog/build-time-codegen: ...build-time-codegen.md:2:8": [1:8] mapping value is not allowed in this context The title contains an unquoted colon ("Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie"), which YAML reads as a key / value separator at column 8 and trips the parser. Wrapping the value in double quotes makes it a plain string. Verified locally with `hugo --buildFuture`: the post renders and the rendered shows the colon intact. --- docs/website/content/blog/build-time-codegen.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/website/content/blog/build-time-codegen.md b/docs/website/content/blog/build-time-codegen.md index 6ebc30e9a9..3185a73469 100644 --- a/docs/website/content/blog/build-time-codegen.md +++ b/docs/website/content/blog/build-time-codegen.md @@ -1,5 +1,5 @@ --- -title: Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie +title: "Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie" slug: build-time-codegen url: /blog/build-time-codegen/ date: '2026-06-03' From dd6e13a16be30f1fb6781aec664f9cdf63d0d623 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 29 May 2026 21:24:36 +0300 Subject: [PATCH 5/8] Build-time-codegen post: major restructure per review - Retitled "Routing, ORM, OpenAPI, And Build-Time SVG / Lottie". The headline pieces (router, ORM, OpenAPI, SVG, Lottie) lead; the codegen plumbing is the "How it works" section at the end. - Front-matter description rewritten around the headline pieces and the JPA / JAXB familiarity callouts. - Routing section now leads with the deep-link motivation: what problem deep links create (URLs arriving from many sources), why a single Display.setDeepLinkHandler scales badly, and how @Route(...) collapses the if/else handler into one annotation per form. Spring developers get an explicit "@Route ~ @RequestMapping, :id ~ {id}, RouteMatch.param ~ @PathVariable" callout. React/Vue/Angular Router familiarity also called out. - ORM section gets a JPA / Hibernate familiarity callout (@Entity, @Id, @Column, EntityManager, Dao#findById/findAll/find), plus the explicit "renamed @Transient to @DbTransient to avoid java.beans.Transient" note. - JSON / XML section gets a JAXB familiarity callout (@XmlRoot, @XmlElement, @XmlAttribute, @XmlTransient direct port; the Jackson convention for the JSON side). - New OpenAPI section as a headline feature. Walks through the cn1:generate-openapi-client Mojo configuration in pom.xml, the Petstore reference spec output (6 models + 3 Api classes), and a concrete PetApi usage example (getPetById, findPetsByStatus, addPet). Frames the practical effect for teams whose backends already publish OpenAPI specs. - Component-binding section preserved with its validation annotations, BindAttr, GroupConstraint composition. - SVG section gets its own heading with a real static-fixture screenshot (cropped from scripts/ios/screenshots-metal/ SVGStatic.png). - Lottie section gets its own heading with an animated GIF composed from the 6-frame LottieAnimatedScreenshotTest grid (cropped, labels masked, frames stitched at 200ms each, looped). - "How it works" section at the end explains the bytecode AnnotationProcessor SPI, the generate-sources / process-classes Mojo split, the stub-then-overwrite pattern, and the three non-negotiable rules (no Class.forName, no service loader, no field reflection). - REMOVED: "The porting-exercise baseline" section and any other mention of how decisions were arrived at. - REMOVED: "The Metal / Android rendering fixes" subsection. The three Metal / Android bug fixes are not user-facing features of this release and do not belong in this post. - REMOVED: "What ties this together" section. - Front-matter title now quoted to handle the colon (carried over from the previous CI fix). Hero image and the lottie-pulse-spinner.gif / svg-static.png fixtures committed alongside. --- .../content/blog/build-time-codegen.md | 287 ++++++++++++------ .../lottie-pulse-spinner.gif | Bin 0 -> 15739 bytes .../blog/build-time-codegen/svg-static.png | Bin 0 -> 51992 bytes 3 files changed, 199 insertions(+), 88 deletions(-) create mode 100644 docs/website/static/blog/build-time-codegen/lottie-pulse-spinner.gif create mode 100644 docs/website/static/blog/build-time-codegen/svg-static.png diff --git a/docs/website/content/blog/build-time-codegen.md b/docs/website/content/blog/build-time-codegen.md index 3185a73469..6d5a6d5db7 100644 --- a/docs/website/content/blog/build-time-codegen.md +++ b/docs/website/content/blog/build-time-codegen.md @@ -1,36 +1,38 @@ --- -title: "Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie" +title: "Routing, ORM, OpenAPI, And Build-Time SVG / Lottie" slug: build-time-codegen url: /blog/build-time-codegen/ date: '2026-06-03' author: Shai Almog -description: A reusable bytecode AnnotationProcessor SPI in the Maven plugin, the declarative router that is its first consumer, a SQLite ORM, JSON / XML mappers, a component binder with validation, the baseline additions surfaced by porting a substantial mobile client app onto Codename One, and a build-time SVG / Lottie transcoder that emits Codename One Image subclasses for every asset. -feed_html: '<img src="https://www.codenameone.com/blog/build-time-codegen.jpg" alt="Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie" /> A reusable bytecode AnnotationProcessor SPI, the declarative router that is its first consumer, ORM + mappers + binder + validation, the porting-exercise baseline additions, and a build-time SVG / Lottie transcoder.' +description: A declarative router and a unified deep-link API; a JPA-shaped SQLite ORM; JAXB-shaped JSON / XML mappers; an OpenAPI 3.x client generator that turns a spec into typed Codename One code; SVGs and Lottie animations transcoded to Java Image subclasses at build time. All four pieces sit on the same build-time codegen pipeline; the details of that pipeline are at the end. +feed_html: '<img src="https://www.codenameone.com/blog/build-time-codegen.jpg" alt="Routing, ORM, OpenAPI, And Build-Time SVG / Lottie" /> A declarative router with deep links, a JPA-shaped SQLite ORM, JAXB-shaped JSON / XML mappers, an OpenAPI client generator, and build-time SVG / Lottie transcoders.' --- -![Build-Time Codegen: Router, ORM, Mappers, Binder, SVG / Lottie](/blog/build-time-codegen.jpg) +![Routing, ORM, OpenAPI, And Build-Time SVG / Lottie](/blog/build-time-codegen.jpg) -This is the architectural post for the week. The Saturday post was about how you iterate; Monday's post was about new platform APIs; today's post is about a shape of code that several PRs in this release share, that explains why a lot of the new APIs work the way they do, and that should shape how Codename One projects look over the next few years. +This is the third follow-up to [Friday's release post](/blog/metal-default-new-build-cloud-and-a-new-format/). Saturday's was about how you iterate; Monday's was about new platform APIs in the core; today's is about four pieces that change how you write the structural parts of an app. -The shape is **build-time codegen**. A reusable bytecode `AnnotationProcessor` SPI in the Maven plugin, the declarative router that is its first concrete consumer, then a SQLite ORM, JSON / XML mappers, and a component binder (all built on the same SPI), plus the build-time SVG / Lottie transcoders that ship in the same release for related reasons. The grab-bag PR from a recent porting exercise (a substantial mobile client app ported onto Codename One) lives here too because the ORM and mapping work share the porting exercise that drove it. +The four are routing, persistence, network bindings, and graphics. All four use **build-time codegen** under the hood: a Maven-plugin pass that reads annotations or declarative source files at build time and emits typed Java that compiles into your binary. No reflection, no service loader, no `Class.forName`. The "How it works" section at the end of this post is the place to read about the codegen plumbing once you have seen what it powers. The earlier sections focus on the features themselves. -Six PRs make up this post: [#5037](https://github.com/codenameone/CodenameOne/pull/5037) (router + annotation SPI), [#5047](https://github.com/codenameone/CodenameOne/pull/5047) (ORM + mappers + binder), [#5062](https://github.com/codenameone/CodenameOne/pull/5062) (validation), [#5055](https://github.com/codenameone/CodenameOne/pull/5055) (porting-exercise baseline additions), [#5042](https://github.com/codenameone/CodenameOne/pull/5042) and [#5066](https://github.com/codenameone/CodenameOne/pull/5066) (SVG / Lottie), plus [#5049](https://github.com/codenameone/CodenameOne/pull/5049) (Metal / Android rendering fixes that fell out of the SVG screenshot tests). +## Deep links and routing -## Bytecode codegen, not source-text codegen +The piece that motivates everything else in this section is deep links. Modern mobile apps need to handle URLs from a wide variety of sources: a notification that wants to land on a specific screen, a marketing email with a link into the app, a "share" sheet that hands the user a URL to a particular item, an associated-domains rule that opens the app when a friend taps `https://yourapp.com/users/42` in Safari. iOS treats these through Universal Links; Android treats them through App Links; the framework collapses both into a single in-app concept. -The Maven plugin now has an `AnnotationProcessor` SPI and two new Mojos: `cn1:generate-annotation-stubs` (in `generate-sources`) and `cn1:process-annotations` (in `process-classes`). The orchestrator ASM-scans `target/classes`, dispatches to every registered processor, validates the annotated classes, and emits a typed runtime artifact next to each one plus a tiny `Index` class that registers everything with a public runtime registry. Adding a new processor later is a matter of dropping it into `META-INF/services` with no orchestrator changes. +`Display.setDeepLinkHandler(LinkHandler)` registers a handler that receives a normalised `DeepLink` (scheme, host, path, segments, query map, fragment). The same handler fires for cold launches (the app was not running; the OS started it because of a link) and warm launches (the app was already running and got the URL via app-resume). iOS and Android need no port changes for this to work; the existing platform plumbing already writes URL-shaped values into `Display.setProperty("AppArg", url)` and the new handler intercepts those. -The reason this runs against bytecode rather than against source text is that the source-regex prototype was scrapped early. The bytecode pass sees the JVM's view of the project (`extends Form` is a thing the JVM actually knows, not a pattern we have to hope the user wrote a specific way), rule violations come back with class names and reasons, and the build fails fast before any generated `.class` lands on disk. The infrastructure shares the ASM passes that the `BytecodeComplianceMojo`'s existing String rewrites already use. - -A small stub source is emitted under `target/generated-sources/cn1-annotations/` during `generate-sources` so application code that references the generated registry resolves at compile time. The real `.class` overwrites the stub later in `process-classes`. Standard "compile against a stub, link against the real thing" pattern; it just works inside a single Maven build instead of needing a multi-module split. - -Three non-negotiable rules across every processor in this batch: **no `Class.forName`, no service loader, no field reflection**. Every read and write in the generated code is a direct symbol reference that ParparVM rename and R8 obfuscation rewrite together with the class they target. Anything that worked in the simulator and broke in production because R8 renamed a class or a field; that whole shape of bug is structurally absent. - -cn1-core ships a no-op stub of each generated index (`RoutesIndex`, `MappersIndex`, `BindersIndex`, `DaosIndex`) so application code compiles even when the project has no annotated classes. The build-time processor shadows each stub with the real implementation before packaging. +```java +Display.getInstance().setDeepLinkHandler(link -> { + if ("/users".equals(link.path()) && link.segments().size() == 2) { + showUserDetailForm(link.segments().get(1)); + return true; + } + return false; +}); +``` -## The router +That works, but as the surface grows the if/else chain in the handler becomes a real maintenance burden. Five URL patterns, ten patterns, twenty patterns; the handler grows arms and legs, the routing decisions creep into the form constructors that need to read query parameters, and the "what screens does this app have, and at what paths" question is answered by reading through hundreds of lines of switch statements scattered across files. -The first concrete consumer is the declarative router in `com.codename1.router`. The API is opt-in; the existing `Form.show()` / `Form.showBack()` flow keeps working unchanged. +The declarative router in `com.codename1.router` is what we built to keep that question tractable. Each form declares its own path with a `@Route` annotation: ```java @Route("/") @@ -39,52 +41,67 @@ public class HomeForm extends Form { /* ... */ } @Route("/users/:id") public class UserDetailForm extends Form { public UserDetailForm(RouteMatch match) { - String id = match.param("id"); - // build UI for user `id` + String userId = match.param("id"); + // build UI for user `userId` } } + +@Route("/about") +public class AboutForm extends Form { /* ... */ } ``` -`Router.navigate("/users/42")` resolves the path, instantiates `UserDetailForm`, and shows it. The build-time processor validates that the annotated class extends `Form`, that the path starts with `/`, that the constructor is accessible, that there are no duplicate patterns. Anything off the rails fails the build with a class name and a reason, not at runtime with a stack trace. +`Router.navigate("/users/42")` resolves the path, instantiates `UserDetailForm`, and shows it. The deep-link handler then collapses to a single line: `Display.getInstance().setDeepLinkHandler(link -> Router.navigate(link.path()))`. Each form owns its own routing rule; adding or moving a screen is a one-class change. -The rest of the router surface is the kind of thing that has become table stakes in modern client routing: route guards (run before navigation completes; can cancel or redirect), redirects, per-tab navigation stacks (`TabsForm`, where each tab keeps its own back stack), location listeners (anything in the app can subscribe to "the route changed"), and a `Form.setPopGuard(PopGuard)` hook to intercept hardware back, toolbar back, or `Router.pop()` with a chance to ask "are you sure?". `Sheet.showForResult()` returns an `AsyncResource<T>` that auto-cancels with `null` if the user dismisses the sheet. +**For Spring developers,** the shape is familiar by design. `@Route` plays the same role as Spring MVC's `@RequestMapping`: a class-level declaration that announces "this controller handles URLs of this shape". The `:id` parameter syntax mirrors Spring's `{id}` path-variable syntax; `RouteMatch.param("id")` is the same kind of accessor as Spring's `@PathVariable`. The mental model carries over from server-side Java with almost no friction. The same recognition is available to anyone with React Router, Vue Router, or Angular Router experience; the `:param` convention is the cross-framework default. -### Deep links +The build-time processor validates that each annotated class extends `Form`, that the path starts with `/`, that the constructor is accessible, and that there are no duplicate patterns. Any rule violation fails the build with a class name and a reason, not at runtime with a stack trace. -`Display.setDeepLinkHandler(LinkHandler)` registers a handler that receives a normalised `DeepLink` (scheme, host, path, segments, query, fragment). The same handler is invoked for cold launches (the app was not running; the OS started it because of a link) and warm launches (the app was already running and got the URL via app-resume). iOS and Android need no port changes for this to work; the existing platform plumbing already writes URL-shaped values into `Display.setProperty("AppArg", url)` and the new handler intercepts those. +The rest of the router surface covers the kind of thing that has become table stakes in modern client routing: -For the link-publishing side, an `AasaBuilder` emits the iOS `apple-app-site-association` JSON, and an `AssetLinksBuilder` emits the Android `assetlinks.json`. The full setup walk-through (entitlements, `intent-filter`, the `.well-known/` upload) is at [Routing-And-Deep-Links.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Routing-And-Deep-Links.asciidoc), with an end-to-end tutorial at [Tutorial-Routing-And-Deep-Links.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Tutorial-Routing-And-Deep-Links.asciidoc). +- **Route guards** run before navigation completes and can cancel or redirect. +- **Per-tab navigation stacks** via `TabsForm`, where each tab keeps its own back stack. +- **Location listeners** so anything in the app can subscribe to "the route changed". +- **`Form.setPopGuard(PopGuard)`** intercepts hardware back, toolbar back, or `Router.pop()` with a chance to ask "are you sure?". +- **`Sheet.showForResult()`** returns an `AsyncResource<T>` that auto-cancels with `null` if the user dismisses the sheet. -The JavaScript port bridges the router into `window.history` so navigating the in-app router pushes a real entry into the browser history. Back and forward buttons in the browser drive the router; reloading the page lands at the deep-link URL. The Initializr, the Playground, the Skin Designer, and the new Build Cloud console all benefit. +The API is opt-in. Apps that prefer the existing `Form.show()` / `Form.showBack()` flow keep using that; nothing changes. -## ORM, mappers, and binder (with validation) +For the link-publishing side, an `AasaBuilder` emits the iOS `apple-app-site-association` JSON and an `AssetLinksBuilder` emits the Android `assetlinks.json`. The full setup walk-through (entitlements, the Android `intent-filter`, the `.well-known/` upload on your origin server) is at [Routing and Deep Links](https://www.codenameone.com/developer-guide/#_routing_and_deep_links) in the developer guide. -[PR #5047](https://github.com/codenameone/CodenameOne/pull/5047) lands three more processors on the same SPI. [PR #5062](https://github.com/codenameone/CodenameOne/pull/5062) layers validation on the binder. +The JavaScript port bridges the router into `window.history` so navigating the in-app router pushes a real entry into the browser's session history. Back and forward in the browser drive the router; reloading the page lands at the deep-link URL; sharing the URL out of the address bar takes a colleague to the same in-app location. The Initializr, the Playground, the Skin Designer, and the new Build Cloud console are all working examples. -### SQLite ORM +## SQLite ORM -`@Entity`, `@Id`, `@Column`, `@DbTransient` for the schema; `EntityManager` and `Dao` for the runtime: +The second piece is a SQLite ORM, also driven by annotations. `@Entity` marks the class; `@Id` and `@Column` shape the schema; `@DbTransient` opts a field out: ```java @Entity public class TodoItem { - @Id @Column long id; - @Column String title; - @Column(name = "completed_at") Date completedAt; - @DbTransient Object cachedView; + @Id @Column long id; + @Column String title; + @Column(name = "completed_at") + Date completedAt; + @DbTransient Object cachedView; } Dao<TodoItem> dao = EntityManager.open("todos.db").dao(TodoItem.class); dao.createTable(); dao.insert(new TodoItem(0, "Read the post", null)); + List<TodoItem> open = dao.find("completed_at IS NULL", new Object[] {}); +TodoItem byId = dao.findById(42); +dao.delete(byId); ``` -The generated DAO does the typed work underneath. No reflection in `insert`; the generated code calls `setString(1, e.title)` and `setLong(2, e.id)` directly. Validation at build time catches missing `@Id`, fields that look like relationships but are not yet supported, abstract entity classes. +The generated DAO does the typed work underneath. No reflection in `insert`; the generated code calls `setString(1, e.title)` and `setLong(2, e.id)` directly against the SQLite `PreparedStatement`. Validation at build time catches missing `@Id`, fields that look like relationships but are not yet supported, and abstract entity classes; the build fails with a class name and a reason. + +**For JPA / Hibernate developers,** the API is intentionally familiar. `@Entity`, `@Id`, `@Column`, and `@Transient` (here renamed `@DbTransient` to avoid colliding with `java.beans.Transient`) carry the same meaning they do under `javax.persistence` / `jakarta.persistence`. The `EntityManager` name is the same. `Dao#findById`, `Dao#findAll`, `Dao#find(where, params)`, `Dao#insert`, `Dao#update`, `Dao#delete` line up with the basic JPA repository contract. The query language is plain SQL (there is no JPQL or Criteria DSL) but the annotation surface, the lifecycle, and the runtime methods will feel like a long-lost friend to anyone with server-side Java persistence experience. -### JSON / XML mapping +Three rules the design enforces: no `Class.forName`, no service loader, no field reflection. The "this code only breaks in production because R8 renamed a field" shape of JPA-on-Android bug is structurally absent. -`@Mapped` is the entry point; `@JsonProperty` and `@XmlElement` (plus `@XmlRoot`, `@XmlAttribute`, `@JsonIgnore`, `@XmlTransient`) shape the wire format: +## JSON / XML mapping + +`@Mapped` marks a class as a transferable POJO. `@JsonProperty` and `@XmlElement` (plus `@XmlRoot`, `@XmlAttribute`, `@JsonIgnore`, `@XmlTransient`) shape the wire format. The runtime entry points are `Mappers.toJson(...)`, `Mappers.fromJson(...)`, `Mappers.toXml(...)`, `Mappers.fromXml(...)`: ```java @Mapped @@ -100,107 +117,201 @@ String json = Mappers.toJson(user); User back = Mappers.fromJson(json, User.class); ``` -The same `@Mapped` POJO is the type the `Rest` helpers from PR #5055 will accept (`Rest.get(url).fetchAsMapped(User.class)`, `fetchAsMappedList(User.class)`). +The same `@Mapped` POJO is the type the typed `Rest` helpers accept: + +```java +Rest.get("https://api.example.com/users/42") + .fetchAsMapped(User.class) + .onResult((user, err) -> { /* ... */ }); + +Rest.get("https://api.example.com/users") + .fetchAsMappedList(User.class) + .onResult((users, err) -> { /* ... */ }); +``` + +`Rest.fetchAsJsonList` (top-level JSON arrays, no `{"root":[...]}` envelope trick), `JSONWriter` (the complement of `JSONParser`, with fluent builders and streaming variants for `Writer` and `OutputStream`), and `URLImage.setDefaultBearerToken` (auth headers on image fetches) all ship alongside. + +**For JAXB developers,** the XML surface (`@XmlRoot`, `@XmlElement`, `@XmlAttribute`, `@XmlTransient`) is a direct port of the long-established `javax.xml.bind.annotation` surface. The same model class can be both `@XmlRoot`-decorated and `@JsonProperty`-decorated, which gives you a single source of truth for both wire formats. The JSON surface adopts the Jackson convention (`@JsonProperty`, `@JsonIgnore`) that nearly every modern JVM JSON binding (Jackson, Moshi, kotlinx-serialization) inherited. + +## OpenAPI client generation + +This is the headline of the codegen post and arguably the most useful single feature in this release for any team that talks to a backend. + +A new `cn1:generate-openapi-client` Mojo reads an OpenAPI 3.x JSON spec (a URL or a local file) and writes typed Codename One client code that compiles into your app: + +- One `@Mapped` POJO per `components.schemas` entry. +- One `<Tag>Api.java` class per OpenAPI tag, with one fluent method per operation. +- Every method routes through `Rest.<verb>` + `Mappers.toJson` + `fetchAsMapped` / `fetchAsMappedList`, so the generated surface integrates with the rest of the framework instead of dragging in a separate HTTP stack. + +Wire it into the project's `pom.xml`: -### Component binding with validation +```xml +<plugin> + <groupId>com.codenameone</groupId> + <artifactId>codenameone-maven-plugin</artifactId> + <executions> + <execution> + <id>petstore-client</id> + <goals><goal>generate-openapi-client</goal></goals> + <configuration> + <specUrl>https://petstore3.swagger.io/api/v3/openapi.json</specUrl> + <basePackage>com.example.petstore</basePackage> + </configuration> + </execution> + </executions> +</plugin> +``` + +`mvn generate-sources` picks the spec up, downloads it, and writes one file per schema and one per tag under `target/generated-sources/`. The Petstore reference spec exercised end-to-end produces six model classes (`Pet`, `Order`, `Customer`, `Tag`, `Category`, `User`) and three Api classes (`PetApi`, `StoreApi`, `UserApi`), and the nine generated `.class` files compile cleanly against `codenameone-core`. Documented at [the OpenAPI codegen Maven goal](https://www.codenameone.com/developer-guide/#_appendix_goal_generate_openapi_client). -`@Bindable` marks a model class; `@Bind(name = "userField")` ties a field to a component on the form by its name. The build-time binder reads the field types and the components, generates the bidirectional wiring at compile time: +In application code you call the generated `Api` class the same way you would call any other Java method: + +```java +PetApi pets = new PetApi(); + +// Returns AsyncResource<Pet>; resolves with the deserialised object. +pets.getPetById(42).onResult((pet, err) -> { + if (err == null) Log.p("Got " + pet.getName()); +}); + +// Returns AsyncResource<List<Pet>>. +pets.findPetsByStatus("available").onResult((list, err) -> { + if (err == null) { + for (Pet p : list) Log.p(p.getName()); + } +}); + +// POST with a request body. addPet takes a Pet, returns a Pet. +Pet candidate = new Pet(); +candidate.setName("Mittens"); +candidate.setStatus("available"); +pets.addPet(candidate).onResult((created, err) -> { /* ... */ }); +``` + +There is no hand-rolled `ConnectionRequest` setup, no manual JSON parsing, no string-typed request bodies. The generated client takes a typed `Pet`, serialises it with `Mappers.toJson(...)`, fires the right HTTP verb, deserialises the response with `Mappers.fromJson(...)`, and surfaces the result through the framework's `AsyncResource` so your callback fires on the EDT. + +For teams who already publish an OpenAPI spec as part of their backend (most modern backend frameworks do this automatically; FastAPI, Spring's `springdoc-openapi`, NestJS, ASP.NET Core, Go's `gnostic`), the practical effect is that the mobile client's bindings stay in sync with the backend without anyone hand-writing a single network call. Update the spec, re-run `mvn generate-sources`, and the new and changed endpoints land in your app as typed Java the IDE picks up immediately. + +It is the kind of change that is most useful when you do not know you have it: pull a fresh spec, rebuild, and your IDE highlights every place in the codebase that called a renamed endpoint or passed the wrong type to a parameter. + +## Component binding with validation + +The fourth annotation processor on the same pipeline is the component binder. `@Bindable` marks a model class; `@Bind(name = "userField")` ties a field to a component on a form by the component's `name`. Field-level validation annotations compose with `@Bind` on the same field: ```java @Bindable public class SignupModel { - @Bind(name = "userField") @Required @Length(min = 3) private String user; - @Bind(name = "emailField") @Required @Email private String email; - @Bind(name = "ageField") @Numeric(min = 13, max = 120) private String age; - @Bind(name = "roleField") @ExistIn({ "admin", "editor", - "viewer" }) private String role; + @Bind(name = "userField") @Required @Length(min = 3) + private String user; + + @Bind(name = "emailField") @Required @Email + private String email; + + @Bind(name = "ageField") @Numeric(min = 13, max = 120) + private String age; + + @Bind(name = "roleField") @ExistIn({ "admin", "editor", "viewer" }) + private String role; } +``` +The runtime side is two lines: + +```java Binding b = Binders.bind(model, form); b.getValidator().addSubmitButtons(submitBtn); ``` -`Binding` is the handle: `refresh()` re-reads the model into the components, `commit()` writes the components back, `disconnect()` tears the listeners down. Multiple validation annotations on a single field compose via the existing `Validator.addConstraint(Component, Constraint...)` varargs (`GroupConstraint`, first failure wins). `@Validate(MyClass.class)` is the escape hatch for hand-written `Constraint` implementations. The validation set: `@Required`, `@Length`, `@Regex`, `@Email`, `@Url`, `@Numeric`, `@ExistIn`, `@Validate`. +`Binding` is the handle: `refresh()` re-reads the model into the components, `commit()` writes the components back, `disconnect()` tears the listeners down. Multiple validation annotations on a single field compose via `Validator.addConstraint(Component, Constraint...)` and `GroupConstraint` (first failure wins). `@Validate(MyClass.class)` is the escape hatch for hand-written `Constraint` implementations. The validation set: `@Required`, `@Length`, `@Regex`, `@Email`, `@Url`, `@Numeric`, `@ExistIn`, `@Validate`. -The new `BindAttr` enum lets `@Bind` target a specific attribute of the component (`TEXT`, `UIID`, `SELECTED`, ...) when the default is not what you want. The annotation framework reads it at build time and generates the matching `Component#setUiid(...)` / `Component#setSelected(...)` call. +The new `BindAttr` enum lets `@Bind` target a specific attribute of the component (`TEXT`, `UIID`, `SELECTED`, ...) when the default ("write a `String` field into the component's text") is not what you want. -Three new dev-guide chapters: [Annotation-JSON-XML-Mapping.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Annotation-JSON-XML-Mapping.asciidoc), [Annotation-Component-Binding.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Annotation-Component-Binding.asciidoc), and [Annotation-SQLite-ORM.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/Annotation-SQLite-ORM.asciidoc). +## SVG at build time -## The porting-exercise baseline +SVG and Lottie use the same codegen pipeline, but emit different output: instead of reading annotations from your Java, they read declarative graphics files from `src/main/svg/` and `src/main/lottie/` and emit Codename One `Image` subclasses that render through the `Graphics` shape API on every platform. -[PR #5055](https://github.com/codenameone/CodenameOne/pull/5055) ships as "Improvements to baseline based on porting exercise". The porting exercise was real: a substantial third-party mobile client onto Codename One. The port is still compiling cleanly through every change in that PR; the additions worth pulling out: +Drop an SVG into `src/main/svg/`: -**Java subset additions.** Eleven Java 8 default methods on `Map` (`getOrDefault`, `putIfAbsent`, `remove(K, V)`, `replace(K, V)` / `replace(K, V, V)`, `forEach`, `replaceAll`, `computeIfAbsent`, `computeIfPresent`, `compute`, `merge`); `BiFunction`; `Iterable.forEach(Consumer)`, `Collection.removeIf(Predicate)`, `List.replaceAll(UnaryOperator)`, `List.sort(Comparator)`. All four primitive atomics: `AtomicReference`, `AtomicInteger`, `AtomicLong`, `AtomicBoolean`. Standard Java 8 surface that was simply missing. - -**`Rest` typed helpers.** `Rest.fetchAsJsonList`, `Rest.fetchAsMapped(Class<T>)`, `Rest.fetchAsMappedList(Class<T>)` (these are the surface the mapper post above mentioned). `Rest.fetchAsJsonList` closes a long-standing rough edge: top-level JSON arrays no longer need the historical `{"root":[...]}` envelope trick. - -**`URLImage.RequestDecorator`** plus `setDefaultRequestDecorator`, `setDefaultBearerToken`, and a per-call decorator overload on `createToStorage`. Authenticated image endpoints no longer require working around the "URLImage does not pass headers" gap; set a bearer token once and the image cache and the `URLImage` machinery use it everywhere. - -**`JSONWriter`** is the complement of `JSONParser`. `JSONWriter.toJson(Object)` for one-shot, fluent `JSONWriter.object().put(...).toJson()` and `JSONWriter.array()` builders, streaming variants for `Writer` and `OutputStream`. +``` +src/main/svg/ + star.svg + gradient_circle.svg + path_arrow.svg + rounded_button.svg + wave.svg + pro_badge.svg + clipped_badge.svg +``` -**`Tabs.setAnimatedIndicator(boolean)`** enables a Material 3 / iOS 26 sliding-underline indicator (gated by `tabsAnimatedIndicatorBool` plus duration / thickness constants and a new `TabIndicator` UIID). Off in the framework defaults; **on by default in the modern native themes** that we landed two weeks ago. +After the next build: -**`DefaultLookAndFeel.drawModernPullToRefresh`** is a Material 3 arc-spinner painted via `Graphics.drawArc`; sweep grows 0° to 330° as the user pulls, then spins while the task runs. Gated by `pullToRefreshModernBool`; on by default in the modern themes. +```java +Image star = Resources.getGlobalResources().getImage("star.svg"); +Image star2 = Resources.getGlobalResources().getImage("star"); // either form +form.add(star); +``` -**`MorphTransition.snapshotMode(boolean)`** is the fix for an edge case that has been around forever: a morph from a source inside a scrolling container leaked off-viewport because the source was repainted live. The opt-in path captures source and destination as clipped `Image` snapshots at `initTransition()` and tweens those. Default live-paint path unchanged. +A grid of the static SVGs from the hellocodenameone fixture, rendered through the new pipeline: -**`com.codename1.io.websocket`** moves into the core. Per-platform native impls remain in the cn1lib for now. +![Static SVGs rendered by the build-time transcoder on iOS Metal: filled star, gradient-filled circle, path arrow, rounded button, two stroked wave paths, gradient-filled PRO badge, clipped badge](/blog/build-time-codegen/svg-static.png) -**`cn1:generate-openapi-client`** mojo reads an OpenAPI 3.x JSON spec and emits one `@Mapped` POJO per `components.schemas` entry plus one `<Tag>Api.java` per tag. The Petstore reference spec runs end-to-end. Dev-guide page: [appendix_goal_generate_openapi_client.adoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/appendix_goal_generate_openapi_client.adoc). +The transcoder is a `maven/svg-transcoder/` module that parses SVG with `javax.xml` StAX. No Batik, no Flamingo, no external dependencies. Coverage targets what real-world icon SVGs use: `rect` (rounded corners included), `circle`, `ellipse`, `line`, `polyline`, `polygon`, the full `path` grammar (`M` / `L` / `H` / `V` / `C` / `S` / `Q` / `T` / `A` / `Z` plus relative-coordinate and smooth-curve reflection), groups with affine transforms (`translate`, `scale`, `rotate`, `skew`, `matrix`), linear gradients via `LinearGradientPaint`, fill, stroke, stroke-width, linecap, linejoin, opacity. -A natural question on this PR is "why is all of that in one PR rather than ten". The honest answer is that the porting exercise was the regression fixture for every single one of those additions, and breaking it up would have meant maintaining a long-lived branch where each split-out item had to be re-verified against the port independently. +SMIL animations are supported in the same pipeline: `<animate>`, `<animateTransform>` (`translate`, `scale`, `rotate`), and `<set>`. Time values interpolate against wall-clock time on every paint, with `from` / `to` / `values` / `begin` / `dur` / `repeatCount` / `fill="freeze"` honoured. So an SVG with a rotating sub-element becomes a real animated `Image` you can drop into a `Form` and watch spin without writing any animation code yourself. -## SVG and Lottie at build time +**Important caveat:** this is **Metal-only on iOS**. The GL ES 2 path that was the iOS default until [last Friday's flip](/blog/metal-default-new-build-cloud-and-a-new-format/#metal-is-the-default-on-ios) does not have the shape API coverage the SVG / Lottie pipeline emits. Apps that opted in to Metal pick the transcoders up automatically; apps still on `ios.metal=false` will see placeholders. Now that Metal is the default this stops being a thing most apps notice on their next build. -The last two PRs in this batch sit on the same "emit Java from declarative input at build time" pattern. [PR #5042](https://github.com/codenameone/CodenameOne/pull/5042) is the SVG transcoder; [PR #5066](https://github.com/codenameone/CodenameOne/pull/5066) is the Lottie / Bodymovin transcoder that reuses the SVG pipeline; [PR #5049](https://github.com/codenameone/CodenameOne/pull/5049) is the small set of iOS Metal and Android rendering fixes the SVG screenshot tests exposed. They share one chapter at [SVG-Transcoder.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/SVG-Transcoder.asciidoc). +Coverage and the troubleshooting section are at [SVG Transcoder](https://www.codenameone.com/developer-guide/#_svg_transcoder) in the developer guide. Explicit non-coverage in v1: SVG `text`, masks / clip-paths, filters, radial-gradient paint (falls back to first stop colour), CSS keyframe animations. -**Important caveat before the details:** this is **Metal-only on iOS**. The GL ES 2 path that was the iOS default until [last Friday's flip](/blog/metal-default-new-build-cloud-and-a-new-format/#metal-is-the-default-on-ios) does not have the shape API coverage the SVG / Lottie pipeline emits. Apps that opted in to Metal pick up the transcoders automatically; apps still on `ios.metal=false` will see placeholders. Now that Metal is the default this stops being a thing most apps notice on their next build. +## Lottie at build time -The shape: +The same pipeline carries Lottie. Drop a Bodymovin export into `src/main/lottie/`: ``` -src/main/svg/ - home.svg - settings.svg - profile.svg src/main/lottie/ - spinner.json pulse.json + spinner.json ``` -After the next build: +After the next build, both are real `Image` instances on every platform that exposes the shape API: ```java -Image home = Resources.getGlobalResources().getImage("home"); +Image pulse = Resources.getGlobalResources().getImage("pulse"); Image spinner = Resources.getGlobalResources().getImage("spinner"); -form.add(home).add(spinner); +form.add(pulse).add(spinner); ``` -The SVG transcoder is a `maven/svg-transcoder/` module that parses SVG with `javax.xml` StAX (no Batik, no Flamingo, no external deps) and emits a Codename One `Image` subclass rendering through the `Graphics` shape API. SVG coverage covers what real-world icon SVGs use: rect (rounded corners), circle, ellipse, line, polyline, polygon, the full `path` grammar (M / L / H / V / C / S / Q / T / A / Z plus relative-coordinate and smooth-curve reflection), groups with affine transforms, linear gradients, fill, stroke, opacity. SMIL animations are supported: `<animate>`, `<animateTransform>` (translate / scale / rotate), `<set>`. Time values interpolate against wall-clock time on every paint. +The animation runs against wall-clock time on every paint, with no `Timer` and no allocation in the hot path. A capture of the hellocodenameone Lottie fixture (one pulsing circle and one rotating bar) at six points in the loop: + +![Animated Lottie playback: a red bar that pulses and rotates next to a blue ellipse that scales up and down](/blog/build-time-codegen/lottie-pulse-spinner.gif) -The Lottie pipeline reuses everything: each Bodymovin file is parsed into the same `SVGDocument` model the SVG path uses, the same `JavaCodeGenerator` emits the same `GeneratedSVGImage` subclass, the same `SVGRegistry` registers it. No new `Image` base class, no per-port wiring. v1 covers shape layers (`rc` / `el` / `sh`) with solid fills and strokes, layer transforms (anchor / position / scale / rotation / opacity), animated rotation / position / scale collapsed to a 2-keyframe loop, solid-color layers as filled rects. +The Lottie transcoder lives in `maven/lottie-transcoder/`. It parses Bodymovin JSON with no external dependencies (the framework's built-in JSON parser carries the load) and lowers each file into the same `SVGDocument` model the SVG path uses. The same `JavaCodeGenerator` emits the same `GeneratedSVGImage` subclass, and the same `SVGRegistry` registers it under the source filename. **No new `Image` base class, no new registry, no per-port wiring**, since the SVG path's JavaSE reflective load and iOS / Android Stub weaving already cover the new format. -Why Java at build time rather than parse SVG at runtime: parsing requires `javax.xml`, which is JVM-only by design; the generated code is allocation-light and deterministic (a path's commands become inlined `g.fillShape(new GeneralPath()...)` calls; an animation becomes a `currentTransform.translate(...)` against a wall-clock variable); and R8 / ParparVM rename and dead-code eliminate the generated code as freely as any other class, so SVGs you do not actually `getImage(...)` get dropped from the final binary. +Coverage in v1: shape layers (`rc` / `el` / `sh`) with solid fills and strokes; layer transforms (anchor, position, scale, rotation, opacity); animated rotation, position, and scale collapsed to a two-keyframe loop; solid-color layers as filled rects. Most icon-grade Bodymovin exports lower cleanly. Complex character animations from After Effects with image references, masks, and effects do not, and the transcoder logs which layers it dropped so the source of any blank output is obvious. -### The Metal / Android rendering fixes +## How it works: the build-time codegen pipeline -The SVG screenshot tests exercised the shape API harder than anything we had thrown at it before, and three rendering bugs surfaced; the fixes in [PR #5049](https://github.com/codenameone/CodenameOne/pull/5049) affect any code path that uses `setClip(GeneralPath)`, gradient paint, or text under a transform, not just the SVG pipeline: +Everything above sits on a single Maven-plugin pass. -1. **iOS Metal `setClip(GeneralPath)` triangle.** Metal's stencil clip's triangle fan was treating every Bezier control point as a polygon vertex. Non-rect `ClipShape`s are now midpoint-flattened into a polyline before reaching native. -2. **iOS Metal `drawString` skips the affine scale.** Text under a viewBox scale was rasterised at `font.pointSize` and stretched on the GPU. `CN1MetalDrawString` now reads the effective scale from `currentTransform`, picks an atlas font at `pointSize * scale`, and divides glyph metrics back into caller-side coords. -3. **Android and iOS Metal `gradient_circle.svg` double-circle.** `LinearGradientPaint.paint` was baking `getTranslateX/Y()` into a translate that sat before the SVG scale, sending the cell offset through the scale twice. The "translate dance" is dropped. +The plugin has an `AnnotationProcessor` SPI and two new Mojos: `cn1:generate-annotation-stubs` (in `generate-sources`) and `cn1:process-annotations` (in `process-classes`). The orchestrator ASM-scans `target/classes`, dispatches to every registered processor, validates the annotated classes, and emits a typed runtime artifact next to each one plus a tiny `Index` class that registers everything with a public runtime registry. Adding a new processor later is a matter of dropping it into `META-INF/services` with no orchestrator changes. + +The reason this runs against bytecode rather than against source text is that the source-regex prototype was scrapped early. The bytecode pass sees the JVM's view of the project (`extends Form` is a thing the JVM actually knows, not a pattern we have to hope the user wrote a specific way), rule violations come back with class names and reasons, and the build fails fast before any generated `.class` lands on disk. The infrastructure shares the ASM passes that the `BytecodeComplianceMojo`'s existing String rewrites already use. -If your app uses `setClip(GeneralPath)` or paints text under a non-uniform transform anywhere, you pick these fixes up on next rebuild. +A small stub source is emitted under `target/generated-sources/cn1-annotations/` during `generate-sources` so application code that references the generated registry resolves at compile time. The real `.class` overwrites the stub later in `process-classes`. Standard "compile against a stub, link against the real thing" pattern; it just works inside a single Maven build instead of needing a multi-module split. + +cn1-core ships a no-op stub of each generated index (`RoutesIndex`, `MappersIndex`, `BindersIndex`, `DaosIndex`) so application code compiles even when the project has no annotated classes. The build-time processor shadows each stub with the real implementation before packaging. -## What ties this together +Three non-negotiable rules across every processor: -The thread across all six PRs is the same pattern: **emit Java at build time, validate at build time, fail fast with a class name and a reason, R8 / ParparVM rename the generated code together with the rest of the app**. The router uses it to register `@Route` classes. The ORM uses it to generate typed DAOs. The mappers use it to generate typed JSON / XML readers and writers. The binder uses it to wire fields to components. The SVG and Lottie transcoders use it to turn declarative graphics into Java classes that render through the shape API. +- **No `Class.forName`** anywhere in generated code. +- **No service loader.** Everything is wired through the typed registry the codegen emits. +- **No field reflection.** Every read and write in the generated code is a direct symbol reference that ParparVM rename and R8 obfuscation rewrite together with the class they target. -The practical effect is that the kind of code that historically required reflection at runtime (with all the obfuscation hazards and surprise allocations that come with that) now happens once at build time and produces direct, dead-code-eliminable, rename-safe symbol references. That is the shape Codename One projects are going to look more and more like over the next year. +The SVG and Lottie transcoders sit on a parallel pipeline (declarative graphics files in place of annotations), but follow the same rules and emit code that obeys the same constraints. The practical effect is that the kind of code that historically required reflection at runtime (with all the obfuscation hazards and surprise allocations that come with that) now happens once at build time and produces direct, dead-code-eliminable, rename-safe symbol references. That is the shape Codename One projects are going to look more and more like over the next year. ## Wrapping up -That closes out the post series for this release cycle. The next weekly index lands on Friday in the same short format. +That closes the post series for this release. The next weekly index lands on Friday in the same short format. Back to the [weekly index](/blog/metal-default-new-build-cloud-and-a-new-format/). diff --git a/docs/website/static/blog/build-time-codegen/lottie-pulse-spinner.gif b/docs/website/static/blog/build-time-codegen/lottie-pulse-spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..5f2d85a26e0626f21cd08544fde20b78f25fd448 GIT binary patch literal 15739 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 literal 0 HcmV?d00001 diff --git a/docs/website/static/blog/build-time-codegen/svg-static.png b/docs/website/static/blog/build-time-codegen/svg-static.png new file mode 100644 index 0000000000000000000000000000000000000000..c9f5d8ab77d3c8d60e29af87e214136e5d556fb8 GIT binary patch literal 51992 zcmdSAbyU<}`!0-M3#C!IL{K^;q(N!v8ah;3x*HS;X=$lJKtMo11{h!@q+{rYA*DM8 z7;4~bpS6Bxz2`m8yVmdh>p91NT<gQ^&)j?O`@Zh$y7ue{4K)RV`_%VwaBv7-DavZ$ z;M`ci!MSOI`ww{18X)`v2d8KLmF!C$@9FJXkN0#F0X+L|{evsNdO0V_O1s`F-|6P7 zq?6hHOvB9_D&Ua*Faciv;ZBBtM;Bvf>{Nxl@*M;FXUZI<DQTF)L6N<<N`ztQq^S`M zi>*KLXh4X0d3vt;4O|l9)6qtg;Na9A@zR2Cz9oQz^XTgh9O6M7ocHhV;JkQo69?xX zYMg&Pz_r2o*Mq+wz_~$ygY);n{~aU#73Tl1dHlyl{A;=YzgG8uM%57&DTCwuGDI<m z5%)=w)??h9kUxXJ{Y1Zp5{D2gxjb$4<4(Fw5rW%7388$F#H-{E@u>Srr$)7CTx;z7 z5<FUb7>;@U!VbY5;!Jn9lWvY9#*+KileR&!xH4Y(2W%`**HGeDNQd=LR=19Z#haE~ z%ggRyiwk&1JhfA{YJ;_czlLGtU*PpOeE6*#hn;4?=W19Sm*woI?3s7ARp6&UbokTv zt>jj4oUArCN_5`YGzyP{%W0*w-lqEWh2G@eg<xvbALHwgTn$yZj@%+2{$f5@Fv1oc zve6|k6w6XC=<dvW!rky7-|VW3j><s9?4r9|tNY=7I_GZJIt?=F!;P$)-FjZ05;ZwK zBUfc*FBAFOmoVqSk_AQbzsqeSi3P~i5e2pdKV+F#3pmTw3LqAy{N>BBmX`eN{H!@c z-}+ely=rxg1~c8t=Yw8%5<)krH)E;=1X6T#^a~=~$hrH{<tNLD+JEdxx~yCC(3aUz zS<ySGxy*fI6Pb%99ubh6xR)QI#eQ*z?MV`DCs~<!d*TrEDvwSA6;y*^8KA8Xe6wNg zRBFJ-B?NWl4Ck;>YR%XGLoBU5m9h1FpmaBa<u2T5Ml{DaAx%lEc!3Bfm5@86#b&ZZ zs-faoDyYV*^TX~7HLEd8{(sKuB0HII88h*uX;C>FzoeyaJxS8&VTA}VjqF=lujuOK zhlTlVWnAz3qTOiH84yLQ$`~~ya$oijJoi!F2V=vfuVj!Ix!iD1$Hqh0WW8;?gwb=u z6gjqcgU+_eg7~V8A(z-zu{~_+1W{E73wNf-n~nO{2KO{|I$_4B)yxOnxQwm>q>Qp% zC;U&Oi5Z1!=uog)q(oYpCEB_V5ol0bb$T~$r|AG$ZZA2RN-}7|J)C!h!yO0`gdomk zdEpJIls;rtC3{^~)T`$CbDFRZ+GN}$u^hpY4v*f>oeenoU)1=yazwJ2J(JQf<YZk+ zc@iQF?PR*<k+5=KzW%girYU`oEW{b*;-Elu7fIfq7T6cuN*6(M9eB)RT0B5Vm8YO} z(|G$mx%61l4$X7D)RXTw==)ui`B0vY)5TQj3$#HvwGW3ymi4?CXzDjO${P@Q<}LNM zJ|l(1kfjt=VTzF0Tf8FBHVbC6_Vq>V+flt>TqRt_85a{IAvwiBt!ELG<Z9dN`4zhS z#G614UVDSv_XVE8{C8BfkETO#Z3w&nRrDm3i^d+AyUzbX`74a%#O`iJ_}=*@_>U=( zV*FfLxo+wH1X-t8Md%}0+{f}kjGrFKej2ICQ?IJLmop0IY~RbSwSO6C+1(^jk1c7M zesE%28xRu3Fc^$CYfdZS{H2qy|GVcWxleN38CC>dyS5HCeB$((1<oWc-1w>+)G883 zeX4XHSHH<sO4Rwxz;BU+3@^PAD>(CK+_91VM4Y7Mh?3PrlAGv?nzz&h{kmWoV7PbT zG11;lL?QGwbWp$&71o!ijEKQc{iP!;z%kF&Z-c7y$tbgv{@Qb6`EAU1^Jpz4$>SYW zv90rBD|Jm7#t9g1PGQoQ+wl%7HRG}5!5Zwwdd{Z8cD{}VR}?|DmSf{5(O-96Ed-3~ z-|IdUd`?@0s<u7oWp=sE7=p)6nJvX6s<rZ4pRm^Z<7TiaNc*Pid{r*8>cp5!e@9fv zu;%Rhyz~whYNWM|Lbigu+eCh(R)tO3BIbIGXij{b1Z{KwF*Uc^3%7oPa+l>7baC{V zl2eRN^Hq4+zyDn&B9CoHTl?W>DL1*bT$t8Jo-=G-@0wq@BJnPt$j!h;1fw2Q_+IU- zqkC;SHS6c@;aLm96&kNHBur&qdNCS*Bd?-us&GLs57QgWe+|)4s_lav&L;GpWM#mq zD3LcPZd#7Io=RQ2rm7}yM<ko`9WO7suT8{C?nQg5B2%-Cp4lBTjE_py<V!4%Xso~Y zlK6UCQ%8_GVti-1N^x9h{riJU@8njPN+cw4VRi-aczNWi7JgRkuoIftLzb=HMJVPn z9WB}9c~r+QI=iB1(%D@C{qEaveTI@4O3LGn3<>iR{93mVM%zRpAz%)Z;jDB0K<mZ) zuM8pjn<2lW$-F1jedSeA*uG6)iG|~}71vIQApvshcM4H%Re1whLmQFR3xwA6c@|1z z@S74_n3G!p)J<*FLyu?CujZ8PJe#f)LbBG%`%N&xSDhZTaycj=`!epG=Ple`YMjxs zY$R}6<PgFQ{T!lAi)wt&^^4of<Qsnd%BI`zlE#Wc>m_JeedOa}yWn4)G%bJp`Oil^ z1?t{=3gowW%=AW*j;&$O@DylM&F*i7#hBKsXg+M^os&VPX(|!4YCN>0CHluloil|w zL<7>d$8P~2MzcE+cYJb~_W1QYa5<8BF*x(m4)5i?CA4*$X^>lMK+wrzZ>EZLzZVjw z{FF@n5Rc7t=?(X1$xxk8$)>t?($Vb1K9iTYbZkTnK{t|bE`@xKt0dLYV5FG&JRg6( zb{eICZR=8252)~uxO^ruFz5j(=c%c8#zNtFI~B#!K|OycTvo}~jCUE#qo0w-b^7`G zDk&-HK<GNHY<;zt{GMnj(RJF|+jFwA?w|QzmU`OVV>F&fzPs2!GANA;f!w|D^>px+ zsdXIw#$6a4fu_9r;o)^6GIYL?=<s&vncQ=w+k)No8z)P47^%zoYnmQh(OAEJDXKLc zNJx&Gst~ske1-zobr-7slfOei^?~#xJjS)>u6UMU=m}xQmZ#TkSWEBHVwucx(s(>` z@=L#z=%-20%Rfiz-&zgJoP|i|my@FD)9!H#4{)<hdi{JeJ6C2)miVB+uLAnJh0>_f zsxL<-+^R3#<9JL@EEYYgt-dqY;CFVoA~f$`X=$*OTo{=feUZ#Mvf55z=D(7x2R?iJ z`zBF+b&R(-boQ55xj|*Y*RKmFD5nVztX5Z~+uf?%;?|o1ao0zFtynC7A+JnLBAaJ_ zbb+j}@vo(KBl{vP)P8?7l|p3r`FD(XoJ^Z`jS#DuXbopItSNoO)&(J|os4W`mHQ~1 zFT^iaKb3)Zc6Roc=gzQ4z+Ao0hZipb6(5&Me!9^Yx(LAt$x(~u8bHW`p-HW4sYBAZ ze8sl@;(6V+{D$NL>$ZI9#JdP+@6SziqtDkhZ6UR{6y@&9Y&)Bq#U&*i+}u{tF8$^e z`s~S(ol8q~PveT=H8p#vnt`q3{w%SHJq-GQra5_TQL{#f0`3=Gp~&pI+(j}Xz>{T_ z>DwQt%b#4F&WGKS3cA#rKU3#A*)$U;?q*erzr`dA{cIg;^BC7FBH-NWMt(@`(dvqc zkeOQ<EZ*3=g9j1k(}+RMa5y$@eP}v;Yvnojg~)SC?nRuL=3#aSab&K$msh!Ab<Z9~ zJ&o@PC4TG~$<wt&lE><)&rq}htR4R0nPpy&vEzqZ{Mh`FU#X4FwAiJM`P&T4doS?P zckCz?r)O|aL$=e!imvu`QA5irQ~?E^0wmme9<$k0GXYgnDXyK-E0h6R-EKSqfw3Y! z9hsRM?@Z5SMXSGkzOp*MonAl{#)wB<Ts-G7VUlX%IhDkwEpNS^){oY%Ve@*0+bp8q zl<;hPeEg&ZkH^B=8pPSYhcUDH0=2y>ye2f`EF&i;2Z1CP7x%NNOC*cAO*gg;q2iOh zOeO}<0X*(f>e$v88G>}Jcllap?Uq5<>&A;V9{RICLP1yYG)85H<ScB9qSkC)U3=L} z1*-a-4PTnmsQV*3B6^?!qNhjG#mSg}-EpFMq)0{YgC+Db&yOvHxGGzI*_L6-lj|{F zfjt-cxXz^mX3_|Efi1+YaI9^5l2%-&44dlpqkNqa0qIX$h~na>iLa!)z9eLdx5|4J z3db%9$BL^eWM`Q(ko5VS*T0GOX_#|o>w`O}j_5!<OeWwC-!_HS_jD&e6fi#izIsgD zZ#gh~P;h{<Rd~R-9$K9jK^$_<A1pCTmxYahi8tBC>4+>l_?=r+aw_98s*|GNCKJh! zU(Z+yb6NRJArL{;5f~=~LeRR9iGoX<izmqxaw3NXVzk)t1~;reY$49h&YnDZ0?4hC zkfo7AW6`C0o!&;@CPIxZ*_wxuIZdUwc=OnIh46tiz6^uglc$N@X!Vk3ow8S28+3%X z{!vclu68go4T#KTjeP87iW{$#zigUcetu*HvW9T{8Aa{o*m8xcS&ntLO<nfJZqLwN zrN*J#WVK^xnz4Z&Itgq&3fG5d{?)#-_L^%u%;HXVy_YcYPwxaRr8!rzJx(dsTO`5k zHzX&WF4u+90(OU+uEyt8(**g+BOW}KkAvzy4Aq*RnVA_HidT6WAZh0E_g{s$08c{| zqM{=HnHB1!q`VPKVXZGCH8qtbgjdxKnZo7a;SsMWtC_UDy*)iWU8G&;+D|68v9n{+ z;45fu-yTT@KH$`NX64|p1M<_FK1e^co|3k+sH9|TW23@Bj1oU3HFa%u6;VbL)lToX zUGd?=hZSV%K(>@rvXZ6}1VTqi>3w+s^5Zl{XinH;Qzxwjyb_DWBFaD*6ciLS)z!x* zCwD$J4-ad7W2d@y8O)@<1A(NXwcld6YVzU=57VZH3OD$fLx_XqzgIU_`0)znu-X`w zZEFpAG*nhr*40hHet`HR9<XRBVfN<t5RPE#o}Qk1dJ~&tB@jph0HMvzO}OK%sNMJv zG7ep0X<t9T8VA()@Nj}sK7K1JCugRRlPMS_s{2q*#ChR&W5C7Z_)l*rM+#IkB>X%P zD;!MQ8->|rB_&2xHbW3S6U+31-lN6E#g2}S=H{0W2pWy%U}qOlt#mNbO!5}LIvP<2 zbG9q13v;_V-zp~}AfO7<G&Zhx-x$_lwJ;b*@{~*Z9(~Vc?Y403OBej`VgZKaM)voo z#QXMJ<rdfiC@w86t<YDQIBscafx-Bum=Ap$%Ign%Qn-u?RMK40eL@_OFpsTq3BMDS zEYWI^p2>QqRJ649=zg)N$Vk@w2-)1SGRN1i-@8GRlOdX#B=~o<i$*u_>LXhy?HnAE zr$}*cDJd(1$Ond9hdmm8{rZ)k|AaisHvK8lLvt0#7y-?5`^ld<wY8_QV!Ofvi|v~} z1NCn+(KgJYcFn;-*zW7ALqDnW3n%OW8iP^EN`G{Z{T9`{pG*HeZQSFCQlpzvK?vvR z6{4%N?4arW+qp6%1*~~uci8d^Y#Wb;l~HhqsCIe!_cZu-D7cNivBwj5jN|2I^C%Pz z?k(XpBe=Z_t#wPtJy4e)KYmmfKWKwW_$_Zapvub2=NtSmJ;@y9jpy$=^!d_eD$K*@ z_X?97XAy#FD&!9zMi&(wV=z(|+m+!&3@K;IY<=C`1{H7HTSD<<az2-B5fBj6)ztyK zO{>QdP_?tS7x&(O4RXfRl-~SDWhFYz8ft4}qnNKHjoUOIG-2Wea#RvC;|3bJ?|M%7 z=fXWj?Q}W@4VQF)Nj3_J@gDnXi9?0aTc6E$byQzH$y%&U=62!j7%wxq_`Cl^M95#q zRQy)P0moy1XY%{^?@q~+irm~_eNMP}C*f2MEa2kAg3mx---fayo=M?qKU~V)-F+Rg zi@5;Bv)CGr*`9Kn55Pe5^fC&HY^SHI?exk`vlN*v&h1g~(!4x#6{>Gw4=XAv3JT=m z<r4G*V7W~F587j638(Ond>h8b#%g9gjdXQWh+AATLEbQv-pd}S3A(=W7B4G)$DS<e zzOLcshVGQQa-mW`RI1{%Tk41@E>=qyU=tF;_&fd)S>tKCJY4O|u>46X{m+LN02M%0 zvz8AwH#dVy*xt53yEi&K40Av|?>~b(pg`3v=j?ln`(btiHu6&qjf_?bV+(A-hEA9T z1*od_71?%ECQkjGx+3%AICW3Y6PP8ktoBdj2>BqHoB?1XV48RD+_5m9**aFsc)pWj z<k;QU*Vo&-y|qO{OKV)~y!h=^Vt*k9((tu{GilgcV3o+~@>uA~qpvbG;NrT`ug}s0 zGxspRcX74Ok8nUNiw*7EIUIOZG6)Y#W4QWb##3h{#|Kq;lCZt(63cgJ3O1<PZo<mS z$}|Xj+}_@9Vq!ug<Y?UB>+y)V_OORz@7G=<lS1qdlV7?M$6|Z+{7g)FU%$S<t$5QK z#$^OgN=lk>ZY2OyJp48VU<Bc@^;8`y?(#>LF=SvZFNq#3a=Kkv(f9ATq0$>xpX%TE zEQV5e?#-F#>cU?)2RjQJo0(m&W;jV6k7_SEd+*Lnft;JJaWXS9G71U`^7MpT8kB9( zi@3_-KJ(Zdy}Y~xi_ennf4DxB_u<9sj%X?$A0I9*t^uiQf3Vf_d)8mf&tf5>-*a)L zBNnVb&DKoE((|7<y31$toy6iw-ztn$dT99#)*QO~Y|bCuM`7yy!Oc`li_hoKg7I&~ zL48)KrXs}~6-L+4B+{|8A~4sLp2NdKXW>l6w(Ov*v#_u*5x3PJ`W25K-X|a={9D?c zv2=j*s`~iUO>9ZHuMegR+R=8V@mcod%0>P2;rCFULXG{DG#j0S;~V!^h7-pK1VVu! zKp<JE@5?ju!{zQGop+dBz<T%8^0gSQPditj-s1F(Z6`Y@(7tM%7p0}UV(G*Hq8pl- zHMy<z=PReqxeZ9%C8V9KbukAUbv$m=y7;qxLflWWJ7o~G0Z=QYTj$$TmB^l+u<&s3 zb`F#gDCoF)Awhg5lMk8@!H4&&tE*R5S0#@IWdfU;s;Z8_lEz7%uMZAtyn5Arv@t?u z4tf`WjyS2SQw6E>p(5>)P7Ch*qfiP{{TfHGgX5889Imdepp}9h#a^NZN{SKoQ?Q|X z98w)1cub)bHsTrFqC25Gkp=Vz)r{v2XR8^Jx&EiE3}wZ|#Xo)|If?olE_*HKRH$fL zq#aMAoHE3#R~MavtmlKu&yaD14<Dw9OTwl*P;4Zm()yo;XpgT3_Fz~`p=<Q@rK+js zD^60eodwwrK(<9aw<#Gdt}f4N<^zq`E&J2>J9(p1O?`_R8v_siw2u_3d(f^`PneoV z15lwLBWquBLBho82QJTm1C?I=y7?azoS+r=&POoifPer{35hJ~2~H$&oq9j?T~H1+ zBC)L^sa)ytE+MnCAm!-etXF!HqsaTznR}<F4X1KNJh$~792_7Jh@+#UwY9amxw)w+ zG?!IIMn+XtHSCQ_8lT)mGN^vR=g-fvS2T{bZ@Lqn9MXZ!Y5)RgXqK86%1R>5is*mX z?qYoQ#&0(|C62*gY-e4&Ljh^PpFZ(5ojv4{G;gR}-Vj(!kyw7);ctF>4MHp|;lwbT zp<D%eA7<*9*t%P!5p9AK#%@Tinl8`Q{e9<`FJB7Nnl}3TSXx@LCl~+Ve3h>SIxZk4 zAUM-<ueJUx&_F>B$S|CLu7{*zJ%Y|hvekB6Q?poM&nctYQ#cJ=L0>2;?xD;8>CY2% zh6J#%JyYifR2|=RLih3ygUa2;3&*K1KmhHouM7L1IvW{f5Wk(SvK_K<$DSXj7pMZ& z!NS6lCf;d($0rA*pTl(3E2}?$K~>?Mo}S+Is!$U^5kCO5f7;O_mPbbeqOs<b9kX8Z zCZ?v`C1d3cC(|H3EiG4W5{W;G%2ZC_JnM4`tOPXyP)se2&&NGWVdD7XT_Q&moQsxl z9<VroC$6;N&vZ33_Cbc0n>7WVA8k-kQEi+@Urr$qq9X!!c6NIW7}Gkmh=@oKNKKH> z=jZ2<QBf?a>C86`$JYmZVoIERV5;uITE>Elc2cKT3_%B7dX3jXnE64tzd`huV6mf8 z!F-WIl_gorflIcd?elvRv)6SQd%wbeG1Eu!6=YW0&QDBCpimU}cS4C%%>sQ?Rb#|6 zR7cb>7X~R$E}jUl0e)&!=bFETIPexvR;nu#6Bp-HzS#IDQM@hjsj4e2OPWeSr{6ba zkHf9l*w~z$?`2!*1+%V5F2Ke?QKzX`Sy<@k>D5$K(Tcb(1A;XoP@12gUsF@_{rmUg zV)nEuYHDguWN}$p3Il1T8z7zBCcdZpi(z4R@E5(;tg>8?<Yi){U#+7}d_kW#`qKKi zNqCl)Tsk5V_GzmNQC0A+l&eodLIP1{7I?M-2t|Z!FtL`7P8Fzm7O3~zUK~b~2^O`? zbzwF3<hRj2;?Q5a2qZ85h(LH)n94}B?BgOGCC!KZbz8tz2ke7X8t~1Oj10h~mtz(H zSXoY;kA9#^FL*BC4u`|Tq;ojR>xb9SPZD2sy0CL7gCs>wPx~%+#RC8=2#*Iu5Y(E8 z<iH+=f}EUQ+?$s^&aIydnV^@leHEWK)j#F0`!K((jGH=!oQ#ai1fhe=Sl*VNp1xJ~ ztE{q88!|Q$R=<U~efu`(Au#e8z(Qwcez5*U?fdudTZjly;+GlM@$vKXb8sL9vWBvQ zl7?HuiC9P@0JZ4_@B-tU60CM!Y}rB8fWxrof`UNMTIPx2TQVhRQOC%mP$)b+Ji5-J zqN20QH7O^Q=Obcg+Cl`vcNXEXv$F%15|rcG57+NbXPnlNZ=Y(bXwsivS{L-DA8hRf zS`XxuW@Gn%PFP2b-j1uK2<B}P8@0Y%_o9;M2YP6AUT<RjX|4-no58TbobKrOIK70g zJ3#uZtgHttYDp3yVDn*OZ+m$uI`k1vUKb}jfS3S}LMdM>cB!j>{27z04kWoIFmJ@b zbG2tkdTYGY53tfWdI>`a<cSzJV9P7*FL2XDJvPG#Xuz_8&gbgpw!(@8L<h7(m8UBP zTE@mdY}4yIj3<tL8vuP!h^2j*(5Nl5!@2^%l0hPPiIz%Y__3t2n6FC2S(4`w8yf!} zW0J-MEM%u=mBErTUh$h&5nxhN^~r^q4k$n*Ow09R$0=uhDFa-4`T?I9@0PSi!j=uP z9M!vSC>Iy6E-!xzQc5`l`$9uQqb@X<f{%~?rC<Ynrdw*ba^P)|p{JPyh0?2zfFfQF z?BPwm;P+jaF1mSZ!0o5uxtoo%^Po%S<)wd`i)%*NmZ?iS8SKNJuz&CPGEt8UkE;-v zCTT>-{2mWGJIul8YPY~vS4T(X3vaW>?2&Mc`;E$`CNs!be}BIjc2jR7=ualnX#eW! z>X{JG{s21Y#5@IrgrqL_TVdrTwY9bN^~Qle4N@Tb`ue7(jb3|m;Qf)2kq103(R3zV zKAfZ(4bCoO*Sgn0U0kBBeYYzyCo1J?pYYQBnQ!HUP1bXrMioX`o1QJKNnNnT@etF* z^2v!@=q_hl1LG>XqSUAc)KcR?2aWV64OSgZO_y1ZiS7#8Lb{|z&{Y5zz+(hhrmUpo zFUerOJ(wfY+S<Anv}p_oAF#d1)8lAGa#@wEtX4;hwDro2sqpWpj&Snu@UXGjzI*r1 z$%*LB$K&H;$!sTp<cCSgHJ`)YMDOOliu)Su<@tNI%e;1gCvQHjZXtwt*L79{OP|cZ z(4I}t?ll}*T+H{fpKsuCnhKy5c_0DNXZ|25KfHKEjNA6MLMEIr%dPJtzlXPml7;q1 zx4D@a&J3OnVX(9(-r~Drb<bnBKP0s(%J0GJPX;7^cppi1KmAGjUC5WIYztAw5%M{8 zalIp(_A6<GENFP^A_RysYb&dsGGt;HlaVgy65&#pi^p3NHE_V45FY5&zQgBlfyxIu zx6%OxC^q0|^Nj&ucA$|^4XCwLCQ*=9eBmKJZ)pkyl)CcjVomC@<QJwdlZ1pV6xzub znW??%G2zsG*<LKdaF)?z3iJ2jvwiyDo@d||w5vY`0M^@+?J0mHFw7ZP>I=-CkSaPS zoSs@@RTGL$FE~CrvY)Aqf944`3Gio?*mM<UQa~nv<XfW+R*S<6Z>^d0-AZ_(?Ca|* zDkc_3C#DN9{Y~o~In7<fR+$d_3g)6vEz1zd{mDs6+*{x?92^|V%E|!un4Ch0VRTuN zdzNFjNtEWg$F@INx^yx|J`MSLB+i%qjsN@~)X>Jk(9v=<{f5DEMUIVb7i;gyRP5^> zMPio3S5#3ONw1hm4>LtZY>T$e0fi%?75<!<h|VDj_>MrNyK(#7{`-WRqU*yoh?vi8 zn4lZj0wa#bxPOj)Mb?0@XJR;0<fT-Zf8SFgZ>qu9(h;yyH`JQ)AVOA@cx2)$r$qLE zm~VrroaXZW{xj5CX13vd>*(&cLx0+%KzBDB5g5UY!?532BRMs`6^eDy92rzvsX@gJ ztTc^`P*>QCjEoGxkfl~vR#ujmyXHcH6$0!+Q11qJM36Z&*)IR6XxbzB5>E~@obav4 zpOSLFITHU>dy7#vr<J7eYyG>a9=o?g!d|mz+TV``N^jmJ1SBTP&D6j^#A&YnVz24C zAj1)u4}bwSG&CHBu}b`-Loe%tK=z9^&GRT+2nh%PyvYoB$!RjtU|PP-LPbptRNDjy z4I6mf7V+S(W{eBET#BOL0o|veL4rK0JLgclK;_=8e}GUxH3s~0K!FSdwQxx1=H|wh z9}^QZWTWF5?AI^{{G@_{r*#%LTHNbP24tO0ArF~lC)wP-`9HH##g1^_3(yie3H_nU z-cf&gsvPIUMiOCp>*!J?ZppQOHaa>QR91}q*4EZaFI!qM470J#C@dh*CNj|5`=hAn zmC#KhI#Fi78Vd<tDXDB?*Y&|18-Y#q*+aR53oLLBb~iUgs|O;rdPKTG30`3172DuD z_4PBac`5IQ0_eBQ5Dh2{k}R}Cz!()yv)0VGgoN}6@fm1olhBUKYdt`dU=p)0EkI2n z0^#%?Q!4#EJ@@Z?1k|#kLi4HQnla)1%LA}DGj0RjnW|o-?2(VdaR><s?|giDwgfYr z1q^9?{AsuvM<hrm%Ppu|AP^-EC^#?_Qj?N;GeyvFl%wCmhr2Ks?9YL>on1+BG28(d za=O6mBqG|IuHMT0s6Q#}S-(z??Ya^rkrK8}XJc^oFkMu;UD1_bP^37~*l{k8U8ad~ z3q+(BoGmA+Uu|1Up{i`P&)vp6Onhn~!1hNThFTf`;SH;4+r#*YLv`4z0f3~Wq}T`` ze9)`bP@ktJg33XWFikWWncP&J+nRZt#Q4zA8%lX6r#+@P@xv~rI9gG6MaY=@g&y?9 zVe4<e6`o8^P1S)00QL!V(<81N{J%sFD9|^+wjv&$n85V%4|M&ZI6R`GY<_94*9%Q5 z<!FoUkSAxR%*rT?n0;m^ntl1*$%TI4jmVB$vn88&awGx%z?Uy%C$^an3~Wn({BWnW zZVe+4^W6SixCNXGA^S<*r!N$;GY|ji?deI#Ulf}2Hg|S*e*Jo(ZVig6_o>A9H4rH( zEgkb{C@tM7Due<RrEg|74?4c7_u}oTRZ0`<L{20(C+Cmi;>h;5Kw0i?ZzmM`0{qzv z#Qb6a&dp!pI?=4)^hTvAO`P(Oi7`zDUR|9vAWaLaEClJy!BNuG6m+~f2C_U>a0YlD zfawBv<YV(!S~>oLR90*@j4~lH5vUnvAKsPQC0oAA%1FENhNsFe!g31o%nEiuYm&(s z1VY*@2<su@m+00Ah(Y$%Q6X4rMP||=j{q>EZkFtspKm^L$}|AuLJGT~u2*UZoJ$oP zD%=gvnoEwZveCaj8nm#|AMt&u);Oo2#1Fpv#dyZS!kJ!TzJk`(XT8_IhIPjE^;+ZM zz2ua%Tpf`CDO1oIfkp%`JMQ5qud1m5`9?@Y#31fHD9{&*N3puL#*$bR92^Y%Xpkan zP`|&;#%so<6L>Y`occd~k2ir@+nK6VxPt{S2M87rF$)Op{17*&BJ;AD96c788rInX z@XAVl&?`?DJ|-t819^n1aSHkq!9qwc4uBq*2Fvq-yEAo?+3JBEzT!||U(*XaKO&D( z1w6QaL+fEXd<VF~+@|%X#}j7r^*(4|tV!o+0AVFB-%({d0vgjtP1?P-Q-Tp!medgT z`~PI!Y`tm;eqcvOXJ);dWEf7IRR6%OnN3?u<{1mrSb)n6LPZgBKc{$eOwVj~Zf<UD z>=-qF^_+)iz$Ft3g{JXa1D;;6<#f0_D!?^+ZI!+Xz6Ov6LR#T{kjp?4cEC7+=>|A5 zfXE)cvic83_1*{P$6GZ{^Nm5*fhH3`8jy1ve^F!xEjrz_UHarT@*PgTJ5bhuA%ph0 zx3vX|+|{H8IDI80cEBwG+2cm5pjN2HOlm&f{F9S|J`M?Q+CqeehNh*Z0rsmddA3aB zRPWMB=LP(!Ov}}(-tqeSdSHc%1DDBFO;uA<Q-C^|>8tJ!{bwNOP^)kU<Z*(0)84uz z4bWk!JWfEyJ33yCl?Oi2+p&4~ZgXcROTcy*IN?ujxtItgD|P=#a6plfk%3tJfYk>Q zQHl=e4;B_{XXpLN3iA|86R%kh*OWbw>88FL`Mtfpxw*NUo86!*INI9-*=)^84*GVY zwg+IT1!`HMAdV>!ThvL&y$8X~U+ojKvJO{xu9v*C&V$h`fmcl&)_d&SuAu=hvqF-5 zW#3NDy0BVz3+jobxIv{jQMW-XrsXwFO-&UQ2f)VxtI+(~c?xF9q5I=Ahaosr{qyIo zL95c!M4(){dV4v!xB$FC9=5NcSJu|dK&*Ha+|lxR1_lPeHw8Mlz&5SGz}VQ>#Dt3? zEjdvVn6e;fVEVJ>KX|ILkcl}u8U<)QF+qfn|M1~M<G*hp=TuBh2_ar|7G`2H|I-%X z>S%|EEG&KpTqM?q;3zagwnd<?r>Dnnw~mE6hF;RY_UBLM@gD|?V+UL=!ew3eXvAU( z?WHCY(^BPhEG@WPeg9lDxgUA4z6x?06~d*%-lRBuE6PWiQKWQTVHN)=aL2r|@*|>E zBrnMg3g81+cp}UK<WWF)g1rWX_ZoQa1-AX^f+atHYLFMLbZ>yJ@@j$?|129oKlTd5 z0xZqSA3r$h<5E*n{?ZIJ9;kq=mb`qJvHw#_{J*sX{OnYj-KVPQI>3TZ_ozF_%%nxZ zD`7Bp4i3O-)Ya9swYBy1Qgc~>3(<f*L9G}&Fv<d735hHzD(dd)`iv=$ekQ`@2fY15 z`0qW;+S(fOr8Y>poHlDGC8T|_-WG6ZoSdBO?6!cp0c<r;ZNQh+D|B)O{J`$ryZd-} zZ21S?#<4GxMw(aTfu#s|hUy3{Ev-Emv%RhJFdq&-0f*%S-Q6U?vUx+mS=ZIo)z)U} ze5&?^mk}71`1k<0fHi<mKmeGNiQi5&a1D|b*vO-R8TD5k>;HVAnFQ=r0Ac`)0Hp$W zlafO2^VPB8czkHZFRt?eVR%$j6iC_u)6JZZA1e;@+vEM}=gwsm0?&@`USrXB8|c-9 zB}T-Pv@7*+r3HuQOD<7N=*H91`PJn$Xn;t9_H{^cF@R2RJ~Ra{Eq(`<nN|i`#?cLz z=Oj-&Ch*a4H%Z0bgh3xo#Kz~v({@_gTU2~Inyz*=1uQwfolS&WON~E9_Ho%3by$2_ z8WrxX4wbP~IzpJpXZkbNPUW6^S3o|RG6H+2xL6WMFfp&)zovNrW_In*!841??6n48 zg*7@epC^8AL#3py+Y$y@9(&O8i(<19Cj`u+?|IE{#!U401RTznMHbpCv6}0gEU-nA z5{9qfSeH)#@>$`B`H+2mxdvR!ZF7c1hi3+gbPYdYKU%uwBgEHMh(n(hR*0kNI^)fe z7H@P`Z4tjz)R?L`m7!%Dr9fx^(@{<noF(Y$k~7LammTJa5@A}RP*({63?}xIB9THo z$JjUPO=zVzS55hruQ+|G`PD<YS7u8aL@cT!%fc;3UnwR$6l&Hj6BWrxSHM~92cVvP z#4>hQm_ni(*WFFxWFG@+?kZ{|Oq-${^$k<n)HJ_!++&M5Jl?>5O9E6&<VJvs_18C) zt_yu)Vv$R2pH*aL>wJ`5tO|u>_9tx%0+9D+WIt=Ogd*7$JU`Hkr(^6<F0Cdt`YAq= zkl3Lux!eDIa2Dny`apY?wj2MsTak_6);}A9`M6Y6Qp`?7BR4JOYx+j!)#vr7!!$KC z9$jy4s9FMDMr8)O6R^2}KKdO!WGA<Yn46qDy_mn2q{N@|UWx(z&Xu`)ywnIto&sB7 zK_rWN@UHp!hdZ}v_pgkgS5>=F<AW>6ZpIL3)xuCj1^Jp#_)5!Kup6U}Ttt=ozQtj) z9ZT_jvfyvmT?69iUeNul2A~101VR>8R<8Y9o78_#J3wh@YBFA6)g?p}h^Q0ilQ0)~ z>U&2VmY!Xnmgi;)Ui#e&!pHY}1_sm>^v~H92P8y1aI!N!#Lq8W#azeC<TL><3I!UT zzm%34`2{qK^0G4E+k*q%q@?J&j*+Ik%Yc>LDL9uDX$LJs9Y65NV3j)k1ZqNeM`X@B zXgRV6fCo5|rIP1o7fKAACs(n<i~`%(xq+kbkuOY4ar+`X4j!5GZ_B?#j5e0iIHkv{ zln41~-Tru=eEB%MAzi75<*AST_BUtlPq_&OiA=wqJJjyRX7umf&|e<aMym{vCtkCe z@fNVTP4je7(f2Yj+<CToyivKYBIU99)Bo%ZFE~g6l+|$xw&K-vF$+#B{3XrA>GyVa z$fSF-rGfxYP+ap0M#{;*xY%|O%xFB2FK(LeLNdk5sNsi-DNFeJuLkog)mg$B9F6%Z z7sAfuhC)ht)1lrTV-P(LFE6KAL^W8H=ZzLoJpBCVX}j{{3#>KIH1zz~R=umTX?wJi zTf%a6JC#yog6V2lFV}tm@CZO=7F41zg)E|7Wqwl+#YUW5rp-3}1EVUh7ep#8RjzvC z8u)kCMD9Z4f+A#`9laYm2^p>q^dztPnuICwMc(QdLEU=X)xI1avCkLpRI^t)HC+Do zKqj{RnUNeyS`FqksjAs9yFRYx3EE2)xqTaM+0^9My-ZNFBn)t32K?$M^E`jc7XUCg z{8$-v7QbAfb5NQ;B`R<9@&4+5qLZ_6<b7k8u0$cbR)b8HMp$d!_v_VAP~CZ1zNL(d z@*DS~Ppe=eK-YI2$c21<@km2U>#r?8JUon7d}VST00)M<>*h(C;h?ML;6cD;kKZRz z?w5Hqn;%Rr*bhZNij;lg7x}G*EAk-&b3%E2aS<&U*gk(bk-AiII?#CBCv%)}y$x05 zwXbt2U=1d2VI_Ia#q9x;P*otLXJhB7QQ5*~sU9wCKePk~9_Y0JAysWpv97~xV+Goc z%YMOJEd6mdeWuS=>VzyxR2q`(Z{e_>c-Lg`APY|omqZ0py11BflfcW^zz6jwVX-a3 zU2WcwjDq5?jb32eBgS8+gZlET2BSbD$BpniNsTG83;G(}$x5h1#iWisOjRza(bW-k zO%Pg3Dhl?U>fmbJ6W7wLTNnvC<1y>&;ppXHNBFNqI{0N4X4`V~K96Fze~ZUB*%fzs zs=**Nss&pwwoI|rI{#4nE0rRrz}A)ioo}D`H?-KKe}RByopw))%qz?oLFYd&W$xX& zy~g6P9^)sLj$6#y1~Y{3^%1f*oen4TzF({@G*FP9(?+s<>2m4Zpx?vHwm#_J`RJe9 zI17H>yB;<-H`BPg!7v--@JoS7mbky@&r(4tb{n&p>dAe&Zx*m~5;x;yGy~`AgbU8P zoeAo3G!82SPEc>f^?v!I(YNy4Tt`Dmn*QJq&E|~dgs;D3v&b1vhz^4PM%-h6FP2h` z&K14URVOjgT5B^qR*o+5x%g=M2UTl{L*`Htcda&tYx=zCgk5a-+klVPn0#bvUsoLS z&QRZ)HeTLFQSaVFWiT|H$X)p@?ft>9#*4n4{ItGB@!jbpjoe%9@#fH`Yuz_BhYJ%| zYe5t|W+Zfx_nTLYnI=4zD%yHbP8XdFm+tBVJ7#Blmnoh^c&?1N>J@*qpgChZ^VJhe zV`q15%lOqgy@FJ#w(iSl2cA#hu_T8~V;DU0G}$SbNm<lK$(_8oYlRy}wf3%LBx16z zFC#>}xHxDcjo9<nM1-h`2b~-)?|9JqVO9zFpSFuIMzVkJhXzWXnl+_YEcXXpU0k1I zoOK;JNvRsRvuN!p>0%!yB?at+UrTI6@?f{rpO*V@b@?Z;Nq^5R@b_NpAUHY|Fn;e< zmd*P{^hsSK%hgVCq<;|Vib<S2KhpQDA*TD)1^HSq9%J~#37z<i&kt<2<TIcRvYtPz zd>FPI>ct0cEg&4LglbNzw=*F-yfGMpjq7u4rqHI-<(AXc=}DaUXO;9=hip$1(E?W8 z9(US<h3ueJ{_FGB!sjMuS=m+!q|_s`BHG&pAC2z%`ax7XgJ15)YEj0pWTg)eCYm+D zV87?9e)UtW=fT#}qvG?E+P;$?+wvJ^p6-5$P7&mQkip05{LJ(MF7%`%F=molG^)Z$ zkFplC2yOa3;u_6I;0e(w!QK5G9?e0QFD*}wnocLK&t6&{k9KJ+ZwuKZJ(F(Re{IoW ziN4wi3ff-9PD%OKxbMZjP%Wi<t$^8`+&ZAdwejxcH_VBzHPI&ZJ>SyfN>3kwVQlL2 zLtRsgBgK(CKgQ$xZ5UbeK_y>Zh4qP<2Yj5rj0(LzT8LI`0WP59jXimmoMO8m-y_V( zeYibp(a#E<d-wX>Y}b4L2FlX`DcW>9tH{_|O{iYE+$85ziQx)@r%GUbS_;o8K0~H_ zVfa!(>+E7j#}-9l;p5a)&zayV<X{&|gzqPj{s*m95S_&KNw{26=CR&wjW5NxNLu0P zLD=4UTkh{`?Cc7|FHdP^$DCsPwY^ex9TMs9#m~hjua5^LY&xflt>!N)cmki*{A8t% z7}nOM6Cb!;f3x`ovf^B!5i`$qVb;%<aZEIS9cs1SvSQ<e<D+*+!R|iVZ`4|-I&j5W zj7W&!j$0*P6#D4(=kJ?}LrbTyeDhVPhWrX^Onlm4glv6bd1aBzN<WL^_p8FYc4)qs z#V@7o!ikF}_iXxo9#PKJT8;5sZJF&}j#890pk>OI3=4dq>e3?E=Oz>T-nb;{QisUY zt9^9S*?63tRiElpQv4eP%O<|0<P?vYzIq%L23DR=^61f(I>p&YItlZPq*9GHm=@dW zya~<}&@fa}WCTAWv~p!7-Jpp+BJ_ReI@>ZlFfX|hIenS5qyJo?{87E%4KA_s#~*K6 z@fm0tBnvlE4x$)pIv>gjMURJ_YgnZWFr5BYdmJ1!nKTYr#T56=Mpz5M>rcV&-C7$y zJ~Lu1?p%Wq^etfuP(w*tC|I9&58Pf1Dj=W*p{#%Fxww;>YW9pjj+9z;8sCz@8*|f; z+e<p_ZCcTR@rVL0W616SBDSwid2pV9qKM7Grq}K}8?w|c#=d-O-ekUMZ*t*<fFNbH zF}KAFH??3%!R-+w-p$IVmIEdIS%S~_rAC$z;wi459^n&M*RtLSND03cr>vAWb|Y0< zg<nZRlwY8I<*{vDO6#w?3EUK&EEf^c@1Z1vkkE7dG0(cce_(ql(ArLD^PcD*ZkC&* zk1v|4m$Y$ig9D>fw@xy?zKyOUDO&zVscr8(ah7lXtkpsccietuu=~YQg7rxf>Fs8G zT$}e%7dFmSpBEb{$nXBISJD3G)u+FA)Bfu!+JEn|)c+A9{@$4Td!_EbKac;|i2vp0 z-~an6+P{tJKQ`j;1;zimkNCf>?!S%dKQ`ju-mCnt)%~|o{l`Z9KMUr6Tit&f)qjns zb!I2LfkPpUD-CWW;!1zNyuaW;DocBvKq}3a|L_KZ^VLxAZS&C*4n#4rl7*U^<ay6O z-gvBx!F1{t@<qr{TQ{WVy(ioCZqzpj7)Co{9wjAwRaZ9Hy(-8tQMkKh7=FQ&k~?_P zD9g9PD^D`KpRzQy@|dSJkz_RV(G!uzjbtjfr<Td9=XCwr1xQM{7dJC23Ub(@wazbB z#}!N+C;fkVJxXwONF|nL&5zD)xv}JuPSR4RVqdPu(Q|Aj)wG@{q*ly^*O_o~mT3vD zAcigBGE}*bL!QLDUY!KhNWtM#6?EkaV*#e^YlZ0@?pdt&V@acx#nLlUoay3~rX#+k zDdyXoep$MnR(QvN2z(2U?x?wJPJct5>x4d0U3)M;ebiDg?)*Z#5|)%H-p=r-Scxhz zKn!O|T9+?mt2iZ}fav`E;to@U)OE8iay7fo(v|Z~cEk7wasmIJwZ;~=j+)L6PWGe% zA91wGpbw9OA1kF1XX3uR1*4jafD3@TpdH@qmem4jt*yZ@>&Cz_vg)&n<te_u>-oc- z@Vu(}7s3%cZJ2eBtNb@B7eyKWusQBN;e4Z}+#=kZu7rj@+Eh33q9w?<6k5$g{Q$D? zQSQx=SNZdTgp^J6#_iBxF(v}q_g;;3T*j#z>4q8)_rHt99hIX{OPFGA3S65P=upb^ z;qi>gpXHr-97?)`V*)LjBk#S$^2VI?3GO(I1lk&PPOX(a`uf4&`HmAMHELd9bSQgJ z0zpcM*FWSL7B#5#`aYiJcXpKS1cmBkPnz8zuFWZq2}OF3p&w~cNWPDR&dAUcT#7AY z3(4$a_M0S?Uc&iB+bY(N|Dl$&Nez3H$sZRE{Bi0oxguBGmx8L8^#Gaf-496xyn$ib zB!3g@jk-S3J?>4aE=uKewHbFx83JmYg#_gdH%^Yfpz%omC&Pd5&hv}@HO3t0irCAG z!-b`s3LGb|sVDM9#KCwi_i{GYLLv`>PB`g~w^O~|UhK6iz_g@K5AvF08L}~b%`acv ztS^24llG0MvF0ZQ%lr9ojz5IfA>JMx>%vk$+ZP|NMB5ML4OdF_?_%dI3Yb@LQ6$CE z1j+14`enRy&8!FSmV)+4266WC-xG(lahawRm1k0?LpHf^Z6&h^p3Imx6zLHv)CfG~ zRPYuM<$l)8`fBp6S`o%gZyAwEtkj5kr*5LxGq`@&S<_DG-ddY`TbuFHbWyXd+}!2Y z;*uXcRyBl^<+QPm4v~f1E@G#kIb%#kQDvvS!!rYBY1#=z*_V4c119m9LTu~2cMe)V zdxb9U%h#l7Zl1o;y)RjeP3U!aGnVcZk&jV~%~@3RMZAx~{3oqH&be$y4CUR|>n%TK z7AA==ddWn}C)%%$)#>hvX-j5htt=p2;{hVp59pVjc5umM8>BFCKw(GS?TR<jHC&Y) zyp=wzeJ~RcJW50OYKf(4`Gl*jJTSc_g3U9r@bGi581oE8hWb;4<N5Y*T^qpJ=5<!% zi9<9W<1W7aW)nCa@VN<T08a}{p{HO%d5zFKl%<{Lc!|3fqA5L~;rY4~W8642#Wc3k zRx-RdtL=;G-M2N%)9~#}dae3$r7#Eu%YO##U)RQ@AbXAv%IEuI10MZji2L$@SiQE2 zEm~IVviY_Fh<VBNCEJSerAz0aoyX9Z4f3$+IIjLOt`ozuFG<$^=-5AgL36BaiVw6_ zrF%%=Vux*p@)0?Fs#G+@FhrJXEpae0JI8bqX{aW<JfG!Jl!=<wb1xARX<jA4WM3Uo zQ7u)YTIsG!J{@ZQx&jTEWI4A*&7$JW(}(eTZ+gh#9LpnLDDw~?VG1thYahMJKu-7x zSc$bPwv_XSC)Tz%P-|1U+<x`NSns<+UICMe!l}n|gdi73`zxbK?$p$#nG$};XSOFP zT#Z$H*YLDA;dseIiapp?cynKj3z7sPa^8??smgIUS;pEo+7zJIoh9W!`AIBYnl8}a z>Gpw5?_!H<h`M!jLK2rSg=AJlB2f`Bvn^idiZQNIQO~C}6CMXM!yBdS#Y>`HHnmA5 z*(oyjr8nnGds8QhknLttLnmFUH+&#s#^Oz0rz{NIMw$-<=mO8$ejlbUp#8!>-pLEm zFLO5LW1IhCy54=S7|t<$XIsJ{V)y&f$ke)5L`J=UvYF^Jjf5hir<qw?5!DKBt*7&A z+dtA<23r2)GeX<^;91??Q>5E?E*NTae<ip!)8GHq$*43D<FbbJre4N5NMRRchgw#1 zi>0PHzCj8%{N$eT{GI!$iLZP*jvlM4X)p!56B_xUv{kVMIef|SNnFLQ$Lc(NWWlWW z&zd{}US$OBM$Sx=n$5Ti3AP2*6-ikk(xs)~tQW<buQl~|Vnhb^r~-X4yyi^V+<dfT z^46)oCFq#X3RG$bOtVD+JFlV=wK=+?6TY=uC!b3;2!y*ev+l%*W}gKhk$0Ky=O+;> zeCqVX$F4&YlC@>v90laQk`>Hr^LienO6;(haB^!7aA7yFqN1E<H}LQ<6WJ3$o!57B z9Pc8`Op<aa=>dkLfD88tzjD3cZTZPOS(U&l)XYc<ugF1TRQ`@K$Je}Wn=mOR%R<U_ z9EV4#%RdRyt7bD;!g?y*r-Co~3a-o?HwTW`LNpk`#dWXIGYrH;Pwy^4GKq9qHo33k z0CApxC3^e)dCkP~EFV9U(AR>yR<t|M7)<9esM4G4c}Lz0bI-(<%pBP{`>2Z?6;v@G zbfKd(b9p0vCG(VDxlfP0IMCL~zQ;=>BQ$Q%DT$-fv00f{dV1fP+DfabQq_+hNRN-p zeWX7bqq#pqQ|I|^J)JE_{Sr~f@pg;7(jH2t(e$tMr7{S7f`#?Jxu`L^8@O-Cv(~bh z%lkvBirMIDq=Ftj=aV)PRevazI&sT7#arquW7TO^)BpPN#}T<>CVd&(`q_E0T3iq7 zlUGJ6Z2On39%p(ggm<Fjl_jkXs}*vu&$K2MxzVGn?!t9}hFwm)sd%9Y*MZe*?b!It z_m6Rto2O|!8V~I|qu)Bc)PE2%!^?FPwB`4UNljB9J335T7hfQWMr<s$LjupTqgYO* z1ca8hN)UmkzHxfyA)mi-Jzb?XtIJu~+<YLG^7Hikd{Ri)gKk|B+E66{t+6w^I+QZK zpG*MJH1D3oUIzqOJwn6o@tYShn|Ikzsv8q$E6kcsT(@+P2kGkHvnDmLto^OVJ3^A( z@VF4(rf|<A^t97j6!92t|GlTUEN7_k3qP^fmS1mHX@o>+H`8oEtDNTx?1}=?si<#1 z?j0w;lH1MA>JjOX&mIcqh@L;>pw9NU;vg1hkkmLGHG<^QFQht@S($tBdL0aKA~>P` za~2_0qU%eh6|yNr3oB!rdq~fBGix`bKYwHc5B(>@*he8VIvJX2rFbvvMSs2Vo%C$i zXi4t#G$8((R3`awjB*HavUH)m2Tj}<Q%BqZHQXKYVz70bHunBYCB9=nZe&tcKEG1^ z1J~&05RRL%czkRF+R1h^ZUzM#pT0f8PevFMOH=5c%?ndIQS;V4(!MXzgq3Z-yx&x& zC9T-A$exE#Vp;PmD<dowquz=YO?S<u&>?Q2JR9!0OyJDYoR+i*I-Vj7$CGEHki~7e zeemvw+a&ahT`%|Xy_c|?JpkZA!QQKbidluTF{UUNQ1}#*``#ffBbL?vzH}dwlbU>C zRubhwh%)}%V~-`u{$Z@|<KJmt#;&8i{;#&1BNW>v$`o5xAG2$qbk8g6Di8@{sI`)| zeEGZT%$7mzyQwIVy1Q|q)c7@p)CFGoYQq7{?jo<XIM?((13gS2tOc(tdjESB?~m>R zN96li@z=IJuU3=|y0Hf|4csgtxR9K{thAKV3^E@)4lEy`=_G@X<A6qix{uAP{%_(R z@ebR`d{7w=N{Hm}ld-cs{w8$yV!2`ttUZa&JWdu`w#BThodf^mwYau@^T*QEkauU! z&O^_ew<Kms{9fi?^OX0a-);AFHxF<l&pM(^T#bLWd~cO|qwiPw?CKa|67X!Tr~5+? zqH)lgm%A%D@uo;%KF1&ND&~vnBF41J>zYQV*&+Qf^|M}BCY78icb5W%)wRpo0wT|) z?j_@=oZ<IsSBDkj4yqAykgK3y`K+&b^*;YvwW#+MKJOcwO<}sa?3oc;vzRO!eCRv2 z{F_E0*C6nung)*@=E1FK)_b;FGJ9843nU27k1h`6D2Llo`JDcKg+lrW0YrpRPR}Mx zJvsHyhgco6UdYs|Qu~)7#1?wWf0m*u?=iCH$uXLogtAAoNAt-a22Tgoj~-t_7eDKr zwT#tGs1u19-@=ExzkO}3+>$pG^sDYWd#AGqm0I1r=}1F4mjSf&dPneV#lY7k>?Fnr zPwL1y&s#57z9C61V3EJxbPQdW9k8qLM?q-d*VXKR4Wldq<-3ei1nyX5x}o4C>Xas( zB14e$9R?AuyARZ6mZP(*e(3&w-KowTU-g%?!KbK<i6J>W4AJ68TdN`MT&YeDk=F-_ zkhDOE<xwjhOm~N&jO+Po^2G{=kWd@={w3#O7ZHPMsl!q0;`=S>v;vO{Z2>45r{v?k zMC6@(Y<f36o3Kx{T{qj>%7$rj<RK595fnnN(OmeMgWKn!!;9Z8gw(6{-l^WgxAd|b zNRl1^`}IH?cKOcp#SSH$Ah}G8nkmWNA^IAP&I<V~+vBiX1H~FAOaBk{-ZH4_=v}}C zF}9$9fOK~^(jhI<Azji9n{GuyT42-N0!mAFcT0CSQk#am_@8^`-aB*V&fHJu%boF? z?E0;G*Sp^5Sp`{RNnXQ6L0L}gP2#jLp@z((Zo9M1%Rjm{z0YFr!ALfSiL2Z)47==G zDbR=A@1dkJ<UdCW6ovGnS<ofxe<H54gepQ-YgSPrtA(yNzYJ#!q~r6AS=}GU#GZ_s zd<u588V@$a6-8Ie-ANL&8>rGbRGHo`qdHkW>q<Ryg?_WVes-cyvcz^t!s2qniC=wb zFt4fcw&x$6-;Wc<1?Z(;NDG&Wm?*kv2M&qd-Fcu-y8Z{s1+mnEEn(r-qB4`1C#QXP z1d*Ljy4<k&oOI2?cq7*84ym-hx#&!hoYWIvIHLJR{2*BpIJ&-{F6~=vOjQNEYhUd? zA5BQs85|DIm;gTlO8QlGmzjRmw$gIx>S?bI9v7XwyREiErDRImQ0Gy1siIUT30dT3 zQ9)<VpGaO&VJLqcDY=n)Gt3Qt-H|$<LG3?19_M9!vy2nBRVzvh!w|)i!B+U!Kf*g{ zWqK8xY}pQrh7I0)wjEm~4v#f8$ApH%$wG;ntBd#Kxh}Nvgd~hO4aeJc>1xyU!gr9* z&G$!bkc5|}kL*|eYN!>zfwPKQyw~_cxH4YwtJ<CoinSgzl2&EhqUgmZH(QxG9Bns& z`DgCMfowXx|M%SaAwx506M0apz4}1WzXIgg4e0orsX<788FpCokYPQ0H>;|a_Ugg} zdOj=~B_*6<NJop*-`e&&U6`A59(^VErqipLM4<q53^;up1-9z7nk0nmn*+D$$)0K8 z#wB+5+XFGUzs@%dzWj-Lxbzv*{<J12(W3>WA28VZ#zroOR^x=cSGUWPRs@{eQ#9YS z9}n*FbE9P%0}h0d-A1^9dv$sx7ykuGnM+7?ZV6rR0u;QC*^-E4{rb642UL9N__<b~ z!a1Hb>mj>|HNCjpA(U(_3_}@x%veNR#dhxt)yH(0GFea5A?(#%hE(qv9iE=VJ7>8d z?lVo|a6aaISRwMvQj~1|D;#kZb9s?mSWOCJBD&i-N{l==dkD6_8n1w62xaZyv+Rzy z{*cv^vNv(19TVikf{q+p>X*<bmOVw6PSm0O%s9x|`97a&bs+C`-q)b-Agw^#A|unV z#qY;oY6_{{8-RIaJ-<lavn8|*U(iRNpIxGpip|kD(($&?2YRaMV*n9_-qK)XvuuvU znB|Bodl{owlIoz}T#}*tDavf<_id2VWTZKCvpc^_;}r=&f8_5}RK|mZ&N8E;qum6U zlfUiea)$-;Rjr|22WL>=2|irk_sp<+Oe{tAl?*F$$v2BM3Ekn#6qslNzRV50_7QNc zSw+?y&wv#cCfV{w`jk|wNbowp=$g=w#L1CtrrWw@6m}kp#@@P}xQJa6=)Y?%SQ{T! zO%m?ESRx^@hGIFYcf{4IBxS~$?Ff!uZnIZ5Tnd-b)^mQ0x0#cwdbLdvpt1^G{TD;; zS;Y_$S(=x`4oz84LFHahrt<%OhDJ>Cy6b13q$CR^qfm;|c(;apDY_r4q(4tVuWwv4 zQZ}c>@tm27*Mk_<Om<gdhiqE8?#uuoOL?peU6~FWYa#jjo*q*3*f(=;cPf;LA#-or zKS=oq{^^N%t9We`v7bqF#|?JZ{63WuTcyq?W_>fZUuelrSg5-3;pvq|{z|*h%%TaG z%bF#5jxJyWaZJ<+;dn`xU3~CdR7kWpSgSj6ZWN6A5c2+xkgOhkWr*QiRaiw#U?{+Q zBCNZe7o3ney09dIC9^>VNSw(|oo&))f^;sdk1uNeQX4`<Chmb|!XB|0af{L$4yx)b zl7N_CZ5vSk&V)gZhvyyv=y4{w<BEs1=%SxY$9RkO>au8|C_6;|JQ`23zmptUKT<u! zwQ>$nEAg-aMS~M{`5=C>4%Sy)8rKLB#o4{h5*}#d+CN-vj?NSEU>M|+B;mp}q;qdY z)wY8+O>KWgUO5*kk_XMardgQ9SaLn2kMa%4cX@qx8NLXjt~qnWZzk7R%ulmn=&iI& z5G&}~hh#LG1@pex-qlf!_tJ9<Ns6!3Hk~D^grKT)CNK@u$V8nXUrle;lUOtUCxNTT z?_X|+QvQl^;<h;)Ph=P}L;llq!telfG;|ShuH_j?yk0C4Bx;8%wlNKl`Cg4e(}iry zu&Qgq8m`kOXnYn@(s1b@A2f7^;wlMOM&&2m@u(bv>}+Kj3z2JdV5Ym=Ly(8z*+s%; za++pZn53LuVz$086Q%D(9r3AwS)U@FaHQ7L+>W=ONe>~SxVeL3lY(g6eIziFB!_;v zqXbZ8>4x?PGk-tFqxYRE;oSKPZ}A^azl})om9RD@B2z*6w=^XveFoUj+GBaMl>jkX zfG9vF0u86Dn8dy+7h24=w1@z<kUVO{S&*B%8nC#M3IN_0C-+B}8<!p5KR9sK<wl2u z$-8tr02&2UNt2?}GBd|5)n;_Cy)trhtI5u$zz!`aOahp^sw$-sj4e)@5)>ig8UeKi zpaDUV5+I@g%LD2!3smW8Xu9{#0h~JJypWUxhAZe0c9_9WjRv+(*}9B}=tH2OM7yb} z32^&BX)xt%^3YzaTd!O&0SXxbqN6*dhDC)D3~B|flHP$D$9C4S{O{<Z<D8EiJExq= zIA{8>6r_wXl+6X8XqlOrpq?L;<&A1Cjf{+pkH;h?Y62LkT7)jVd+iZUSD=d}$vPR2 zYM|-feOb~qIn_P;{9si!9Ob0N@7Hg+<0U&HMci1&)H}W#5T}Mk!P=bzif2ib@C0X# zl2E6x^61WXla?8RvIAw5QPDhO8K|F`xNyT0zrC#X?s2Ix@K+W+tYth6xNDEXa@9%0 zR6R;bWxEy|T3I(RI|=DU6z%cX88&FM!7FX#lhY#KH{q5=+oN}`)o|r}m$G^$V2jGA z4l~{cn-p|$!?QW7I^PO+QktLe?v#0u5j*S9fmh$XSD&)!<6%a&LZ+&pjlt9Fbb6Y* zer-WE^SVBp%AvBGP%uL-b3OMi3IxKVZ|R?2fnO5Dr(zW;zJU&v`cBw<ZO4uC*32B* z(bNBeyirLCyMCC0B)D(8RbHiuPxvQ3y>|s$)Q$?HdJS`}g(NM1hO&%nWk;k_;x&J* za;$ZA0gjssbcUK}>+h#$nJIPif^w4Se~1QoxnCIpFyRqk0A<SYjG8BajW7HCI~*PK zBG4$dwHtAujRB0sdk3l_?dEIB01EZ|GY?@Jn^6}aYm-w`{{V&^AV<KAa(ea1R|EQH zIF<h*o5Wk>-A69Dy~9Hv0DuFUnR;#%P-+c;2L@7$VUBE*4p2384&DU(NtI19+vdeh zQBjdy!*SQZfUJZP=*m9Fq57bbOV4qT>rsT@?S1!}dmdESoOEC+aB^`ifEqGTUSl;? z%tT9j*@n~fBP!}mu=wMb0HuuPoQ1S9wzh{UypDMa>C6NRFVKj+?yt63>i5eP0P7mD z_Oozyaq<4Kyg5pG9=uoeJoF<cKET?*U*4XV_zD`f`Gd0kQO_a^Ed_<)u5bcS4Y;wT z>EHlrZ9)NO4O|*tm;VaYim2sNE^CLqhge??@fr<O9e~PiIADPuOYfbXxwaZADjWe0 zOGHEzv1V*yq6>acUGby40nnUI<8q*0Y$tN~LKaU8T{jm@RjztF_lFBqIuPAV;hKD7 zuu=NkKC02jG%zA0AZ)eM@#O$HvagD>3#4Ou;YIaYm|zR`k@~3)GqG0m!o1yYA)fv5 zKh0Wc+}YC<TMYu$u3%@JS*)rX&-<rm4eHRnA0}ORR-h}U7w!$U7z+D*wEbNb*W1u{ zeVBPz2{%<~|LQ_JwCPVBzwI#yZ*ya>&=`Bj{VUOC7@AyFBknNGwnYf;yyH<GH5gRJ zI~^_8*=(XcDPtqP^IAFVmi2z&$ovk0hc)9(O4pq_=(?cV$w&_AlSEwFipu>Oe3eD` z@1l@(P~%zqX~n}%pqJ)O(@M}eGtSwi3^m9*47pTN`jizsoT{(S7Slp3n(sBPN~&L3 z+lI|W{Op+&ZXmU?O;pG`jXIndeg`MOuOM=OHxgYf1pM2v9xu~SX;zE+ed7cl<PUkc z4z7Z~=ikmGNlLy7*G9(6_WzOmu$3^VLfkj+%9#09!a-NPF+==fSFfZv<k-jUE4qK7 zzoU@p6SCY62OZxQDah4)dphR2uWh1ld%?MRA}Z)_%@21+MBSR@#vd550d|qFzjRX} zd{bf1Gk~kz>~mK!EM$e-1?tI8Pfu@dZuWL}f%AjKzvkio29)L-8X8h!0OAVNtLl|- z6QcHi8^-03J1y%b{+O!_3L=q^kN}463Ey8y5e8Ji7DuHRBy;Z?xU@)oZylzb0idj^ zrG+0Xj!Gib;C<uLUry|{j0iX-eL&ImvosIzrgK@v?GJCH05TtxCreW*tEj{zCo|YR z^Epjk0<$thNOWSN#heQOE&#z)Qny<O;MfR9Jzd>KKrsNU5#U`Sq#3j_Dk_*;^INA} z+}!<vrRZ7N*<wnt-CaxYS=y`Ysr>x>B<|}`0A~Sk%dcO*04D<|4>0ZkP~{6G4dAzc zTI{`}BT(l2ST9K(6KGfoaC10(b8~Yjg%_~604Kk_zi0+kh$dmrzO^169_HocNrYne zqSXSi%%-5$p*`>M-oC3H>IAmuhJm)OVY)`jU2x|NyV<y)8xzuGe44d_)_hS#&5n<w z^YD@I$|(Wky3+m4Vf5rzfs&yUKYAQ-6Q}XA%WUlzNW||_oO~;*wrDQmdky<Zv|-*4 z4UC$&3p3FPpVnjlYBPUV$k$F@6`mWpm|=jvBqPyJ@m6y#rLn{@+wR1pFo}8as4a4w zhMRNV4MeG+ly^_Lk_XB}IwjxmM?3a;RWX3kSK;)T)Z%nULN7ivp;wUJ`6`&e!J{q& zp18Q(aZTp8jSRNA&5d<8QWtR;qQwbVZg5A;r0YS(W<Ij1A1pUZ&feO|n2Rx6`!C;f zN;cQ$nJE{SK`o^tP;c8#8d%Vw4VIkHfAtjb__SSfl5)Sm&wRHzM5OskY%;-xBlk6@ z;cBVEo~0@1<v;sC!7?@B9!G`OZikN8eR=cjeDjWm?2xI~7QIEBN#nmZl-;ZR3Lpk0 zaJ4I#`~34c$=2}eOjfG6kj`kf&VEUp&$ML4Yu89ZGLn`=`Ge+i<AC3xQAqOw;Cx?Q z2Uzjbe6Dvu^8@5)2_WfF(#BK8x?yF2hdcr0pRqv(0RI8(kPxr}czSLDoF-o`8D5co z_Y06gpx%^0y%<z@N3@&J7y^I_gbqRg-+A!_ajr@q&=Y{3ArkbcEGu*9gV7bJ?xwIE z)E$B~gt1=>&?Gk13wahvS+vRAc0QYlW&m;riv^hEskLW-cmQw+u1nsopcwkxT=O$v zMt}ul7+A-QpREPcr15y1nZJME3V0cPC8ZUfA%JTD3(!CCmEU4v0fHbSBZHKI!OFlO zqojm|f@0hurK?L)Ldmbyz|3q5L}GxvC66+<vr||5)6n2Ga8+i~kB!#^*dHl*d0++u zyP{h_q8zV=vVi*TSU{t|VEaqW%}q^u?;7cH0S*`{P7an_piGG9{LIpLrVPf1p5Efg zMn4G8t>=8!!nr|3G>z}Yg%g|BkjLds{+#ynU&DG)$*x|VA7fKB23BI*M}6;9@>8() zp)2Dvf!U+O_e~pn)!1MU6c&AAEqJ#Yk0yD)vJ)ZQ$ECVEHG|0?1QPqrwbTl>ig~9; zRj5r4l-Is!u-xQf_TTrX8@7@=-SNhI$iI6g86xbexOcrC{-lAh>J{z)G@w18{TW#Y zZ!P`-@~Zv&r)7k#w87f9R>Q9M>rKkM{SA37Vi1dM4luGV9u__^T0IMtF=-!<8nkg4 zGvH81k4NEcw?8A8DgF^)8iWGIm{H^b?%Ce{$Ei)To4*YiNkU;Ck{^8bT6~)(a?8gn zUDN`^<t|j3ZSKbYT#=-u<H6~7h#St1=M_mFwzl|Ps;KX-rO!1XpX;G31!ZDugcluA zD>|32H+B}<-z&_i7qj%d{CVQL&cGyfYk0Ffm3E~179KIwHNt5FC^;ayQ5~-TyL>Hh zeL9!+;Ol$s`%LpHVlV6lfm+6#2c4aBX<Ft=ntzsM3{UVV@T-QnVc+&8%JXlJ9y-vW z23r6N2s)+{@CLnp{W@4&RPArFZC$Xk)~8Q-dv!K*dL?YYZ~@l+_VQnD0$m#S+i!@n zF~zI+?CN&%01{-(4uF(+CT*AHmahP(0#hDfy3#nTXn}6-u~r=*8ccL_FQ0$QvnVVC z82$v{LY(dGSuuhY`NnpnAevRyntFPA0>lba^K#=U!oK%_xB~3DAujNZ0G{*Rt2H3s z(X2E#6i8FV+L+X~1Aa0<Cv}591vVEP?Ci#Ob-#bxfKdfjGJv51iU`mlMW22H?3;y| zc^`oOJ39bjp=Dws(*5O12<WCC%1P<z!WPOV0=Cy)O@Oljs+#oSc$r)f>;qH<kYD!u z(`@c;Dg~<E-h#Q6fd9ii17K!;Zf+-Q7?7p0Xjd^l`sF+>7F?yWN5Qn;GxzL-n8Z%% z>D{80pzkcV*WKB_6lFVG#q(XpXeWZ3UtB@tdl6mHRniLO%YJT7@Y|*p!Gm6cydZE| zb;suzfGbl2f{GHNh&)2J@=tHbl0=(p>#WAhrbFm5=QHr-YU{OQB9Cx?4U9hAbuuTi zgTuBwMVW$)@4g<zYYI1kC5adVC>F%AS`p@WmEeeoQJC2H{T1ldURL3vkl?(UTf!*A zO3S5x#gqQ%{wSjY1_1(nn}L_$yt2mI#Z;o|5IV|dE?DKwYIr;*tE*0H<fLvzzORPr zob$=2S<gr3&nqpxRNmr$1brk`ubcF60Hcr+#h{7$_wwvWYaN3S$wA%4)G`dDGVP4S zZUZecL#!8yIO1cP5>8jY_5@!4EM^Tz%j;pt|3^u5|96XzcuvUvu5x68+|E|yui7k$ z<809W-ym{=-L;qf=On_HfqkehdBqQ-Z0?y=ueFH7Yjt{jMw{J!$;n%i$kf#J@!$~0 z-a{Q9lEaU|Q)F;-N+05(xpUacMT+_(m0j1S8qgs2=QWvsR_WKTkLn@$Ff$&7x-1-E z&B4K*i@1|dIWM+Xs9&eg?QlsEX_0z%bs8i*ysc22+Q=Rk5*g79aJ%_=opH_$+9zb< zAXf%Z)S#dsu&0%jlms{!m@}=d32|}1cdu31xH>!cp7d;I+U29>JL+;{A)6Q*_h<p{ zlTbPfAu9OaTxB|kMc<z<F{w4;{?5-g0Cdnz0Hij+{L7vwd-R1+V(at@L{oLPX^Y{2 zh5?&UhWbB$xUfUtVq*iwpNd$)eu$_WFwP(h0m0PH&JG?fE-eGYZ_o>YSq`YC-Uhfh zI|GFpi&mxi?nFU(LX+EZ1Mm=lfC)%!09MGH*Y785Yg>%I3L<$xm*mr_<bllyaIXQG z(M7IuoQY<Y4InLnf4~KZ%v@XmOjeMY33g9R6cmq+C(-X<g#X8QrU61Q;Lb3>i0tM7 zhCUD^U9`IKlR+ptN-Da1_B>1A=E&zevL+o)l7R}BPVY>AlaPJaH%k?RKm0m~(G@wV zRKY#Bl+APW5J;3V+5;VbQi2YYO37HX7!2M``Zi5d#WSB1$g0!gh#HC;I<1vW&r&Ff zj>XXUXR<#W7udpn1PXmzjAjVy<BDBZ?zwZwXJCi&63}PE+_+|^?e4lmb$60}s~d%g zHp6v-c<$4EzDdY6)pM~$zoL%`mEn-7%XXRjL50)sZsP27-@1J~9RVqQ_VsbDoHrl; zeB$hQ9A$Sm`%5y;fW8ia@jp~gmGG4C7M7xB|0Z#&?*7F!qBIGG4Q>#7biaBiy-Zv4 zETUsvc!KRW;ha8Qb~Z+Wm<mqRFPxns7unP@n<@^cdDPN(fI_aN<xBD2Za`lB8efF> zSkG@)v*@@1bKf2X$klqJ@YSt)TDsml!6=y=SJ?<dT%vg5NGT;O5O&T@a@v4s1ng^} zW@h;|b9Ke(eCt0_oWHMbmo-9-=K>ZhfHBATZ=o7sB7vgju*Cv}!f26!XyoLkT!JKA zl6NapQF_YRy?~>OXKTe?W9r<PolcmyufHGZtB9wkC%Xm6$U}$v`};xS#t{kyA&4@a zy33N<r%!$LA)`#&z*hqz1wcGr0_qyDcT?pR6+p-VNLgUOp}s)^n**@kgKz4xKV4=q zUPyqC53F6lcaxl+e#A4+DL3T|{9c53(f8xVU~q)IcGn-!e&gr%_%v}qJ%-E6Z1Ew9 zxENA-n>!17E>4%eWe4bq9|lMfPt9zPw`_>2nQtD`;oiEXvZXrZM+lNM%83zamirFW z-LS`w)pL&p=PM8YOkEd+yl3~?-F`5J<wz}r`$!k%Dc-HWCRVtL+CAGQ0+TN%pQ&2j zsV2U@ZEKNI`cMse6+?$6+I=G2W!`oFpgIGOqFfFW@^k`)Nf)Fd102{6sc`8fZI3%O zyQEN<uWzpHk{lg1<qI}6b~y84z$?m@on|8WvvBv=ZFX)h-EB1(Y&ZZ{Je150bh%)K z0i&iHY<5ynQ8d|!iHUtqdTGFT1*riX7CpjO&l~mZ$fMl$%en!P#r%_$;Q=|@EHx)m z+k=)9Y`s&#JOr3Vu&{!+0V~lAGTfsPID;O!Vz9RD?{mJ&E-zOe`XL+H6E|}m73sAO zhBwH7fz3H^cmP8d=sw!z#=RiMq$W5~$(LUM<StM{a3&R&l+gJ9mw||^=9VW)?mlM7 zZfMCY(qy@t#mc3@-2rZ;0fDCJKHS2j5>htIYI&sU4`tEngbs#N;o<TJnEVHJ9(mk+ z<A%IjY3Wm~`4pg}2=#u(#h?K^Nz^3i>KT@88m8`$PNOJ|eIi;1h|JGSg2KYI`=gJ+ zeG_?so7$FkS1UBW(vUJD&m0L-z*YjIP-9~w$QSk+D_4mCJ&p+n2e|M+zzrb(rC_@? z#D4_Bj!MS<ql>=ag`~XHq%UR<KiyEM9>81&o)Xx(&Dqxf29IR29N3GN+ITo*EO-b% zVVRhl(<aJ3vV&t_-*^9bv<$>=UP9@N9;&LUAp1hZW1o?oon2X}>LLIPiWWfj0{#IL zMSpKE9WCvT^Ve!>COLhdLk)3(hUL*RN*;v^B6Yxv|DW9+FydKR<a1R(AeE4uJU27r zzCF?khr<Do3aIwJ_dY(4+8w~A0yPX!)BYlnPy+6g@wL3(8(VUo<>h8@Of8C@KAgW- zXQH`#^^mZ45^@{zVWk(3v0ZK9nAut}h~K8s=H81$1((;vr?Cx|XCzlW&~Olxel4^$ zzk-@ggNz?m1_YIse+zF8>lGqar-9M%E7A*GBY-^ryHR*G5#IS3tObRIF3#t_^crWK zb#<qt6#l^E>>{NqY`kwb)4~UeU39sD@q-mms*mwJ05~gNuq>}+R_OvKDe@yY=yEvk z4m?Y_%6VC|!Q!96%#?BpemU<y`SD6{U>i=reF$PSb8~YbhfB(vsRHUV;#bds!1Wy~ zE2~l0s~KRC1W7U=%>WA|apYs>C`x)ggrPWr*O7Y5Yqdj0?h*Ajnu7zZ*utW~A_-94 zAlEhzeht`+knIu7%*>p0<^K95d$^Kp*W?Z?ahF~~5=vkt0&Nk<m5(sg<{&OFFArkN zj~_!l7KaU0vU(?i;=Hyeud0#Bw`(H&u|>@bCvgtyFZeI=QgWou?OUaSsvjTeAb6zb z|9PaMd8gY<J(D`Ft``?g7mXlyros40Umwh;K-h}Sqy>|m1@Y#JeNA=s1sd?KflZmt z)T8^mu&_LrE)<D4k_Pt`hA6Nf)Oa}m1STb5ph>aq3`5b15R<e7sT1(^fD=YVK@j-- z^7pPmOELB%2LZcL`_|I;IBfu{Cjsr}UP<$#leYis-#8PSneyDGrp3K;X3cW(z>K}R z|JaB!ii$oeVQKc+6H2-K1m+5$UNdZaI^&{OZMy)HD1d<n{IKhdmk{0sSRKYIQ&Jw~ z2f!EGv33lG6HrObteS>_O{xvp(19hy|A)nRUa!9ReG{0+bb!?pO!BM8m+QSTn86(& zZ>UlL>t1tjewT%~DF0DDn&KIF7*2?YsZHVkb{AcZ=hF+_xsD2Wspf{lyOV5_o#)Vm zuD&_VT}`~V1}z5^>ZgyANRU|tcINg39*0$?>iK9u{LAD5uhb*14V>yA@c0d!D?pEC zdGH8%Zcpw3tr=(o(8!OeA4a_fx9c<fZU^f*p+73B%wlBUHd7AtyB$O`N5EtU->(=3 zD^{^)g{0&hz|rr3CnX~7%xiWm1f520%Y^1X{%&bX(3h{kpZ1x+t>=aS>RxfVE&!I? z|Dxl;=m)^K37r^Z<=g|z*dYI9@>={*1VHWj`ss$a!Q$iq{RP>AW4DIP%oQ5ptKi|S z3Py%R*}(P{&{Ns?`L$8m%WUewr~ngrem)I2@F*;ld0zeN&2Qk}#11_G-36plfw>o5 z6wJlvg+;|4*E{*6-=FhvQH}M#n5hCCU|)k#^2G}yJ4fC~2kZAsSA+a9iygt(lhO;d zJ8_BCcmHCRwsd%kIj(2pLSG2posEM$MbmzHKQU0>N>h$aPGW~kerq)VcF*p$4>;}{ z`}II6H|4y6YuH~7o+fQB&?P{d%JVEhst#-eN6kTE%Lz<uU?v7@2(U8b<QSj*L#m~f z0$NCU`JpS>`X8rqS)=AsQb9IzUqv!<a{ST9W@f-~9f0;(K~RhdRv745Ri4F8t1oz$ zJPY7w1<L3%?hW%cAS@yj^iY*QAL{J|-j-O3Bq?8y#5_86efC#IP8>RMT<g0Zq2!m3 zfrWeukJTjOlrxtcNHYLSi>-}~9Cb`m9@yjk1wRW1C$czMMFw=o6d7h5T^V1%i9?6b zfJhJQ;D+2m9s(#I0F4bFPrnB)JfB^abb5Mve2%1lM0z$l>;B>C0<P<hOFHTNWvUEC z7!h)%Zj3r%ljWtqC!#>Y{dm<^*YWSK+m)Jy$ys2YJ~=%dN0FxO3n;0$Mb(vujj@@; ztT}IOYMVt^@~0PXP$gSKQ%Osv_)Yp?PSg<*82#n!?CfBf8SC$%3sDBtws5`iaDvSo z)SH}lvE@G&Y_Pbi;CL1Rk!U{}Z^Zb>2x$;U`UVaoFl&fO0dX`rK?1a~`cWuN?m`Hb z4PY-Azlpg&00U*+GnWDBB=4&-ALt@LY1vb<5#nG(t^hH_4U}Cui|qIL$crHF^SQoQ zTUi<UaCgzaq(vMeLTV2f=Un|5y(ZfM_y)53&Otv~BsjMMah*J*3@l<mm@C)hNN;ik zd@n=v(cZ~5s)#@YL)}X&&BAxY6XDSd@1d8qur#l8p0p9ZT)$Azp21bI`H{|ByqCvv z!}iDMsy}}UC-#9-1?uEEQgz_emFv4c!CpCFg(s^Zc&-YZ#oM{d^19SJpk2<utOCyc zA~^^ukf78n33nfS$5O6$Xq)9rf<5BYN;j^FjeKq=?DBk%&yJW;CU<aBEN-&VczA^t zx{fYfU0si+%hvv_w1Y(%gs&AgH$71lKogh?1Nu}NEab$z;CvE<A8YM?-8!Ff8j=?3 ztH!>{{LM3BPxWo-oEg)Eyn#Fg4cor*kC)&wKNSHApGwIMV!gWqQw^9WD_(W|K$*&o zyf5JOgcHCjZk5euCIW2Xl`pous(fc7pXyFM8ioy6Yk(ICoRfU=iDv5pnS^*2{U+dz zb*-pD{HM1=Ng03UG2(|Vqbgy;GwZhZYi@YPCC(%qgw@Pi;1U#LmOjJAgQ~eM+0T^u zMep^uS4WR_ROH~HkCt3uTmg|y97;}4pC?H5CA?%ru-A&8=Xm)x?;WufXoTO7jWE3E zLVPFwb|%-Qtk~V%4w{)BPU0Vy2Loxl-c_x-;*&IOr0X%Eq4nGNz#oy(S>5UR=h*K$ zY4J*Ghswt-&Wr_Xle)Kw49+?lI?ncjFA)Y`)>S^yQi5#;ZhCGmoi+;J9L~%Q8PW8l z3-sP7*KmJzin_}=H*)yZ<-CC3|3(KQX0mn4n2<vyfWPLi@h*OkJauBIlsA`VasxLt zXXpGx<y}0=Y~$bpwtqsEeSjkEs4BIiu;KA&|J#?MtJG6i^y%xLc}0tb^BJrMp5z}H z#gEvlswuso_*OmKcz5ILay>(PbU%%O8=qjBz0ATDv19GXMz*A_jgP*Xv*LFK^WPBl z7ua3xB`X;cB{sSD|Dp3Db_`RP=XZxN*%F6o>+AR5EgY{9teac0<zJaxs*(9y50|eA z%kKo24A;&<dmn<Y(mG?>R6_3Pv#TgL1DF%g=?C8tGOtVd6^}^7h?(%F`F948n#^=P zf(@NMy18)_LZta`>cxu<<LiamFH$3Yx0;3Tm$o!#5H7#aRIY_6FfugQ*vd0*Kz+zb zu73WR2l89={x{<?x9N4|(uPj={v-OujFX(yq0d0EI+EqXXOmvP!cv_o;X7++Ntckj znvzYTa1xaI?WK^nv(j{aQk8wJeSoyaJk;L{!KH0Af?+I@I*QD5mqK0Vy;tB#{8XIR zIXvV={JQVeW_fdS0V78S^85Rf+34i0bxNjUc2K-rlxOO5FbRzv&5~V9w`F+PJ$Or^ zsr9d#JI?#AxNlc9eIo>|%}lV~_|w$eu=2evosxp2HS$!%p}(lk5<NxOCfoe@**<77 zwRDo7%!oA^RnfEPCPor6%aLr3O9cN;kW|p%T+coqkZyC(A$!`3VgdW{DjokHtyCQb zEJANN9>)Z~Ki`B7woA`HnR+{m8P4Qg;3q3clX2y|QQl|Z9zkPx+>p^^|CyF0XRg=) zHeJkWlSw-P?cAPZ&hDtZa{i+kN)zDIkat(4@XqHUw~9Bm6^*HfM21JO-6c-{ubL^Z z0Ds0pBk4teAX2K>X7hq(6wajYC3LP?=<iwjFt;ZsyqX*KTp;9^8~Q}X5?7gV82bb* z;!yV0zz4&?&Cway=cQN`cBt5O(TnFK3-iC}&yH*v`KRCbI;m9Wl@2qrKzXlP`)$&7 zl_m(ve4BaI;%qq2C@EgLn$|w7^&>lqY29SZa9GpGE%I7hfD-keFlt6u3%Ra^Q%Bt) zyJp6G?$7#cRKJS$rHbZ+8wKn>r&VWiYpSfPzdgDBnpr5Ipjp-J(%CFLH!ox!XN-5j z*uyY1@nZF`g5MLZisoz$%_kQI+j0xU7%JYJwjbNU<@EgrC7=?AjN()vx7A4*MZp}W zZUxdaZ+%oQbWu*A->z|dwS99KR{m<L=%4uNAJq7m#wnONjH^MkMvgWYStVbN;VlbH z4nW;M#L=v)Wqr7)XZa&o`}?9v!d)fwF0juO_Wb#0RGf|?hKfGFZw}qr74B;9$2Sd2 zk_g6j`7p2WW|tOJ-~A|k*eJ-GLPKRLdU?^kzi2q;B+l5GO{b1NHWCw-H=p+XZUVko zv%#Ez8;ABfL1&qR6TV*6WOrXc)t)~{d;VZ9cXOd<%h3BSg#G-B)K%Z_jXFu++9rl1 z=>6{Om~8qkVTm-W3^xf8>dl1RlJE*<Kk}AZfZig1smDV`;mDyO14G6eQRKF3CP!%6 z%p^a|K29Fhju+cvTQ0CcrX^c-!(;CGV0zOeZ;HLD<kE$10R50N!U?g?LjneSZOhb1 z%ysh=zmB{|HarM>GuC(q6-VcLU>YSEC3ntqfxfR*8V-P^+c)scqU>i?b;)6<g-T*? zt%7#U{*eC%D9c=2ZZhb;Yp^lJfKgFdz~WpgcxbP*l&Vo-XYV3Gx~&AS?yPuX`Cj7& zd=6S==a%Zzr#K3>dp3t0{pEsj6kyyCn3-$^ou@a9EecxO2=O&QB|kYw+1;&>$>Htj z>Ug@*n%1dL80+y;tsOpdXE{1}I1el~kA{m|mkc?@E^_kEt=#SqdC&MT?W<^CD}xL3 zdb;D@$};~$A$z_Gcm4FIORjk2;_3(gQ_dF8<KXY0vMI;wsA&=xrz5}Oi`2R0FYeC@ z0~e??sb3Qg?3LpV-iUKv<ZgZnl$EMPOH`K|1nu}WK}C1DXiqlJ`ta}D^kRRn-O*xW z7ZJ~YCth=J5yh@H>Wblr6^#AUE{vbee+kTq(OK-uscm|^%zQ2QK`d9zT~GZ-72<gI zXz#N{jj^4`nemUe-`KYDczK1wJ7t?1+3>k_-R<^kK8vPJWmo9Rl?e_yq)T1>TWugP zH7OC~tSsW4#QDREQ^DXjB|Ch*Hko#xpqsQ&rYldk;rA2S^Ppv9xA7aAuI5j6{10{4 z$B6ELmag%q&gUtHxc^Q0F-b5k8<hO6+3|fE`l_PTXH7Xt{SI3q)>F~z@QU*Kpx<9> zILMa93ChS{=F?A&a~Z#;v56d_rN|qM@tbF5;NMo#dZFyCbi?3ly_~`-<6#7!AQv_| zvzHQuD95eg$?z<^+3Taj8-<MvTGNHe_gugwf4A0Tv+|KGP4OB_U=*vH1@U7px#jgL z&g_SXOy?6@D)h+r=X91NB{^)s!iMipdPL?A37sOGsO^#@=%~U*TWeA)uaG{Tcn1FF zx_RDC?96(|d6t7M_e!v_(UtYk=@sfQBMO!Yei8g^u9#I7#)Ghok&?a|GAmHBq*#tL z+dQw7smPblepxZa?@9h?s?-^Lj@`W42fWmTqXlJ>H+}>3C=<@qc)4J8nj^@HW11u) zzFt?8c<_=6un3)H_ibBUXpifcu<M9J+p4l&;ntYWU*r<zHm&0dXj=T9TJ9znRg$|D zma7vvM7{2j?4iOo{@OFP+}cRpal++l_L~?QGn3oDlPB+cbWfq`2Rr(n<~{iwWd6lv zubtb~75Z=Uwfn2NCEJD0cMB5tb_4M}lmWy?Ll`g`LU?DT;L@dRJ5rR8ceA~D=vz~J zyCkeyd!WJDo-faE9MmA=Xt#?rrk3k<)&KCFgIEYsLn;(m*I4`z5YBY}s}y61GW!Ku z^OQNg;B2gykCc8-eqD+{U9IO@lwq^f?<0A*q;+yk`~_-*J7Zl57cs{|&5o_zcS$+! zBq#8lV&2*9au9gNypQy#<S#Q_T3(!V`=}qHT*z9;3hto9C6eKb%CV|nHCHbewmq^8 zdEJ>BL1wjACOx)V*oN;B&7br+ul+4JU8i#4?xv&a_J|g9F#F_A%Kfvk!EU)W^=|ig zCb&@4lN=7lkzt@-+S;+X^+9H4_tJiuZYHZ`ZI<V>o<4WwZ?Zyq7z&tJta@h0@%vA# zFi!-N+S2A{$ETC|M&fYkk{ev@{A%{jF0|wBTDUOjQJ&-t&RD2(){i{9L0rsUR6v2N zh+3-yLO?C4vSxqsbXyjn93M1``-3x;m?7EX>Y8m(t^f;UxrE|kcDY>9AFx3pbygWH z$!BEc$nWKS8l3tzbs!}}vf8v^xcD(j<TS>~sOq?Xv3TDm7ljpuA&V+wt7Fke)~cHs z!RMW7&^tyFHtd5iOS-0yo0|MPUy?N`35(K|5gOLFWh-?Pxf^`XQ--Gzhk4dLyNMn5 zUd-q~6j=;KE1Og;ERsckbJAC&(KGW6nF=vd23#$mDEjP;=#MX%5nd~JSF3KQV`rFU z3iV#mON#4!#6I8pV#8kXK9fX;3XE@ry)Wq+`$%;4in^IqmCv-|B!;w+4vn{r5QB`; z{`Nr9S9+U1c8*OI>h+h2yi@}NL8lFgS2E6-0P~ZmP`vz)(Fa&W!{|)+GqNq@IwfJZ zRd1=I_FioYGxuYQ2ep)y1Nket@#fhVdnI9bfB!EX!~cyHCq3G0Me|o&;qj|~iZb`4 zRvJ@H$2Qr;WjZF_a5{o#ywvt7r`H!#X~*}XK5C<C+=-OMp+-+|a>GSlZWQF$%q1dH z(17;$$y1AaGxG22OLIxt{@-*cL85`Nvd6~JKK8^y$nhFRU%Rua+8I!gcn#YfcqM|7 zN_!eD>i<$@?!3h-fUTjz*H+L)n7bT5%)@phDMUv$9Fd*X-Vkz`i-=&Z){!r(*y*W) znqpK`o+xlLA7|FrhUD|t5)K}GgBs-A{jLWl0d)O_KocSYG2)DKI;<`KY^i3-XfbEQ zB#@X>=+ULwi?BAy%>>C+{rfA8S!g7^^zyEsArBT5ljj+iUrL^_^6js??OX%v+)e86 zz&WlZeNrj@-oaO&$BO{la5J&Q_zhBqc|l<&dLCr1YF2w5Ue)^ZkM*ZkVIMci)n7Yd z8<H#EdN#=Sr_!{hP7;rrc?sE&^wdxSG-wAJgbJ-xl}6(N9s12$1J<A%otSK{<~?CF zm~<B>iC4|{CmUCZX|Mx!u-NUeYb}+Q+$8(*l=|o^Fxu|Yt2nDEVVQ0h=Arv@{&3KE zJIThh!V_^YUA1Sgm9SRt>%M_=loX9Op|W*6fC$>ko`Y{$jVZagtoo+&H&HU`naep% zblw_|t$^v;Wed+lsv0&bK5Wchq=X)sIbF@Zy=`^2Z@_<NnprsA43!i-iBQK@+;dM= z(H?^V%bf^tN3L?7XO3V9A7{f|MgNgn(MM5ORBvZyN-53$lyX%vr>^9VJKPEMDV%6h z|DW{ZSb6j?<-)>kfuLgx@i|l+|7lcL!bAJ_bhQ~l&MU$6BCPNT^wqjH2O{1{REk4` z6qym2vS{Q3$wpf`H1x}J9wGb?#Q`RNhgAH4zxxOXrSr7^r5O1il@|Z6ijn`dSNxAk zi~qiZ`+xja|BJ5xCW!xUmxuq4Zj}F?RQ|{7#{bt|@&B7={vYk}-(BxZ_4`gT1UJv8 zD=Fxr+dU6@CpQcc+{4qJMnOPTU~ibo$n(aJHI`Klx2vc6s<$L7{>+AhD@MGg!}+C= zzp_8q6Z~cG5j~gS&yWQ%EYU$MIk<(?J9G)Ns87FFOtQ9Vl79L{T#b%<G0C5z8Z~3* zqui)elWy0(qk?2kR%-jdAq_EAXC_O___x=AJt2=VMJC%yav3cOQph~W2wMUC>`9sp z>NZO`P6s2i)uoxw@oi|t(cix`$rq;)6ibM>@=K#=QmChU4-vfYEWl$LLcd7CB>SFq zs`!Q_VHGw|$-v_JaSK`h2lbkN{dbGUZA8(+z{|`wOoL-v?+3du?`DH2?A4s_yA-k% zAr9nh3gb?>TQXY}l2;aUqxr#`qf43jGf#+8cVLkBgfTVm%H*=#7j7*bd-H!Mx*|uW zQ<MAmWxW7>p7}hmf`OAHcVhb3+i0oXdKq{0PMi&5C~hwbSy}ZXXg2d0oEttqy_F{Q zN0$Vbz`q#^PNj4S!TFmP=d-9|FD#b}sg|;ZfR?fEtx64``FTcs_WLet_5^?QiTF9j zVFW#=zVv-s_Sf6Ecg}E+GxvABFDYPeIAnCD(%d~)Cm&Xu7%iz34}pk5r!Drig!=Wx zGrdbzB3sHuown2{bK-b%c3v^TYh5d;$QdjXe|C%=Xi=QF@No^R--J9_HfZno&+!@m z0{=$*Zlx(9QzZ)tvfuhu#-rEjaXdSE!XG04+1qxeVOlKGQQ`Y6-2@-R6yu4GR_yD+ zqO-%(=3CNC*w5#0hNedcvpq+*=_oe0Et=8I=GzL^*0uwzchBsYhN_0mW*w)<@2zu9 zw3oLoN;^oEDlyLqAHVXGi#QniuKta>b<J1v#i*)NO$?4yr?V&DoX>Ea&Tw$jM)Q5G z9IBW`RNhfFx7%P0DB(|fs^5jO3Q%}wf=RQ6GK4^~rG9Nrru#ao?(~Xsv!*h8XU<k? z+`&?cANwWF?woJ_k(bt`9|eih<KOo<K2uAT;15F*rtnx^@9V0?Z?<bDl3R4)PYToL z*Rs!|O*<E+t_mm?1-*ufeRsx+@Rln49p)z9hdC5_@@C=LQ2@>azfsm&oVa-S;P%A7 zo`)ZJb#R;uxc~NN>2|g1qf<zKzxfo>W0y}Pw*=ldLWSRhGW(el=WyUdt_w!EIe6zz zlFMIJCAr5gZDBF^ZAbF_Neu@soOnwfl^;1v#@t0LmK0Qx8Ur3xTLdHG2aBTq9Obyr zyo<iEE$$s`pY>zK<^)buEr_bW0os)>p;LlAPDzBHJgYD_*2_%JY^t+&Jbx3V`tXx| zxBMBN{Ii|S=o#o?Z&)C)xz9CnzW(GRyVV&N8M50a!prAnJX=U=XLnKYqb(d$ks6?U z0yH!t%!`+=b#1%@@;rjGB8|s+^S-9&e{Ra(Duu+G>rHx!+srXL2^SJRe!80+t#}R1 zAC2x@qPxX36#4JV{ws*GkN*>hL8eiD)8SUG!f_3*-dvh<Y<)(SB3XYt{rGr0`^+SD z)UC865?ofVO5(Nnud@aWGhq-Z{xfpJr&Op<Ij=H?qDVD3_g7UaE8a#eLHVy6g>ZDj z_}E4MsUD%plK1B`amc6!K;B!Y=?QvUe+*Tg|J=mz?Lg8j2KQ9qj59sUX(C+~BD&qX z#Cx#U`N4NtMc)@Lms&Z)(Xh{$%y-w{(Q`d&<|S20f<8jxFOKb}EJLUCwvfSJsgL#p z?`P7L!m!QD*t0dhfLH!&*-9~}t~#Q$hSIyPO@!V_3H--2cz3C%sFP(SI24YC9RbE? z2~+tOySE(I)<<reVR=ut2%lVge-!$ps{S(%UCyxTqc!vMRok1=g%LB7{VM#M-&JH% z>OKC1scfrIWvovXcOh%YkzLfrR)I44Sh$)(5|C(U%>f2k`gL%>>3sGTxDA-DGF#y$ z0%syZsC#Q<haH$AkH+gw+IW?4U*gI_M%nf&U-3zK3}!dNS8OY2Hk~BrYdU#p{Lq2# zp$9$*YY4-V#3QQB!;;|)kRRfRQ}w`xxtqnhoqPk8W={Sa5U|GrzpuRGs|zP-#**3J zSIpn@eq_XVGTlphuO>E*az{{QQAg(0kOC14L<#qeUybNb;IGh;hpp*P7o+>r!f3;0 z{UGFU=NwQx`k+8m+&8%i^T1Yf!};VE+Fn>Z0;5oVXZDIt&<Br+IfuwQQ^L418xhgF ztPsx+T`X5G94@{Pk1F9?;q7K-MQ`Y+n^{Z>!x(x-(^10F+)8b{x1l*(`6QeCqYa6R zb-X#U1p)MWEuwgA1?z~=MNKl|d`4F(NSXXQ&!ipEVHxq<TRP-|ag^{}wWcEK8|tlH zwwSqM5!q&fbMs@kCDD=iJZLedGrTm@Eh!Vu_mUJDOE{ylFOMx%)y>74&)dFEkKcTL z!6zpQwt=Fw*_E`v;*5XBIG)ozlhh3S6j!kM6b4)%-W3ci&u18n>c~x@0nx=j>oduY zO&y_T$usZFQOIaBb(QkHr!}2fKc(dg^03^l)Mhq(!RM;&5B4L2+3`jc$jXAn%xWN& z@RwcYq=V(mx~LVA(c(4J1m95AX}<AeQ)KJNd+|~E?;mlJ%)Qn0=2>JnC!qg}l~h`z zV5UBCd6<e>$ixo44JlR*R|-N2!VCf>@e0C;>gYgNqf9O>5%-RldyV3>ji`NSGHyLE zaQzUj>Rqz&ND?ay+*QY4r_GUgn!oR28b>l@3C-c*)sy~OJ!?s<_S(&LcGS*npNQ8) zWo<g*`O`Dcx|Ng_6HmT@qhcZrUq-eR=<8TKdb!ywo?r899BxM`BPke>d5ZmSP;p*@ z+mj``xW+lUX$9GybU^)gAfnPfij7vL+e3+&iwPAKgY(lr+!}=(O2=P$Xy{g71?1PK z&l6k?tPX6%c>9gi^p5&oR<YwBnA4AZmlSCZA{ZhLr-unNm~1DPpuVCcOz*;yRC$-4 zP_(2(P-l_UOs&7=M`>foCpyG!h{Ik8i=g*F2N?y8Vp4zqS5@U*zIRx@{TZj*5i9yO zM2Eq=@4wktN;l2G8r&uSt(~@`^fkmWL|5@NhXjfIcGwTAS2?{PvXRn9cGQp`zxz%{ z4>3PUOL4}4muELlK6vInTp_VV$_OI=(Phi;aGV-g=Hj|9f5o)%J%P^nkD-oM`OcMp z1Zh=o0I56TMn6NjT@tpNTmJ}VeYPmNT&BW)L@_U6y{r5sCQ2Ko<C%0H6-|=g>LpdT z<nMnBlJ_bpx7La)5tgx|QG#y1TRej51XroJp4`;gkF()HSR;Qws}Mc<IAr@mxqU{l zKq|X=>CIJ%`VD{JK}Kt!iWju_{$bAZ^j~4|>HdwT)xpZZmbpL@mB^E?2~tL-Wx=h} zU9Cp@)5Sz{a^pD;NhLeWoOVrnRx#WMQ<Zkfc^`Ij-nn3)9X}=h=Z|P)`pOgo@)bSF zjA&=TQ_HH+cR!l~F&dqNXV2AP=7mMYaOFkg(cLez%f&&>YFX%2syK(cZ?vIP!IRc1 zycbWYH|jbWpfF$Ew+(iI7hCCYZ)F^HR>i*bnb}i4=gSh?ArE``yw0*tHiIW$lyx<5 zrBn&9^lix)x~RAjh#Q(?7YZt1NcMp|NVZ?^mRg?;vN)yAXmDP)S!oo%Bk?x%Bf`L7 zdU}oj!5+?QuibII6S$}jm!J$I#6Y#$zfWvx){j%e_+j)s)cjSuiA=5t1oC9?bIa9v zZr{KQN8v)bd+U#9ia0d%1)*8Oz8v!-$+vLPpf)4gN$CNf6!WK&4h=79k`P!Cki>rw zx0QL|C-AYdyhUu|G<x2R9N##v)}bSz)4N<AkIAj>RgiD?ij9beXxlNcnUw9wQ0HIn z#i+X2>wa2%rW(m-NoZ3t&t3<owBeWtDpL2*WnV;e+^>8~t0QhdYEeqvxXMXq9CSB` zi$wJ23S>if!Yjcwps|+LQO+VYe0G?$(^LSvH|%dsGWyFw#ATwKU7Z=@Pwq4JGH~d% z2-cU^DQ=gr=N3HkaePd82rm+wpCO1KP$Il^ST#8OeAr`h$i7>Wbx$|1CcR)ndczxq zfS`nwfS97&K7_B!OXAHnQ3?sa{|w>WD#)vah_q$&d?$t7zr)+YMhb=Yy_iMPT??n6 zMXL6@j^3x)6B|B4<`_CC?J5sGBw315Nz0z5@{6ZKOyod7g&-;Md_q8E&&p}mIuQPT zQ|NB)YrEQ^B1vI94nt=^pgyx=-tW1HjUxa)c@v1?au_ePwu1C8qWj1nB|^c#pD({7 z{I$<|v)9P8_|(+jKl1$rTZT3wlEJe4i_<Wp#Sfg0)aP<#>}C$GbTsVt5kFA}2*2BA zTYX5C`e@Bl6e;<o$DqY`8=qjSh1cGt4u4gts@iekQq%vfp$LQrpZ422UAL2xWvfJH z-yf=xok`(BfAlAzCyP&Q4og>`e@tB<OkwYHiqVN&|5PfgT>FAr&?IpWzwPs~>oNt= zb@kG=z;xafA&>1B(PgRXEdjpa5_Bwic0ZQ88=1ZG_0<GY%M9aWtXURUJF11b+$QfI zBVV4NBRq*?NH&dK8z@X24M{(8pmLC8>5o_$Xiif->$%-8&7GDLkkrYQ5+lrvMKC2T zTrnoVCHv*PBF^#hfFjC>M@!1XQrawhVAAi^K(ZLemL_lLuldda?bej5FQ6fRrg?1G zAJB4<^wvdWjY4Xk^^UYiajy?TpC%xD5`pF&Dk?uu6k~@Wqo?MLLXe_Gpa`E{R0*%) zy+Q0~8T-m+!0GHx%5LD^)4AMc*~-%GP5J_X5<`?lG2;O8OGOgneK=V~RX@*c0m<P= zqzgWg5`!UY82XDL9v+jFm5v!(3uu~hY>E7k8jW#3FY!wX>4bqSq#4tx?|f!F4$k%W zf8u8eL`_>hTw|Qov2UT-4eDuZhV95!T;_5O74STNvbruVs@i=Qv@sM8oqJL9KpIi? z4N>F^e`=*Y*<g}bV@yIxbnVBVMd%-jdkF`f0v|Tkn3v=HW-b<Yf1`~y*YYADB=u5; z4K=~PK@0*gUpN~(lES%zaFICtFqwEJMXphQY%7h`2l+>?VjlI<EF!&7)aM=4Gu~V< z-k9$ZG$AxHwrB~1o$2Jt3=WqwzLR;4A}Jzg|I84skMKh^@KrY5dv0fGr}yeyXM`Vm znOP06jBy6su#AriK8Ji!8lgb92!!9E?>(JCf~4<;zCm~)_(~j6AF&47nu-+neAM>4 zv&b)k?@yu~S(&yPtXfB@)Xg;G5L-CqGDq_Xt-QU<94!Y-^O+}{cAJ+l-H)Vy(MWQI z8v0wS$nqk5340^j!efTyY8vL){LQ$wH_Kt@ZS3Jy?vN}F8=XQ@N~_7MsWdy|_PrL* z<d`Lo-xUSJPCc}S|Bje@-FCZVtNo1l+T$m9=DI?DrqH&~z9fm|p9F!F^n$h`CnCb~ z)7_$+nJMj7f?r{Y0~~1#LN@~91Lf_lxDJsaQ&ZIU@PormpZ@ICd&;{L)g$4BM1nIJ zrSR~T-L@bd`oQ@+@+aae(odeY;Jy>3^b+4)l=pCnPSfR?MZ`ux-0UwqiBG1w(AGRn zs6asY5sP4}tDA{7RJ;DK@qucr5yhB=^|=`}VmfgE4;S-S)&z&1<QMvP#vNvCpA{d3 zysjfhmJmW-FuvB|{dayxS}%D^a~EEE#5;Yr)Pifko-vBch=lHUqHQ>fq}YIfh1Mf) zK%IauKAQm-<oQSMM1<JMF{0wN9V*q{nEIxw^(h9K(PVnZ(VZO(q7U0C6Jx5N`~ZM_ zNTva+G+kp7`;(!;snf3kHKERlcts){X}gItvvy78EGP3r_EH_to&<JzUd28l_Mzh+ zZD0HmlCBwJpkXb>0$FS^(3ceaa|0RkWNUpoCNq>5OqdJf$f_^1YaGtu5v91se8+VZ zWzBAlV$}#nEfAj?fg1&!=c{}b%q#s>cJgdA%p$nm@_ni4(l$r^L?oHgxIFgNme1_U z{kXMjLx0*~sFx!ciQ7n2ErY9<jP*^uP`w)F+;+nw7UZ<@LeFR{)Y7hxTwj>s@RA#i zZAa<RkTke<VRX|Qg#84U+VFUZ+b)s*@s+(s{f0`4)SqCm!Ni4f#QN=H?J5z(yXA+| zJ_FMTiC3`G!IK#zF{vM^SEP5BFd6e#rceAhR=$RRVMTbsnC?SkoL;vg>2_xeNkw4% z%7ICI^;F>fvR6Wxa!RgH%C2xr-4TNQG6em(<(J)WCc<BL^ofp%I{8+<H3x~=ec699 z6j)mqrj$J@foVQeTUf}&#kDt8GThUnQ40lEnQVfJ<WD7f;piUVdM<EJ>g)EJa-k&0 zLwg?h;lj;Memc0G@VC|<nP^I(T@k#lg#L|LP<{tWKS50@xOB?lN|X@xl|DPC*9ZP# z`@)m_yfN@&Yhl>yzEGqwn1HinCLf!2YEsElou>$GA0&BcAm=nYWwvVuMLv}utCPzR zNrzVK>zhg>ZqkYFLc8h@6Av3rqWga@*R;|$*UfX9{Mc#RL+x(5(hBNCpdf|#IOs1H zTBI%Vv~Q37tRNcvKe~Ghr#PZ6%zKbv!2*QfPJrMR2G>Av2oT(Y2OA_<7(5W1;2I#f z1b2c5C%C)21h)WtdEc$At=ir15BR21MNMG3d%92Gd(P?m{GL|41fj3Q?<^zVJ?Pe( zu^!q#!C3zNe&myR8%E_{rOotq`k=Ipz~ZacpG8d)p9GL4rA*c;))OdL|Ftz7PF=`& zV(ZPB3H<}&OgR0~CWfYz$<}iRf$D#OW8=)?iS;1`7Jk}p43iDAM-=sUlJ$2;^SVXO zX(}JRO*RHN<qtXKDYL&HL&&s`5$GE*A|TGvTwRv#HhGhNa}OPK=LR&2uoFo!WIB+O ziM4q`Am)B81o00Hziu|h$?;w?O@vlU9?Ys!NgPYG>GgcaOhw${I7hIYK~EP(ionc3 zd5c|l>CULjRmLLjqaB5Y@U1Ng0V1aO7kOpT(0@Nbc*uX3R0~yPiMJy(8&0(LmhO>Y z@#~k698(uGNkKYG6*A0o@Da^nn!Td5v@|zYdW=V;M%$2R4XB}kTCGlxEdaNL2){kM zT<dK*QmssJi`!3=)8GKzHf&;<Pp_$UuQz|RR>&Uem99tOZW*cAabiQB+>hIZB90c* zbi=vDDz#(+4y{KPOCk=fCIx=P%c+d69#KTVRq%Cr2CuLDS`|0g(viALBb01hCXHHy zmkJ`_x98Y>5Fh+7FL&?7zE{f1sj>-5$-(~kPl%t@Z}3*HTsqF(;_`{3BnvLEH1xA* zDIty3?MtR2D$>w$QT17Piz7>puCoz8{99bk*4xM<{ruc-73Fp|)K;{acB}mQzL~CZ z`RO`tlR3%{5(sR@gs_C;seOk|!g#%`-L2T}G-LHa-0X$GM{hfV1(R4|%MBJ}I_hL( zbL`K)_1k<uFPMH4RZ^x)zFW}dBmEdJC=zt}fN7c_{ONh$QNZ&DtdJK(UsgL+8jvGO zkqF4}{#g2)dn1J*wznb>u+N_iahzJWvM!SqQuz3@BjkyF(mFw6)I}UXl!8F_;n>(M z*dt0*80(7uUzEjRBpgr6ko&!nZErIwQRtpSMN4@*$|HWQrlu1T5_wFe-&1#KX=uDr z#gzb#>#5LVAf}f@i%UqDyWnq%$^0yM&`;7}am(42$obkPfcmao=`+0r1<{3S8-D^_ zuh%yd(FQc?!ou0(GvlRpt0A|^qHjEePwT<Gwm4e?|EUv*FT?XbnpzYpxaK?49F3{X zS8wI8K(>EtQhP4zeU0uv7wY>4!OAn<b%IA(G4EJb|HHz{bfyayf+pJHyY%_Rs8qw% zU!Mann~4ot@Vn2LcXAJOb<>d^rsA8^i;t*@R8iQTJZv?!2^I>$gXJ>^$=u|U9jXj$ z4YGKCDKuRAAuPWSm%Su4!x@?HRQQ83h&vHwwZ|o*$=ZR&(xr&9)W~1S0!%&9O7aIe z{aV}`Lmk~d__naOu`NzGwDvoN3=l!KDux*0t&DdV5qz)0?HR+psTR@;P`wH!g-r+- z?P7&(HrdxczT{eK-PyLco%W}oHcjuyO8s2Hf-m8$4?Jb!&GN>qw1MQ!KOPl}q1kGU z-{Wv0X~$9vvGYmD3n)^=N>9HE2jwRG1<{jM6&N|$=e<~6Tsq%fdD}2Z7?I5bAEP0{ zcOj54aQ$7E*hWUSXrC7)4fFCmgHInDiqVPT!F(?6U>|5bH{LKBK*o_RQ1l)MeqD#R z@xe;!T?>p*1+pYCX4);hH&dP7sB&~&nDkfB$;v%U@chX<-pCB;<xdxMWrNVg$m&|q z%OXNLI83#>h^&*P(HsQQE|m83DqG|p$y30fxC^tR%+SY}D6hMOu6Hqy_3Q#gvU+hb z#h54n_cKF{LVC=zO(cj<Vc|uil3|cijJbvea9)EyjBYzvM27HD$a`8S%E(Ng@V^}} zQZ{&TbrDY7iJ;A0ug_wUP>z-I{Y#)wO-ebnPhSRClNj9QyS<bCYG>0o{czd7I>~lH z(&#zmmy03<@DIM;J5rIl5~_C?JOc`@(^oT_&EEgYx{ERbdgZyY!AR@v@-6G(!|v2h z39*c_z;3#xl2GWa4uX$aY%={NF(}{$_{roYor(3oc2}|Iz|mcXob7!LJx(?*zC%Ct zZ11=>K$efM@9)<;y&|o2|FGV&!Yq8>p9^RGb0|2)-}rs%cq?;q?7ALvq~(5EUD#52 zq6wP`Dqb;5b|~qQTL^A&U2^Z<I$Z!_2(Om(cdukeAK?yw+5;xTMPRmgv6G<ia;jK+ zY+(UDXIrb7#Px-9a(4FSdMmxQx|%p}#aRHz0k;06Bz*hk%eh!(wRSj!0~ef5De6ge z;PGhh`s+?^aUX(YQ6P%uyYF)`gz}KYfWyJRK}jQ`64UF8@D{u51MZOmI?p%pW4|29 zPK+phF-0maGB~Nr0|uE_<39+*ch%2Q(DMxGDyCN41<VV^Os26C*{pG&T_bo|$RN+= zmzL~5#-p0N&KRWh{M!aB!hrXp$KKCcF2K#Q`p+v9SfsT9xdE`itEqWC=nix++S*A& zTVp&23OoDT+W-y2hbsXn0?G~!4ggyQ)J*iUI?bN$JS4#O)0&YW+N{2~*rv_zi9zX9 zbDh`4j0Lb%1WWFL!{U6oiOi=@)j-`{>iQ^s%2TE+1R_+RasuY@ogX+gG)_-Wz}j>o zlbXr7sW|Zez_8TC)zu^ns0HI$v>hkwPPbPgfN?fCAlD@+02ff8jp&VGn44l4tcUB* z)Y=;Yox<3TX;@mN7&nRt!~I{&f58c}xDwdJ-B=eb_Cwb<?LN}(&|VG!zMzyr_@u&j zo;s=FzJf*FR|~f~Ra>rKL<LA{iCl}^bm5M-z3b;|sfLC`TCaPNAm}DAF#^3C3Gpzh z<<^Jh`Xd=ims>KrlFC)go$DZs-1UMNWzjB#Qwl#A;%>I$8n$4DPjNGzJPjK~9f)o$ zXe5Bj@c8Dt_%?W&*JZKy62?L`MPnbX<PU@$c4Pl8H7(@eo-v$y3Uj`Uk;k8}UP9!? zoq#%!bY3QYag81}$XR)wbNsx(wl;6ipa@oAaLiiy_cdD@+gK`+_;M6g$JP$km*kXW zLUx1Hq@-T{Na-wa-hm9Jp=1fxf#oX(F`1v6)795kL_2m9ilzgqxWA9Mp`9HEC|O}) z*V-{Stw2fi2wDMx{{EgGVEj3WBv3c<H+ab6eB>(*KB^d_hQtSUQn}qIq(LI-Nluj4 zWvLlKZJKD!?c>}@By^v}9onvPAY>dU%do#WzBi7^9tEksyFrsf8CImR>`3Om3@<RY z#O#Hk8b)V&)@}S-Z{r07=YEzPiiroBCq~l&3Gxx(Lu6&G0m)K=nfBB<@VPyhujj@K zh7Af+C{y8X@9oLIjB$CJ3A{6}Pd0#<F|UB43rJFLZai*%>At<CtN46r2doN#gDk)k zz@WglH`hugf((d7;M<u&`|Q9;)d6VpQco8b7lDWgnx-_T2+VBD00;nhqt{5wM^^#M zWgtTXfj5^sy><HMyYMaWU3P+!)!deVtpNRMLt~>Ya}!`Kb#-+C{ZrU+{l_Zumc=sT zj)qTrqX;n|Y}xc1oPh!9MH7jM&B1InkX(8LX^u?fr?<2_vGU?65#24P(s@!*Rt^bB zk7-Flo(HXf|5N7pN<mvLY|b=l<fn3J;9nz2^<z*9kz|q0W6V0z)HkX&!b7%3uJ5nu zvBRkB{>mTZ9&p(q|2=D5Xqg!~(r|#vc3UtFiN=cZ=Lc4YlFTd<lnv11MDXUH7fs*~ zt*S8NmSJoWKL@Ey>FP(q9|Bw^ND~+@9@6BA+DTG$_dO4bo+$sCpTy5A4Dh-#&{P#` zsGpxmspE0D$dvoT#6{~<7RNi(*Q`|ZPrmvXNAAE|?wmAdGW>npJNRntfZrTQyvzw8 z(Dsl3j}K?wO;Z<tI*HX@b=g1I7y|5qnHfEGc2N;C88$GMb`x5hoQ#i)djbLat%ed! zU<*k=5Fn8W+;V~ZicPC*xr@}^Ss)FBF{nRk?{t85Ex@$NI+VZpIi3g4l}?|KN!LE@ z;D<3!81%hG%u^}fjs41<mse83#ev^yRR~$qh4B5uO`T~~XytOI2ykP7a<`_%++eN= z59=dEC+k4SZjuYoSsODvwLg-N8uFaP7IR)%O8gkn+Ukvo39aPkqmu<X<=vwrb{3XY z9xFU*QvfWXgr9w5=?8-vkS_sDPi3W=DnadBIOoN+C$P>1M()WSD~YcUoWpC5E;+l< zs0R^DY)UI_r^}21j|C_);^_)<bIm~%0=1_Wz$D#WF4;4eE*;qeiIk1aFCf1JY80TB z1A4@d*4Cmxlm)1g0FFTu0Qh3(;G7tRZ4D%;y?gh;P!qWQ;`dh^HXez{M$>%jnX_+M zn42TTL;(Wf)P#hov9U@Z#|sQZ5ma!%CgFmSIsi33y?nd^00Sf`06*o*k`g;`!vp9Y z_+m&tX@ah^-t+;f%9zPcDs;{n8un<!BB;Hm(di4Mdarx&L&iemPE*)!m59h7gs}pf z2~ZL16Vb*>?}cwf5@H;`+&OMkZEZkZZE}h<mB4=>a+#3-tMgFF;@!RfWrN}LMEb$E zc3FYa-^Y}$TN>+(s&}ge&n+OWW|UkvWYsMyk@pOT)+mVYS3I*;NzIS-6?&z3e8bSF zJPTrm_QxaK=_4i#S>66^)GR{H$nIt+XCDqqmJectRnzoWNfTl-rQaj^I9Z50?v6<x z3-6X2zG5(pB6%%$K>G7v&TO`Q%A2Bn1)Ra&u_Kq3io6ykKZ-skDNlQA-4yaoYa1IL zMJGT50p%`GvVqgFmI^#$wc<720m}s_xaom%^AQ9GG=`vH>fq=KX9glZ`=;~v07*!P z*E@g))WBLlCwtVIx|g%Y$Pd*h%MlAjHB5e(w+@H~g=n-A8=>c8hg15mD_9jZB@6_Y z?ba4B2J8pU7cBRp4nq1{iTAy+2k4OH#L2hSbArU5BD}O1AcjD&M<UwNKRc>@Vci;2 z3r0d5bk|>Sa9U9i6#2aR8(nb>)Yb_=H9Rr`=qA`<$3RO;0eDnk@T8CFHR7;LHV1~! zX4i|Kj~0OaIKZFq+0LqKYrC6AcO;E0x(OL*YhVBEz+nz)CraTkMl`Vj0RdnUKn4yJ zqAsRX-`*DMRPW}d*o}VDkKX{SLjW_HnwmNS4&7iL2k;ai{`?RIj34&_WTo1v1cdd~ zNk97$&?nxU?NnL}%~xA%e*WCpztM0yC<sC~YtI7=-5f-Z47wowQK)V{r1L{L5HywO z)sI%NNW9h7o;e*7^#-x}h*kwZ0&u&g0p10;4wGYdZ!2@^e5D;z+>C>ETl9KY@)W%? z#OmD1d0Wz&*LRk>`YSS`%W!(3<-in=cA0FFEDY|<b03$~-2LK;VXNTfMshE^-EhaC z`cCkO=&j^!{EcaZ%x=V33bWqBsgYM}ut`^Ehz)ERlkNpfC3&ha=t2AA(i2D(tl8ig zE9;7_#GHoNDy2_8xfhlzJ;drz?3KTKoG|OL#$()?-aLP-?7AsbPBom6kwBZ()r{?c zPb_d6OTT#+WN@6fdkmZimgKNVg%3!>k8v1^zQ3GN6TDq*B>hltu=BPtSDoMneh6|e zQ!ZIFD;pay`h^m*egp%9r6q^rSVi&0g^Py9K@2}|79EkHj5C|z2zyKSW6y&wT1UOg zJ{-Xa1n^)KzS~33U9j}ukq(}%-w?<fzV?neHMxU9)E|&69|*25`~hoWq5yNF>dPnd z_TL&E>*7u*>HoY{S||wksDu&?{#X^hbI@WR3N-yaml=0@Sb(e-oxQmk4<^n1c_T0t zVr>FdU#e1lbF&B;wqV*IK;aMts_N_iAp*bv0E5%5wM!%a(6AA&ODBtgj0gyx%t01d zYXEGZtT7=)V=Vu8HC>Jt$-||A)V@2CG6<JTky}*M8w5<RY4p2~MAB5a0PG4t14rB2 z!#qIFTMqo;|7(^TO*bRcS**?dm@U9>FMteHyV4xwkTXeiF$~IpC6(&b!2$Rb0MYde zaNnHpEN`{?dU_H?y_=hGu^>PY4suUXV3-Z)6)c3O9!)_1*SHc$x?k0P>M)Ef*>1}G zYQa_E_=;SNIAmu(`g?xOY!_Ap?!4-Tw$93|n^3uj>qFir^du^Xo1N>!T#(77!le*T zw<wcl8(Jq;7r$OcmIWCRY75eo%g)14a>;_CY)i};{mvctFVTAL?!47HFV&BA{4f-) zjS4x5+f)!?c5cs|jkMRQdcDmeJ|{8}OX{7PMQ>&rx@ws?g`&c%UajOU?I2<+>$$2r z9u0P?sFACNU%$e4deASuYS6iTT7AeT_a`*lj6C^5y=aY;dN)Be0K&@B(?8hvaSsDP z9jG7qjec#*SI27rxS{-Ah!{KQ09OWxYsJNVn~KMmmRf)c5u8iFH|XF{7~{e0FnB6~ zmXxcZqP0BK7huUvvkPJ>@N}eOO42DxKT6eMw_FK~O%D_`4``-a83K{cEnhh3JeHg6 z#TQVi8hw&7WW*zVm<2Z~p7YU3LWq>Ci~Mk*NdBTBt~v3zL#2F7s0y&UN7MGqvbs7z zegte*cJ|WZ;sG9aDA{Ywtg<o=pm}a;68`qKPOk(|0(3(U$O6G!7)0UGgN>Lvk;K(S zhAl&dYZNx~aggW~z?dTQ0IG~4a_(Wa`A`5v=85&^U4YP(js6c93J@Y{mVvChD}rI# z+8NB%XqktHcKUp4$56=n`ug<Z<RVTNaMS&64G~}+HYiQtltwEz83wxZkRO)G@d_{R zyhI^@mXe*DyBV)*S1!4=Md+`T2ZIgb4}3`sJP28k4`UtUOfyDiE)wF4Yg`lpEJ@cZ zv6NigSdQt^+RK(^Q4h5*x8?5l*E!gqDT>?;Y=uV^-;i<5PDK4Xof1gCDfaOX;JsP@ z<V(5qU6Nlf6`RyWJY%&Z*hS`?eSG#oVuZt$KP+i!_~jk_X@unaRj$U(XKN#m)8ZfR ze`cTm;0oW_y+Cz4X$VdE%=enlmi`%RGc7Uk;c3>sc=t+rU-(gL38ms?sr$fX&yj>H z3E^d(Fg-new-V3A*;!)l3<v|GHpIwoUc31^e^eZR^O;`h1h?0<rw9b?iv*xLj2^Fb z1MrBrxHt!qbK^p$$~Fioq#$H9Fr>$}4c2F2){zKP!27UtxT=MD#gBp(X<_ST(2JKw z#8JpLmQqi|?Xf&hT0nTX8Sk|C)Iy+0Gf$*hJ{gN4hoNncjEnCN28yBo78H;7#Tqe0 z_TgMtB3573()_5-FUn4dr58=t1$Nl|g5?(g?}{WT0G&4{E}B-nneH1w!SHt<i(of> z3GdkiCv3u!Iy*j2@?UEY)|c#|QR`0u?AJkE$erO_zkIY*0q?uMO)Z;yB13n9qeUgY zS&+N~H)vc5!<*5BK~bD!&Sj~%&$Vg~1SO`}n~Mg7Ni|3rk$*0iv^U(hVEbPdR{U*~ z6{75pt5LJ|tWEk~*0%^v2$ueSb|y!-mfXuksuv)YwaW#`$8&s@pDX!rV6no7EoFk@ z#Kc%U=B@SZG<**!xf4~eN#CeW`-Cc&=~EFouPD7fuUKnp*}Iez*Y}4szXzB%l4T|> z^T_wMgVllpS|03PK)g>H!kXzi0a_yyo;X7H!)Svo!eU5M>E58=+C5{d)f+k8fX?<N z_}&|Xi;TQ82Mq+eE!G#{DCe-&#n~k<FAwNa?kCy(8x<@-JgyLLHhBGA_;UoMsKI}= z-T(<dU0n}m_tJs_*>qJjX}d$du0WS<_0ze3=r(Q`bT1&vNlR`oRFDXc#GbDfDCeC^ z-UUI(!jMfh+E*zN^Qan^16zVLk7VhqwvD&1$WC&RxP9|EjEQ+{kvda$<vvbv>Y%ut z8qF&f=-Du%>raTS`;I`fYJP}R=HW>gjf90^ra$ImHugtlNOE9IubJrHai$3XBwm5b znPzbS4XqKb5-zwi3M0w0(gE|)T`_9{pqCJaGKH)<)<Y?aFULMDtiV*{YzqK~1*pk( zoC^zgVbFb!9wZ#0C_+8m4BL@dy50>(1Tk-KZvkw(IfL5_fffN-#W5Re8$&!ml{O~w zYFS!4mZJFvxQ?WO4r7XZ^?D^E_Amc3TA}E<^rfZzqMTo!@vI%MPGT0JdIj4%8E9%l zgNi|W$+$dhnjfmWpMvyszE^w#+g}C68mH@iALjt4dH5!h^1^emm>L;@;X<&Ch8k0h zU!{v_Ef!%-Y(|Wh!Os($47PHZcwR~>c_}h=Gf?C8XEm^sKFrI@ev$8m1s&@kyLuWw z3`6S446Up8?xJVy=RN%FqQFh1(50)!E38r-{wZ2+l<~K`*v$e_`)<zVCg+mZGj>0c z2B@=+TITNd2k#XaHZiZvzPkl*P=yT;aj2#I&Gy>sW?&FnNI840{pRg)9i5Jr`ueH6 zaw^mTw7CG88kD;Fd_e9F2o`{g@Lo*~5Y22@QG5XHm4B$eKLzUWgM5_-a}DrYXwUpN zC4-1kDSnG}oHvoyEVV4+2v6V&U^MX#yCOz6Q59s|s7dq=_1uZ!<r}E{TJ8(jU6QPO zR)!oVaeS`gfJ($!Hgy--!dLdY&-fxHN|Y2&m}x2umjfw`k;M(;AAKu}7}_k3*cNpZ zSwWzCYmog}s#hgipj{xu*9_&<4~%G;DwY5t1zw<H1g{!bfQ-Qoq9wpc6LRMw!koPx z1SmGpBdK9*)GGngp2c@}b5N<*6al88k>DXfXH4(xhWua*as0d7X2}B(P2j6DnYsLw z)6|^Glnl~iOJM1@s};lxCKK@_f;c)kfewYaIl$TgMwV(U0Kl~@QKBLHwPgSr7dd&k zRv2z{dOCZ*qlt-$lT&5)S{o54fdP3aOD1wQ;lfEUn63b@U;vGPEkQn-E^n;BO6L)n zEF>s6cXZjkc5KR3z}N?}u6@g)>-Tsx5th;YA_d24_Cr6r>SU@4Te9vkOkeuyW1ERX zkdZd5lCX<Ycj0*g7n^O{i@9`bWVGP171>9=_eZ<wy8C)Ui@;Vz0s9p{MQ`2*^t=d< zJ_z+PS@cWmNUdu9n@pFx^Scpz;aqufr6=83261`!Ew$$C>Fe0^GhdWkHwdBzp5p|M z7sxzF{=DV=t#~*z${?Jh{13%xlbSoC_)24h!t%FU)mVhg-1W$kcWtP{ecsfQ4=7pt z6@0;Oh#++oF7E%V$B$ZuVfrr!7CC|)y0|JUo?>7Cuqv?$$j&aWJ#($<77oFPbud#I zgo}rX0?=YC{qG1mk1p{gKq>>^EBpXdqd!$^GxJVg{{RLZ{P_Y^RQKB@Q)9H4i{C!c zSIappik%)|p@Vip46Q&I{{91{)=8Fn($&AbjC<M)fqV+fS;RkcnO7beFY6qa54To2 zj>J!uG6blQBNVj$)t3Dg^hY>sDry^jN55%8xx<CKCx+(388pW4ezG1jkq!stOL8vY zoHZ=iDUM-w5b@dRd3kx6n5==RgaUL}LH-I@IiN5~%(dDY`sD0vGgor}7+WBvcN9>g zUdtSOW+KFs-Ad#nkOrc$^w)`;z#lun(TN=eeNfPbbw1Af!3cV_zE;Vg-Ei#Yxi|Tf zm6f%ya4?xS)XA=;4D@LuMQ$uN`r<BJ^$iUl`j|_3`1l^Xc%XDs%T)k9D0y%12VMK7 zYMYq~a1+0!JGs9->i$sfe7wTn$!Ds44=O(dqxJyw<lKYl@+<&njn3W~%j>TIt+W1( z5Gfh}2w`GprxcE&2_JoUK`fgEqi^~YlXYPsx9~CNM!Vnu4nHv@UZb>#;G9@9kV-PI zQIOvT57lnX-D<}fCc&Z~`?oIAtbS2%jOF30F%1C{RNb`CpJeYmDb#IyxnY3H^e0LI zgE!4XF;8{M#JMxyjx#8L94~~_MlbgtXdZ#w+Czh^q1A{vuK-rLm`8DKf4<$aqQabS zq~Il0bVEv#7?B?cdIXN23Qw6t8h#s3l{rhZmdZ6h*ttrUUZ1gQV-wS3c|A$aG3x!% z)qFE3Ab{@R<cUIqMuu$xT1twFSk&2o-4#vOs9p=2*MNE!Z}umVvt#dkx4}+(5>V4Y z$9a5w{0xw6J(@tl{5>v?*J3agK#%Gd4xfdMCh`i9CrIyX6Oy=bsK}zxRvA?A$p>4_ zDsx7q!LG~_?}?DRka(%>2^E@AFYZZFXN;tbJC-^$mry29#{-Ik|F)(KH{joph`UHE zD)gjA%`(Ji+-N}mz3Q=BKAV@O#a7Zr7W=9y;INvFRX92}w&v0ZSS|;*uDS}E#ahRW zOLrvzA*9)I6Q}=nbZH4Nq<*#o@UArA>4Hi+q4|tnQ0b>ta>?F~FrYS_y-H^tE-VE7 zH6u{?0N#m)#zYAsJ2SH`=;I3{+x&;vt<N@9RNB1j(nxILQn3(CFAp9Sd@SvGEb`+t z4Q2os4&)Kw830#OaZ%CU!9f~;$n4Kl;s;A{5a~60Ue8urgPFrPWm|<2K)MB759fi= z36z$0E%hXW_S;)9B1=nmg|as%e*0#u9e+0o9wb<ZrVVZBR#}b!`VlB4(-dAV*j-+; z;N_M)dGB{!v^phh5j(#HJ!{FiI2a`N{>k&JSn>Y5_L*79RTMGOAX}b-439K!asHX7 z)sIF_Q!jPWB^A=8vErmy`~ae$!NdvTYM0k^s5<$y8WO4gN=ZD!v|p%Vd1kIyu6?zM z4U=}5dt=v7<P%?H2-fiQi%9Y2T(h446_q~_L}-0wkge!G`$`W1qUlNhH`VDVB#m82 z{cjpCd39RgQm}V<^^sQXacPlbDB{T*wmD+!uc=e#?{G%2P~ya&(`JPIN#gD{h%78F zu3~v=Vv}qRsGz{{1*;>G%Pa)`QcVun0D!LI$iZAKcyV`ufy1u(8uYK{r=}9(;^G>T z$a6Iwrg?5+dwnHGmz8AgNSSQH#awbqW}=;7fdZ;jlNh&NNb(O4>bBGEEnjZVA6GeH zk*9YwF8MrvKsYpd#h<;7!dP$IgCGkr&eukw6b1-|X+0Pu;1S{E8^^495pV;TxL}eS zyE_L5#%TgLR99DPk#pcF*3FHaoSYt;Cb;HYNv2_-tpvJ?AQp;&1IH9r%aSOd7J;Nq zJ6>_@?Ao(Go>da<+OyfYmbSkFpqPO5MYgi&-8kDh8!M}R9n4r-I?$L1bmo6v0>c0d z42=DE_5cS8Xu+V+m=Od<9h(D5F64?}Z<3No)W5-FH^9jP=&wqBS<B>Heeq@xw2zGW zqWt_iK)wN!hOUkdIPz}1V5Kd4bpV@=i(}Pq;9+3c0`qC?=<4b!Xxss|yHYfr98-?- zO8XbKgd$MH74JovY@?>>?3~b$s3|pX=if7seMCkt{`I9RJ1;EyGynT2;>vD`4l}aF z5C{Q!0bU64zF25;6SYI#LjE47&h5{9B~FrJLL-+v<^U)xGQ>%E^oqs(*lnth>3fBO zc4eL2@u~7uWe!O23wsYJ3#(hAW+(j-SSqE`PlQeWnJ8S)GAHkDVoyzDN=Jswwold? z98JGZAAqgg)1@S4{d3lU^&)E;MjO;n$GBMSwY|POw9wr*{%kLz4K3;+o=T#@Z=9E( zI<I=DNXePmve1#*&!Lw1dWWwa&)WYXY-ZF(o6sUm9($=<UUrBrN+@qIL&9P&#YUb4 zg&935#`t=7JjCOaq3rrIRbx<<2}J`l@&KX?#LgQ*4=mQx4>G!|_2q_OlKJRnpe)x| zwCZBcBeHZ1dVkqX5O+bM8qSL1ds=d9P1NFC=1i}s%u048yzh>}_~Zws=sWAP%{zZt zx5w37n_0&iL(qI_(>Tuf!IkRMZwJs)xb=tR+_{6n0nA?y_d)h8cQr#>pTRR4(73Uk zd4n_^KQ{QeQf-4rF~+RErUpDnO#cKWQwIHRQ2i;6jq_lc*z6T7j7X@)@>);YfaW^r zW=9I0d}TdzsiYH}fN!^_{b1}htpMb-B!#|;{nKlJRvK%9j?Qs(?VEIXDKIH+^@cBc z+gVn~-H3=q)7?(sN$e-^ISX^Z$Ms>NmH`M5?Pp?A=~r0H_66@Qi@|!K0{5WtW=Xb2 z$@H^?_kUkTZ1~ooCuHTYQ&^_tX{S<YscdTTEEXgQ6^}I7W!21C;*4#2ai?Y@(~5}^ z55c0Z=?9Nz9Nla1U>_3vcw>S-1rAj@!ZR|P50Z5k-$mTLv%5ocUT(%TIqC4&a4m3c z7sDX0Cq%Ww!{kic^2k{des{%A>fu#MyRQn9?D5?1tf6G-2bIQB#(Wu@jJ?*Nc-OXA z5ye>2E5K0Bp^=$jmFCEH`W1K)Rb`)~e4F_bduKZ5C%X$aVXCmVb(lypf-1EhPU#{? zK77Y?%h;0#RiX83dvar7{=X;%JUU+rU%nPDw@<bHv#mZz`3Bo1fwe6t^=g?$6wu1n zZwTr^rf4^$nO3@e*77II&WWd|Ba-jsVtVPebK%bwwpfV*%RSC_LC>%gJoGSZp0_jn zbhcd%7;cZn`r8hUz>6l**?%#dgrS{*UQb=#3c!P_N!@Z=3Y<TrHfal_DXGSutz|Aw z9)@V@>DkzW3r5K;Su2h<Q$M<6;OasWSXc=9j0-K^E%4{W7grpLPWS(=U8sNDvFwoN z8jcQYe$o+adiq`VD;h*bI-p)Yrt)DX@o$~us{6+8kM(wG^9_S64f5$%ip-ZNY>lXa zgZdExLIFOQJiHsJCYT1#4K+7^dHo9IHiGp91>?R&Qys+WWAZ=UzI5)Je$V1G<IkdK z<*v(r5sF}iO%#W-x1l^5mZYhHvGB#R%FZFFHS(zEXOHT`ioace&%66td)FyvVo|O5 z165UptppF965%upxNVqGc9Q4&Z?t1y4)*s~8u@X0x*5?6C6xy&=_cBy1Kra{oe9!) zLnzwwf(YK-Mees9K;uq~m&(N(G|-;(BD7}i;Z_|GbM=zum{Sxk`qr0khu!C!5J^Di zR~fp90zGSLLay)bL2tbofFJ=Y5DHrs17(VtHYkli#VjiN@YuAE$&#thQtoep!xic9 zcBFG@tJQ19t^!{zyj^HI5XNkhz-;_eW@}^XzqGjMwcLsThHIPAFKGl&&?a)W4<Ac@ zA9?2d!s+G8&H-n+#E<TY*>vXadsO=9WeBr<u*ixmvpuoX2K7h83AP6U3+%jXzcf|M zxR9&Nr%CyWsi{5C8P-pp*^>|N<r+5~aCX3%Y*j!eC|=*mk}fgZj~p*r{mFpu-Bh#Z z7WoVot>U++et2_yz^`%r@!vahR}O5uC-BMag_eei@BDw~C9i9hFQm>w4OV;j9j;!p z&@Wu{Fu$JXX)o^-kVb!zdRZcku7dg9%o6r*dHB~`kxhN9TV}!EoNFUjg%*M2?q)$~ z0Q+47TE}1wL?d)=>-2FxG57`L<8uugGdkc<XCx>rDT$}E0<>)4iZ{T^^SN@ZJCcu= z7i8(69x#}_{S+pdsRF!BHV`|Ao+2Z<?5xERlL-D&H<sPKR^Y#2&bh`S2t`DR*SCsY zw2u{5Xu>}*lU|<O;2ckIv|&b-s#`}CqjOZZ@=_~#5JsQyL7#uY(S=oKZYR&J*I|EQ z)8Rxaxw+IdcJ5#+wESB(=9X-I?<ta@;r3-dot<9v{ldkm*InF2b<htCaSiv~6lKC^ zo=njdsK_3PL}&F+_m+p-PbapYzL<PUOd#ltb1^)<LyO_8lXWotja&yjR<J`c4T>9- z#Xa~aDfq`E`;V!1O~Qhb^^mvhWIlZ__WQ7SRZd*W77S#MuZ|92c?4KfZ0DhG>xO<w zhKe#z$q{<U)kjfLQMv{ezr9hHUr5tuUX2?y8wh^NA#Ls#aKU)a&iL~v<KC{dm8*+* zjpDWZVKw5|voiKF9-IleyfDnZ2P^oIy~_nYazy|hO1ehA2wZ-06r)zW-uxsKx|z!L zSMcv)?)t(|4I^HJ<=Mmh^MAASNv~jqV*TG$^E?dWL_D02h3&(Yo}PuttQmTl$7YuA z)T`~l+TJ4NcSV=JewVsih2lorS;uyhT{Xg>uKz>R(HK#f?hn#ee|%zw*_;}j@xUc{ zTT*c(7~-E~lh}Ft4fd@2UOh(|5XPv<HDR^`GiDUhJ?^i#{K-?_e%;NsZy9ekcw8|! zgMg0mO3Ph7tfDmeOD(r6=Z8s3f1dQ$OZsucsJzGNcKgEPxwm9mwRJR^jd|`ZP9|Mf zHuQEJp@_}PM3D=bg2rVs-b*#LZ;*VzGUbDG!v1x<2_8o!vgYuPFVMgdLFaFnCk0Mz z>~9adX_~j_FD(@ig>S^T+MeTWtHlozu<=L5#R`aOkla(%{`&HR8Um>u>uVllY3?5| z6mMEXkiTI0XtXKz6xnm*4;NMI|6G7fE0Z&*yk2ve9ihlrf`oW@obrY_yrNX6js5~- z#Y`8wsgLbLE5Dn@{PRk$rlyB_{gt}Gd5jRtVji{o!RWBY+-pRoVqLx3LGJ;?4Jv9_ z&$e#qr+>zVJadZeBzL8^ClrZ0PpuR3-D6mX`C`87Q@P6w$lubQjqKodPb2HV&e6}9 zdMyIv?UrK$tg}m49s70aooIivinYR%Kr@uttuhWye)^t+mlT)kBf^;4d8z+<0)4p@ zp=?v@Ru&{w)3cbjtUC+zpX}o2M5T|>V3695K5d)LC3C`gi90n^#Jw}FQg4GVE7)Ir z)Y=+JVni2+Zr0uA3yhYHR1D%uOOkiBdH?7pQ>%5wm=~Uo6OqR)4EN<w1uPrBKD*z` zRf!L+k||~&MD}t~<|yR!EMWU8iL7&hjlW9NDU)6#Z75C&r^vKbpd#kVMfYvqd_scK z&j*=tz%kv)KJpnqE}y^f9dAO4CZvKe7%v9DhXuzqwe}gb>X~_F1Y&R^C8DQ(kM<27 zb}x8MIUw<N!@)=lx$Jj&w1+_9nwId+9Q!BRc(7{!uklx12t-MWdn>uq@by#8cS}-i z^|;kOFHsG`>frKB1-fsNdkwFJPSVo@lW$o|{S>>H{5>h_oeD2~wVP$@LujZMR$p$! zrgJH8RfXoJ>AW<CF}oRtUW_R=kw(zZV;ss4lfJC`4(C|<NfT<&u%C$Fdq}QDrx3dN z<#zk2A@?so5dremIyJPj7m^vuz=s;~WsgEs^H5IB`MV>w0t-|*saE7DpU;TnqH#BQ z!(qe&e8C<JFx~|DlD2HsLEK8nbZY>bNX;q?q5ydoK?lJ^LqIX|DTXS!EKA`>Onz(j zr_)oENY8RZX1VP&9Uahqe<8u`P5dXZ%}jKaprrn}QeCmCRak4$>a5+`)ZFbPdBo*! z)+DO1D7$i>n0fU>9nKkURzudm@)S>;ATbVd%9MyS#@V>04rmNJr;Y6`^Rq8TlH|qV z4jy;Vsi!zww`o$fS2;ElzxiFRUN0y}H2P#$LWj-HM_#bnII6;{$X9W(Z$e)VTbLI< zL#6V|k66QcyrT8my9?qsIFjve$?>s`2B}Wt$6B2?SuF;sT-P}*L=x`A$Q1sN4U7hj z=`^I?NZuY0!+XMLm_yDCQZ2iJUy}(d-C##+36D02ld3o-NWk%b&eMahn#>ziFApYw zF5C$eN8~SNBK>d-ljW#y0jm0u$CH`cx<Nm>8x+G@F9wmtBV>}J=!Y29EeQEvZZIYt zj_tY5(oWtJ-WjFT)M^WkT0zZBxgrqmO}{^|CzzTG1S?(B+hz0p7Eh1vbl|<-W{&<G zl%xJt61vTvE0(@efKWu%4<SoZ#p4gT#g<?3&u$@+iCnX!)q=c)phQ8?eCW6}IW-Xn zG|<Q#EZCglva@5<4tt)MQ`5$Nj0~lVwdoEf6eFUaE1L|)w-sZ}fDl5Eq7Vp-fUYg2 zM+o0?lZ7Nv9KNB~i;Vm=7l}n8VTgaV4S@_V8f`aR_ei~a5sJGoRk%Z_iB>V>9O|Ia zF7o`vRgUvtbZVp2+B03%aP2T=JQ_55h1c}TcWo8>W-)pwPfnwYPJP7e8~EeQUF8V7 zDQhF8k)z=f8SJ77cm7I2X!(Kp`gRQ3NlsLso7)gn$*t0$BMLu0LEp*KR5Q-_;<NVb zcb9u`_-Li4kCrFkP)-y5<3~{O?MFB~bFiRrdd@L~3{-i(uQpkhBdBT{BOF2!eFwJ1 zqDV@1ZuXg7s%3m2JfZ%b3m9IW;>$qIsMx(mNfA!@aZ0!2JyiCYMC{4eE(!FzDr6i# zRC8L+zm3D1TgdmjxdVEo1Y^X0{SyJn=_9Qo3q1Z=&-Sv1vIsq6>z7StCX86G-hL+1 zl^i)UxA^%4l`Z10D59^3T7fS$Gbe{3s)Nk1<8vS}gCP76P(k7(r=N`??&`%h?S%be zs`mPd#&r`l$?N9G|FmvjF~xB6)n-Kk|4AKfP*Htqj}N)tJKwnw8-%fM`jK`iX3q=* zLnpgK9Lwa(k5YG=Y(w%ydzH?Jg67VJ|L7>@ElykXkvU)|^SaFnq9;e^4Kle5u&L** z7vMWR@1rU-toc?=8zw~@Djlh>)y*{oV`&tq{4)0Sr)bx3qG;31*FTa0(hue6XTv7O z+l4}W-^?(pPTF0%C@z&Zzh>)HWjHxYhEXf|>H;kwKJiTy!`*6Cf8Fjp4@A5bd^sdY zt>0!mlrWaRrN-y-x0QU$lU7y~TVv**+?~XZ+PSGKG-$2adffaFJ>pNBwC<y!c_UNt zk%985SFh?qo_MG?)y%!(vaZvbWxQAmLwDF=5q{QK_e&=T1@lvT*%(<{(JJwi!n<k~ zM)H5TEPYsgCIV{^qLS?#{O}KS?B$WtTR%oRZnm9l83m*%S#c4CSL<m!4_~|~IKW6i zUX!%;LzSG~uD}rz3c~HqCxMr2y3$d?OGx0kks_MmBAS$}b*TuF$IsB%9&~6Zt|b31 zQ-+n`JzJ(#+M)1lm1*3gG~2vPa%wXkf4u6?Q_KH+9qJjPs35ZCe&$bz$cn4SX_gE6 ze{~p%adMmd4B^rpgT}=E(&_q~GEpb0F1+u4o6{Y?>0n#Nyk?I76T*&!Ut1}W@x+hW z;;4R~QoZ4H($YCX#G^_WQ%G#9nc3NZBpl_npczhTk(YxHnlB+*iKQo!tWP#|Q&kBU zWjI?xq=*?ewiH5uZ!lvJuBGpC-?W9F!q|X*7ddfjnE1n2>C2QC6Eazq*V~nc82WUS zX^WV~9QZ6*?R_bs#Q{D3c#j9ogk<YL-})=Ab>La_2wQn%;M0o{*a(~llE>pp@>Z_U zH&zU-N(}a7bg!;Wqx5+q);tko*s6E72nkjJmRX<%jGRFWt?F_27!p2yad0FmPdQ_P z1|!Pw5?;!*K<(v$vXf1keq<H`$;a(%R6ubj2KGslK9dcv;|hbn!<x#C>_Q%ZVh#S7 ziD?`E^5MT<HP(M;{##b$1EI>nxXpG^hm7GS2_Z5>i2s(oJ{#M-1}y+2Mw%=M9dbnU zk&Z*i8NI$2l`r;z9O`5Q)+XYyPZEx1X{_U!#eeud`^}sCz{f-U$T9NL$<!LZ8A}04 zVUS|t4spuQBs%p@Ukt6T$LBv6@i`tVHEm&>_Y?*jYSWAT0&I(#?7BK$7FgVbAO4dM z<TqjVi5tvO6vAr~^tg{Fu&tz4J#^@X9!mk0IiBQ%N8NLX!X4T@FX+rW;b(##o%a4Z zt@n$ll#WDx<>N8D668&6(_33}GF*>Fwfx6*y<L<^n93NnU(xse_xond-`_}7>Hf22 zv$!SIO{U1jDu4G^@5-?Qf-Xl4!$=6hZ2Yxa+pM<p@Cr!=IiF3s4gE1Vl)}4O6?T~- zSv{v%?lFj(jOZb<KF1v2maH2H=i|+3G2bhs-z`krvLn)bO{Q^L!=Utm!#R(c(2!yA zA|u!l&vP8A*M1MlE{U{a;4)AlrXs<X|D8G5bcl-4-hcedNzzdgs31gaj$<;X(U)!v z0WBzQ>{Q(+eA|`H)(UmxJLpF0ZWh$Th;6)?BbYu;ok0Wnqc?>ftD1B=Nalzf2y_Sz zh*Zmr6NWo9XnSJmxzBRQ(hfdw^u50L%8Fu+mxw-qNZ-+y^mFK{M%4q=$nT89h-P*0 z@eZ*ro+76T?zc1Tl(j4+SY-I*E%Boo>VgS{Y!w(tWD&1F^K|xLS<%{mO*y-;W8*k9 zveP1g427r`w4|E<$!M!Lhf((@cLfKWF+yG#V?7>YHQBKk9)l7U8l#N4*6tjZR$K7P z`a5{*ZU(TX7BnOBYFC#le%7j8D`T-V0k+mv*I2iYz@lA$3U%-ah?4bv>B~+1=keg! ze=k2DL?D8ofNGG$cE#?@tcjV2-~}X#7<JHxTTCk;rBsOy3@gZ68r^;<(HTTsv{U2r zd%g<7x(Q!+o`Or)Jp6%`1_=?@eHhVKj0#zY3KtC-Z25n^d5m=M2HZa2H{kEV8xTnU z>karik8eOM{(pSzzuWkKeGKux+xXvi{olR)pC9|5yZ+DK{x2W<@8SPHkNAK8*#G~J d*pHp$;YG~(L+0Z5WLgM#$-YsNDv>bq`yXxrtvLVy literal 0 HcmV?d00001 From 198b2ce20edae4a5c0a92ca406d506161468e0a9 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 29 May 2026 22:21:05 +0300 Subject: [PATCH 6/8] Build-time-codegen post: reorder + retitle per review - Title retitled "OpenAPI, ORM, SVG and Lottie" (routing dropped from the title, not the first thing above the fold). - OpenAPI section stays first, then ORM, JSON / XML, binding, SVG, Lottie. Deep links and routing moved to the END of the post, just before the codegen plumbing section. - Routing reframed as "the first place we used the preprocessor" rather than "the piece that motivates everything else". - Deep-link section now spells out the honest history. AppArg worked for small surfaces but got fragile across cold/warm lifecycle paths and especially in the case where a user lands mid-app via a link and then continues to interact (back-stack composition, falling off the edge on back). The new DeepLink + setDeepLinkHandler runs on a consistent path and parses for you. - Removed the "The Initializr, the Playground, the Skin Designer, and the new Build Cloud console are all working examples" sentence; none of those use the routing framework. - Removed the "Three rules the design enforces: no Class.forName, no service loader, no field reflection. The 'this code only breaks in production because R8 renamed a field' shape of JPA-on-Android bug is structurally absent" paragraph from the ORM section. - @Bindable example now shows the Form with the matching components (TextField with setName, ComboBox, Button), so the binder's "match by component name" contract is visible. - New SVG sizing subsection. cn1-svg-width / cn1-svg-height in millimeters is the recommended knob; same constant size at every DPI; sidesteps the design-pixel guesswork. Two-float constructor for projects that don't use CSS. - New paragraph up front in the SVG section spelling out that a transcoded SVG is a vector image but still an Image: works in every Image slot in the framework, just scales cleanly. - iOS Metal caveat fixed. On ios.metal=false the SVG / Lottie shape API renders with visible artifacts in many cases, not the placeholder you might expect. - SVG and Lottie both ask the community to file issues with the failing source file attached when the transcoder mishandles something. The transcoder grows one shape family at a time from those reports. - SVG / Lottie source path corrected from src/main/svg/ and src/main/lottie/ to src/main/css/ (the actual hellocodenameone fixture lays them out alongside theme.css there). - Lottie GIF regenerated. 24 interpolated frames at 60 ms each (was 6 frames at 200 ms); much smoother playback in-browser. - Wrap-up teases Friday's release post: pretty big features landing, the headline pieces are the most substantial things in months and worth checking back for. --- .../content/blog/build-time-codegen.md | 326 ++++++++++-------- .../lottie-pulse-spinner.gif | Bin 15739 -> 81494 bytes 2 files changed, 187 insertions(+), 139 deletions(-) diff --git a/docs/website/content/blog/build-time-codegen.md b/docs/website/content/blog/build-time-codegen.md index 6d5a6d5db7..415d16747a 100644 --- a/docs/website/content/blog/build-time-codegen.md +++ b/docs/website/content/blog/build-time-codegen.md @@ -1,78 +1,83 @@ --- -title: "Routing, ORM, OpenAPI, And Build-Time SVG / Lottie" +title: "OpenAPI, ORM, SVG and Lottie" slug: build-time-codegen url: /blog/build-time-codegen/ date: '2026-06-03' author: Shai Almog -description: A declarative router and a unified deep-link API; a JPA-shaped SQLite ORM; JAXB-shaped JSON / XML mappers; an OpenAPI 3.x client generator that turns a spec into typed Codename One code; SVGs and Lottie animations transcoded to Java Image subclasses at build time. All four pieces sit on the same build-time codegen pipeline; the details of that pipeline are at the end. -feed_html: '<img src="https://www.codenameone.com/blog/build-time-codegen.jpg" alt="Routing, ORM, OpenAPI, And Build-Time SVG / Lottie" /> A declarative router with deep links, a JPA-shaped SQLite ORM, JAXB-shaped JSON / XML mappers, an OpenAPI client generator, and build-time SVG / Lottie transcoders.' +description: An OpenAPI 3.x client generator that turns a spec into typed Codename One code, a JPA-shaped SQLite ORM, JAXB-shaped JSON / XML mappers, build-time SVG and Lottie transcoders, plus a declarative router and deep-link API. All ride on the same build-time codegen pipeline. +feed_html: '<img src="https://www.codenameone.com/blog/build-time-codegen.jpg" alt="OpenAPI, ORM, SVG and Lottie" /> An OpenAPI client generator, a JPA-shaped SQLite ORM, JAXB-shaped JSON / XML mappers, build-time SVG / Lottie transcoders, and a declarative router with deep links. All on the same build-time codegen pipeline.' --- -![Routing, ORM, OpenAPI, And Build-Time SVG / Lottie](/blog/build-time-codegen.jpg) +![OpenAPI, ORM, SVG and Lottie](/blog/build-time-codegen.jpg) -This is the third follow-up to [Friday's release post](/blog/metal-default-new-build-cloud-and-a-new-format/). Saturday's was about how you iterate; Monday's was about new platform APIs in the core; today's is about four pieces that change how you write the structural parts of an app. +This is the third follow-up to [Friday's release post](/blog/metal-default-new-build-cloud-and-a-new-format/). Saturday's was about how you iterate; Monday's was about new platform APIs in the core; today's is about a run of pieces that change how you write the structural parts of an app. -The four are routing, persistence, network bindings, and graphics. All four use **build-time codegen** under the hood: a Maven-plugin pass that reads annotations or declarative source files at build time and emits typed Java that compiles into your binary. No reflection, no service loader, no `Class.forName`. The "How it works" section at the end of this post is the place to read about the codegen plumbing once you have seen what it powers. The earlier sections focus on the features themselves. +The pieces are an OpenAPI client generator, a SQLite ORM, JSON and XML mappers, a component binder with validation, build-time SVG and Lottie transcoders, and a declarative router with deep links. All ride on a single **build-time codegen pipeline**: a Maven-plugin pass that reads annotations or declarative source files at build time and emits typed Java that compiles into your binary. No reflection, no service loader, no `Class.forName`. The "How it works" section at the end of this post covers the codegen plumbing once you have seen what it powers. -## Deep links and routing +## OpenAPI client generation -The piece that motivates everything else in this section is deep links. Modern mobile apps need to handle URLs from a wide variety of sources: a notification that wants to land on a specific screen, a marketing email with a link into the app, a "share" sheet that hands the user a URL to a particular item, an associated-domains rule that opens the app when a friend taps `https://yourapp.com/users/42` in Safari. iOS treats these through Universal Links; Android treats them through App Links; the framework collapses both into a single in-app concept. +The headline of this release for any team that talks to a backend. -`Display.setDeepLinkHandler(LinkHandler)` registers a handler that receives a normalised `DeepLink` (scheme, host, path, segments, query map, fragment). The same handler fires for cold launches (the app was not running; the OS started it because of a link) and warm launches (the app was already running and got the URL via app-resume). iOS and Android need no port changes for this to work; the existing platform plumbing already writes URL-shaped values into `Display.setProperty("AppArg", url)` and the new handler intercepts those. +A new `cn1:generate-openapi-client` Mojo reads an OpenAPI 3.x JSON spec (a URL or a local file) and writes typed Codename One client code that compiles into your app: -```java -Display.getInstance().setDeepLinkHandler(link -> { - if ("/users".equals(link.path()) && link.segments().size() == 2) { - showUserDetailForm(link.segments().get(1)); - return true; - } - return false; -}); +- One `@Mapped` POJO per `components.schemas` entry. +- One `<Tag>Api.java` class per OpenAPI tag, with one fluent method per operation. +- Every method routes through `Rest.<verb>` + `Mappers.toJson` + `fetchAsMapped` / `fetchAsMappedList`, so the generated surface integrates with the rest of the framework instead of dragging in a separate HTTP stack. + +Wire it into the project's `pom.xml`: + +```xml +<plugin> + <groupId>com.codenameone</groupId> + <artifactId>codenameone-maven-plugin</artifactId> + <executions> + <execution> + <id>petstore-client</id> + <goals><goal>generate-openapi-client</goal></goals> + <configuration> + <specUrl>https://petstore3.swagger.io/api/v3/openapi.json</specUrl> + <basePackage>com.example.petstore</basePackage> + </configuration> + </execution> + </executions> +</plugin> ``` -That works, but as the surface grows the if/else chain in the handler becomes a real maintenance burden. Five URL patterns, ten patterns, twenty patterns; the handler grows arms and legs, the routing decisions creep into the form constructors that need to read query parameters, and the "what screens does this app have, and at what paths" question is answered by reading through hundreds of lines of switch statements scattered across files. +`mvn generate-sources` picks the spec up, downloads it, and writes one file per schema and one per tag under `target/generated-sources/`. The Petstore reference spec exercised end-to-end produces six model classes (`Pet`, `Order`, `Customer`, `Tag`, `Category`, `User`) and three Api classes (`PetApi`, `StoreApi`, `UserApi`), and the nine generated `.class` files compile cleanly against `codenameone-core`. Documented at [the OpenAPI codegen Maven goal](https://www.codenameone.com/developer-guide/#_appendix_goal_generate_openapi_client). -The declarative router in `com.codename1.router` is what we built to keep that question tractable. Each form declares its own path with a `@Route` annotation: +In application code you call the generated `Api` class the same way you would call any other Java method: ```java -@Route("/") -public class HomeForm extends Form { /* ... */ } +PetApi pets = new PetApi(); -@Route("/users/:id") -public class UserDetailForm extends Form { - public UserDetailForm(RouteMatch match) { - String userId = match.param("id"); - // build UI for user `userId` +// Returns AsyncResource<Pet>; resolves with the deserialised object. +pets.getPetById(42).onResult((pet, err) -> { + if (err == null) Log.p("Got " + pet.getName()); +}); + +// Returns AsyncResource<List<Pet>>. +pets.findPetsByStatus("available").onResult((list, err) -> { + if (err == null) { + for (Pet p : list) Log.p(p.getName()); } -} +}); -@Route("/about") -public class AboutForm extends Form { /* ... */ } +// POST with a request body. addPet takes a Pet, returns a Pet. +Pet candidate = new Pet(); +candidate.setName("Mittens"); +candidate.setStatus("available"); +pets.addPet(candidate).onResult((created, err) -> { /* ... */ }); ``` -`Router.navigate("/users/42")` resolves the path, instantiates `UserDetailForm`, and shows it. The deep-link handler then collapses to a single line: `Display.getInstance().setDeepLinkHandler(link -> Router.navigate(link.path()))`. Each form owns its own routing rule; adding or moving a screen is a one-class change. - -**For Spring developers,** the shape is familiar by design. `@Route` plays the same role as Spring MVC's `@RequestMapping`: a class-level declaration that announces "this controller handles URLs of this shape". The `:id` parameter syntax mirrors Spring's `{id}` path-variable syntax; `RouteMatch.param("id")` is the same kind of accessor as Spring's `@PathVariable`. The mental model carries over from server-side Java with almost no friction. The same recognition is available to anyone with React Router, Vue Router, or Angular Router experience; the `:param` convention is the cross-framework default. - -The build-time processor validates that each annotated class extends `Form`, that the path starts with `/`, that the constructor is accessible, and that there are no duplicate patterns. Any rule violation fails the build with a class name and a reason, not at runtime with a stack trace. - -The rest of the router surface covers the kind of thing that has become table stakes in modern client routing: - -- **Route guards** run before navigation completes and can cancel or redirect. -- **Per-tab navigation stacks** via `TabsForm`, where each tab keeps its own back stack. -- **Location listeners** so anything in the app can subscribe to "the route changed". -- **`Form.setPopGuard(PopGuard)`** intercepts hardware back, toolbar back, or `Router.pop()` with a chance to ask "are you sure?". -- **`Sheet.showForResult()`** returns an `AsyncResource<T>` that auto-cancels with `null` if the user dismisses the sheet. - -The API is opt-in. Apps that prefer the existing `Form.show()` / `Form.showBack()` flow keep using that; nothing changes. +There is no hand-rolled `ConnectionRequest` setup, no manual JSON parsing, no string-typed request bodies. The generated client takes a typed `Pet`, serialises it with `Mappers.toJson(...)`, fires the right HTTP verb, deserialises the response with `Mappers.fromJson(...)`, and surfaces the result through the framework's `AsyncResource` so your callback fires on the EDT. -For the link-publishing side, an `AasaBuilder` emits the iOS `apple-app-site-association` JSON and an `AssetLinksBuilder` emits the Android `assetlinks.json`. The full setup walk-through (entitlements, the Android `intent-filter`, the `.well-known/` upload on your origin server) is at [Routing and Deep Links](https://www.codenameone.com/developer-guide/#_routing_and_deep_links) in the developer guide. +For teams who already publish an OpenAPI spec as part of their backend (most modern backend frameworks do this automatically; FastAPI, Spring's `springdoc-openapi`, NestJS, ASP.NET Core, Go's `gnostic`), the practical effect is that the mobile client's bindings stay in sync with the backend without anyone hand-writing a single network call. Update the spec, re-run `mvn generate-sources`, and the new and changed endpoints land in your app as typed Java the IDE picks up immediately. -The JavaScript port bridges the router into `window.history` so navigating the in-app router pushes a real entry into the browser's session history. Back and forward in the browser drive the router; reloading the page lands at the deep-link URL; sharing the URL out of the address bar takes a colleague to the same in-app location. The Initializr, the Playground, the Skin Designer, and the new Build Cloud console are all working examples. +It is the kind of change that is most useful when you do not know you have it: pull a fresh spec, rebuild, and your IDE highlights every place in the codebase that called a renamed endpoint or passed the wrong type to a parameter. ## SQLite ORM -The second piece is a SQLite ORM, also driven by annotations. `@Entity` marks the class; `@Id` and `@Column` shape the schema; `@DbTransient` opts a field out: +`@Entity` marks the class; `@Id` and `@Column` shape the schema; `@DbTransient` opts a field out: ```java @Entity @@ -97,8 +102,6 @@ The generated DAO does the typed work underneath. No reflection in `insert`; the **For JPA / Hibernate developers,** the API is intentionally familiar. `@Entity`, `@Id`, `@Column`, and `@Transient` (here renamed `@DbTransient` to avoid colliding with `java.beans.Transient`) carry the same meaning they do under `javax.persistence` / `jakarta.persistence`. The `EntityManager` name is the same. `Dao#findById`, `Dao#findAll`, `Dao#find(where, params)`, `Dao#insert`, `Dao#update`, `Dao#delete` line up with the basic JPA repository contract. The query language is plain SQL (there is no JPQL or Criteria DSL) but the annotation surface, the lifecycle, and the runtime methods will feel like a long-lost friend to anyone with server-side Java persistence experience. -Three rules the design enforces: no `Class.forName`, no service loader, no field reflection. The "this code only breaks in production because R8 renamed a field" shape of JPA-on-Android bug is structurally absent. - ## JSON / XML mapping `@Mapped` marks a class as a transferable POJO. `@JsonProperty` and `@XmlElement` (plus `@XmlRoot`, `@XmlAttribute`, `@JsonIgnore`, `@XmlTransient`) shape the wire format. The runtime entry points are `Mappers.toJson(...)`, `Mappers.fromJson(...)`, `Mappers.toXml(...)`, `Mappers.fromXml(...)`: @@ -133,67 +136,6 @@ Rest.get("https://api.example.com/users") **For JAXB developers,** the XML surface (`@XmlRoot`, `@XmlElement`, `@XmlAttribute`, `@XmlTransient`) is a direct port of the long-established `javax.xml.bind.annotation` surface. The same model class can be both `@XmlRoot`-decorated and `@JsonProperty`-decorated, which gives you a single source of truth for both wire formats. The JSON surface adopts the Jackson convention (`@JsonProperty`, `@JsonIgnore`) that nearly every modern JVM JSON binding (Jackson, Moshi, kotlinx-serialization) inherited. -## OpenAPI client generation - -This is the headline of the codegen post and arguably the most useful single feature in this release for any team that talks to a backend. - -A new `cn1:generate-openapi-client` Mojo reads an OpenAPI 3.x JSON spec (a URL or a local file) and writes typed Codename One client code that compiles into your app: - -- One `@Mapped` POJO per `components.schemas` entry. -- One `<Tag>Api.java` class per OpenAPI tag, with one fluent method per operation. -- Every method routes through `Rest.<verb>` + `Mappers.toJson` + `fetchAsMapped` / `fetchAsMappedList`, so the generated surface integrates with the rest of the framework instead of dragging in a separate HTTP stack. - -Wire it into the project's `pom.xml`: - -```xml -<plugin> - <groupId>com.codenameone</groupId> - <artifactId>codenameone-maven-plugin</artifactId> - <executions> - <execution> - <id>petstore-client</id> - <goals><goal>generate-openapi-client</goal></goals> - <configuration> - <specUrl>https://petstore3.swagger.io/api/v3/openapi.json</specUrl> - <basePackage>com.example.petstore</basePackage> - </configuration> - </execution> - </executions> -</plugin> -``` - -`mvn generate-sources` picks the spec up, downloads it, and writes one file per schema and one per tag under `target/generated-sources/`. The Petstore reference spec exercised end-to-end produces six model classes (`Pet`, `Order`, `Customer`, `Tag`, `Category`, `User`) and three Api classes (`PetApi`, `StoreApi`, `UserApi`), and the nine generated `.class` files compile cleanly against `codenameone-core`. Documented at [the OpenAPI codegen Maven goal](https://www.codenameone.com/developer-guide/#_appendix_goal_generate_openapi_client). - -In application code you call the generated `Api` class the same way you would call any other Java method: - -```java -PetApi pets = new PetApi(); - -// Returns AsyncResource<Pet>; resolves with the deserialised object. -pets.getPetById(42).onResult((pet, err) -> { - if (err == null) Log.p("Got " + pet.getName()); -}); - -// Returns AsyncResource<List<Pet>>. -pets.findPetsByStatus("available").onResult((list, err) -> { - if (err == null) { - for (Pet p : list) Log.p(p.getName()); - } -}); - -// POST with a request body. addPet takes a Pet, returns a Pet. -Pet candidate = new Pet(); -candidate.setName("Mittens"); -candidate.setStatus("available"); -pets.addPet(candidate).onResult((created, err) -> { /* ... */ }); -``` - -There is no hand-rolled `ConnectionRequest` setup, no manual JSON parsing, no string-typed request bodies. The generated client takes a typed `Pet`, serialises it with `Mappers.toJson(...)`, fires the right HTTP verb, deserialises the response with `Mappers.fromJson(...)`, and surfaces the result through the framework's `AsyncResource` so your callback fires on the EDT. - -For teams who already publish an OpenAPI spec as part of their backend (most modern backend frameworks do this automatically; FastAPI, Spring's `springdoc-openapi`, NestJS, ASP.NET Core, Go's `gnostic`), the practical effect is that the mobile client's bindings stay in sync with the backend without anyone hand-writing a single network call. Update the spec, re-run `mvn generate-sources`, and the new and changed endpoints land in your app as typed Java the IDE picks up immediately. - -It is the kind of change that is most useful when you do not know you have it: pull a fresh spec, rebuild, and your IDE highlights every place in the codebase that called a renamed endpoint or passed the wrong type to a parameter. - ## Component binding with validation The fourth annotation processor on the same pipeline is the component binder. `@Bindable` marks a model class; `@Bind(name = "userField")` ties a field to a component on a form by the component's `name`. Field-level validation annotations compose with `@Bind` on the same field: @@ -215,11 +157,24 @@ public class SignupModel { } ``` -The runtime side is two lines: +The matching form sets a `name` on each component so the binder can find them: ```java -Binding b = Binders.bind(model, form); -b.getValidator().addSubmitButtons(submitBtn); +TextField user = new TextField(); user.setName("userField"); +TextField email = new TextField(); email.setName("emailField"); +TextField age = new TextField(); age.setName("ageField"); +ComboBox<String> role = new ComboBox<>("admin", "editor", "viewer"); +role.setName("roleField"); + +Button submit = new Button("Sign up"); + +Form form = new Form("Sign Up", BoxLayout.y()); +form.add(user).add(email).add(age).add(role).add(submit); +form.show(); + +SignupModel model = new SignupModel(); +Binding binding = Binders.bind(model, form); +binding.getValidator().addSubmitButtons(submit); ``` `Binding` is the handle: `refresh()` re-reads the model into the components, `commit()` writes the components back, `disconnect()` tears the listeners down. Multiple validation annotations on a single field compose via `Validator.addConstraint(Component, Constraint...)` and `GroupConstraint` (first failure wins). `@Validate(MyClass.class)` is the escape hatch for hand-written `Constraint` implementations. The validation set: `@Required`, `@Length`, `@Regex`, `@Email`, `@Url`, `@Numeric`, `@ExistIn`, `@Validate`. @@ -228,12 +183,11 @@ The new `BindAttr` enum lets `@Bind` target a specific attribute of the componen ## SVG at build time -SVG and Lottie use the same codegen pipeline, but emit different output: instead of reading annotations from your Java, they read declarative graphics files from `src/main/svg/` and `src/main/lottie/` and emit Codename One `Image` subclasses that render through the `Graphics` shape API on every platform. - -Drop an SVG into `src/main/svg/`: +Drop an SVG into `src/main/css/`, alongside `theme.css`: ``` -src/main/svg/ +src/main/css/ + theme.css star.svg gradient_circle.svg path_arrow.svg @@ -243,37 +197,61 @@ src/main/svg/ clipped_badge.svg ``` -After the next build: - -```java -Image star = Resources.getGlobalResources().getImage("star.svg"); -Image star2 = Resources.getGlobalResources().getImage("star"); // either form -form.add(star); -``` +After the next build, every SVG is a regular Codename One `Image`. **An SVG handled by the transcoder is a vector image, but it is still an `Image`.** Everywhere a raster `Image` works (`Label.setIcon`, `Button.setIcon`, `BorderLayout.NORTH`, the toolbar, a `MultiButton`'s leading icon, a CSS `background: url(...)` rule), the SVG works too. The difference is that it stays crisp at any size: the same source file is sharp at a 16-point list-row icon, a 64-point hero header, and a 256-point launch screen, on every DPI bucket. A grid of the static SVGs from the hellocodenameone fixture, rendered through the new pipeline: ![Static SVGs rendered by the build-time transcoder on iOS Metal: filled star, gradient-filled circle, path arrow, rounded button, two stroked wave paths, gradient-filled PRO badge, clipped badge](/blog/build-time-codegen/svg-static.png) +### Sizing in millimeters is the important knob + +The SVG transcoder's most useful feature is also the one most easily missed: **size every SVG in millimeters from CSS**. SVGs in the wild routinely declare odd `width` / `height` attributes (a 1024×1024 export of a 24×24 icon, no dimensions at all, design-pixel values from one specific framework). Pinning the rendered size in millimeters sidesteps all of that. + +```css +HomeIcon { + background: url(home.svg); + cn1-svg-width: 6mm; + cn1-svg-height: 6mm; + bg-type: image_scaled_fit; +} + +LogoBanner { + background: url(logo.svg); + cn1-svg-width: 32mm; + cn1-svg-height: 12mm; +} +``` + +A 6 mm icon is 6 mm tall on a 1× desktop, 6 mm on a high-DPI handset, and 6 mm on a 4K tablet. The transcoder routes both values through `Display.convertToPixels()` at install time, the same way `font-size: 3mm` already behaves elsewhere in Codename One CSS. No design-pixel guesswork, no DPI bucket to choose, no scaling surprise when the artist re-exports the source SVG at a different resolution. + +If a project does not use CSS for theming, the two-`float` constructor on the generated class takes millimeters directly: `new com.codename1.generated.svg.Home(6f, 6f)`. + +### Coverage and what we still want feedback on + The transcoder is a `maven/svg-transcoder/` module that parses SVG with `javax.xml` StAX. No Batik, no Flamingo, no external dependencies. Coverage targets what real-world icon SVGs use: `rect` (rounded corners included), `circle`, `ellipse`, `line`, `polyline`, `polygon`, the full `path` grammar (`M` / `L` / `H` / `V` / `C` / `S` / `Q` / `T` / `A` / `Z` plus relative-coordinate and smooth-curve reflection), groups with affine transforms (`translate`, `scale`, `rotate`, `skew`, `matrix`), linear gradients via `LinearGradientPaint`, fill, stroke, stroke-width, linecap, linejoin, opacity. -SMIL animations are supported in the same pipeline: `<animate>`, `<animateTransform>` (`translate`, `scale`, `rotate`), and `<set>`. Time values interpolate against wall-clock time on every paint, with `from` / `to` / `values` / `begin` / `dur` / `repeatCount` / `fill="freeze"` honoured. So an SVG with a rotating sub-element becomes a real animated `Image` you can drop into a `Form` and watch spin without writing any animation code yourself. +SMIL animations are supported in the same pipeline: `<animate>`, `<animateTransform>` (`translate`, `scale`, `rotate`), and `<set>`. Time values interpolate against wall-clock time on every paint, with `from` / `to` / `values` / `begin` / `dur` / `repeatCount` / `fill="freeze"` honoured. -**Important caveat:** this is **Metal-only on iOS**. The GL ES 2 path that was the iOS default until [last Friday's flip](/blog/metal-default-new-build-cloud-and-a-new-format/#metal-is-the-default-on-ios) does not have the shape API coverage the SVG / Lottie pipeline emits. Apps that opted in to Metal pick the transcoders up automatically; apps still on `ios.metal=false` will see placeholders. Now that Metal is the default this stops being a thing most apps notice on their next build. +Explicit non-coverage in v1: SVG `text`, masks / clip-paths, filters, radial-gradient paint (falls back to first stop colour), CSS keyframe animations. -Coverage and the troubleshooting section are at [SVG Transcoder](https://www.codenameone.com/developer-guide/#_svg_transcoder) in the developer guide. Explicit non-coverage in v1: SVG `text`, masks / clip-paths, filters, radial-gradient paint (falls back to first stop colour), CSS keyframe animations. +**If you hit an SVG that does not transcode the way you expect**, please open an issue at [github.com/codenameone/CodenameOne/issues](https://github.com/codenameone/CodenameOne/issues) and **attach the source file**. The fastest way to extend the coverage is for us to run the failing case through the test fixtures and watch the output. Every SVG we ship test goldens for started as somebody else's "this doesn't render right" report. + +**Caveat on iOS:** the transcoded SVGs use the framework's shape API (`fillShape`, `drawShape`, `LinearGradientPaint`). The full surface is implemented on the Metal renderer. The deprecated GL ES 2 pipeline does not have parity on every operation, so an SVG drawn under `ios.metal=false` will often render with visible artifacts (missing gradients, clipped fills, distorted paths) rather than the placeholder you might expect. Now that Metal is the default for new iOS builds [as of last Friday](/blog/metal-default-new-build-cloud-and-a-new-format/#metal-is-the-default-on-ios), this is a non-issue on most apps; if you have explicitly pinned `ios.metal=false`, expect some visual regressions on SVG content and let us know which. + +The coverage matrix and troubleshooting are at [SVG Transcoder](https://www.codenameone.com/developer-guide/#_svg_transcoder) in the developer guide. ## Lottie at build time -The same pipeline carries Lottie. Drop a Bodymovin export into `src/main/lottie/`: +The same pipeline carries Lottie. Drop a Bodymovin export into the same `src/main/css/`: ``` -src/main/lottie/ +src/main/css/ + theme.css pulse.json spinner.json ``` -After the next build, both are real `Image` instances on every platform that exposes the shape API: +After the next build, both are real `Image` instances on every platform that exposes the shape API. The same vector-everywhere story as SVG: a Lottie animation renders crisply at any size and slots into any `Image` slot in the framework. ```java Image pulse = Resources.getGlobalResources().getImage("pulse"); @@ -281,7 +259,7 @@ Image spinner = Resources.getGlobalResources().getImage("spinner"); form.add(pulse).add(spinner); ``` -The animation runs against wall-clock time on every paint, with no `Timer` and no allocation in the hot path. A capture of the hellocodenameone Lottie fixture (one pulsing circle and one rotating bar) at six points in the loop: +Animation runs against wall-clock time on every paint, with no `Timer` and no allocation in the hot path. A capture of the hellocodenameone Lottie fixture in motion: ![Animated Lottie playback: a red bar that pulses and rotates next to a blue ellipse that scales up and down](/blog/build-time-codegen/lottie-pulse-spinner.gif) @@ -289,6 +267,82 @@ The Lottie transcoder lives in `maven/lottie-transcoder/`. It parses Bodymovin J Coverage in v1: shape layers (`rc` / `el` / `sh`) with solid fills and strokes; layer transforms (anchor, position, scale, rotation, opacity); animated rotation, position, and scale collapsed to a two-keyframe loop; solid-color layers as filled rects. Most icon-grade Bodymovin exports lower cleanly. Complex character animations from After Effects with image references, masks, and effects do not, and the transcoder logs which layers it dropped so the source of any blank output is obvious. +**Same ask as for SVG**: if a Lottie / Bodymovin file does not transcode the way you expect, please open an issue at [github.com/codenameone/CodenameOne/issues](https://github.com/codenameone/CodenameOne/issues) and **attach the source `.json`**. The transcoder grows one shape family at a time from the cases the community reports. + +The same iOS caveat applies: the renderer leans on the shape API, so the deprecated GL ES 2 pipeline shows artifacts on the more elaborate Lottie animations. Use the Metal default (now on by default for new iOS builds). + +## Deep links and routing + +Two pieces of plumbing for apps that handle URLs from outside themselves (notification taps, marketing links, share targets, Universal Links from Safari and the equivalent App Links from Chrome on Android). + +### Deep links + +Codename One has had deep-link support for a long time through `Display.setProperty("AppArg", url)`. The platform plumbing already writes the incoming URL into that property on cold launch, and an app-resume sets it again on warm launch; reading it back from `start()` works fine for a small number of patterns. Where the `AppArg`-only approach gets fragile is consistency. The cold and warm paths execute different lifecycle code, the value is a flat string with no parsing, and the trickiest case is the one where a user lands in the middle of the app via a link and then continues to interact: their next navigation needs to compose with the entry point, the back-stack needs to make sense as if they had arrived through the usual flow, and "fall off the edge of the app" on back is a common bug. With a hand-rolled `AppArg` reader it is easy to miss one of these and ship a half-working flow. + +This release introduces a typed `DeepLink` and a single handler that fires for both cold and warm launches: + +```java +Display.getInstance().setDeepLinkHandler(link -> { + // link is a normalised DeepLink: scheme, host, path, + // segments, query map, fragment. Same shape cold or warm. + if ("/users".equals(link.path()) && link.segments().size() == 2) { + showUserDetailForm(link.segments().get(1)); + return true; + } + return false; +}); +``` + +`AppArg` still works for projects that depend on it, but the new handler is what we recommend going forward. The handler runs on a consistent lifecycle path on both cold and warm starts, and the parsed `DeepLink` value carries the scheme, host, path segments, query map, and fragment so app code does not need to roll its own URL parser. + +### Routing + +For projects that handle more than a handful of URL patterns, the second piece is the declarative router in `com.codename1.router`. We built it on the same build-time codegen pipeline as the ORM and the mappers (the router was actually the first concrete consumer of the new preprocessor) so the two surfaces compose: a deep-link handler that delegates to the router becomes a one-liner. + +Each form declares its own path with a `@Route` annotation: + +```java +@Route("/") +public class HomeForm extends Form { /* ... */ } + +@Route("/users/:id") +public class UserDetailForm extends Form { + public UserDetailForm(RouteMatch match) { + String userId = match.param("id"); + // build UI for user `userId` + } +} + +@Route("/about") +public class AboutForm extends Form { /* ... */ } +``` + +`Router.navigate("/users/42")` resolves the path, instantiates `UserDetailForm`, and shows it. The deep-link handler now collapses to: + +```java +Display.getInstance().setDeepLinkHandler(link -> Router.navigate(link.toString())); +``` + +Each form owns its own routing rule. Adding or moving a screen is a one-class change. The "what screens does this app have, and at what paths?" question is answered by an IDE search for `@Route`, not by reading every form constructor in the project. + +**For Spring developers,** the shape is familiar by design. `@Route` plays the same role as Spring MVC's `@RequestMapping`: a class-level declaration that announces "this controller handles URLs of this shape". The `:id` parameter syntax mirrors Spring's `{id}` path-variable syntax; `RouteMatch.param("id")` is the same kind of accessor as Spring's `@PathVariable`. The mental model carries over from server-side Java with almost no friction. The same recognition is available to anyone with React Router, Vue Router, or Angular Router experience; the `:param` convention is the cross-framework default. + +The build-time processor validates that each annotated class extends `Form`, that the path starts with `/`, that the constructor is accessible, and that there are no duplicate patterns. Any rule violation fails the build with a class name and a reason, not at runtime with a stack trace. + +The rest of the router surface covers the kind of thing that has become table stakes in modern client routing: + +- **Route guards** run before navigation completes and can cancel or redirect. +- **Per-tab navigation stacks** via `TabsForm`, where each tab keeps its own back stack. +- **Location listeners** so anything in the app can subscribe to "the route changed". +- **`Form.setPopGuard(PopGuard)`** intercepts hardware back, toolbar back, or `Router.pop()` with a chance to ask "are you sure?". +- **`Sheet.showForResult()`** returns an `AsyncResource<T>` that auto-cancels with `null` if the user dismisses the sheet. + +The API is opt-in. Apps that prefer the existing `Form.show()` / `Form.showBack()` flow keep using that; nothing changes. + +For the link-publishing side, an `AasaBuilder` emits the iOS `apple-app-site-association` JSON and an `AssetLinksBuilder` emits the Android `assetlinks.json`. The full setup walk-through (entitlements, the Android `intent-filter`, the `.well-known/` upload on your origin server) is at [Routing and Deep Links](https://www.codenameone.com/developer-guide/#_routing_and_deep_links) in the developer guide. + +The JavaScript port bridges the router into `window.history` so navigating the in-app router pushes a real entry into the browser's session history. Back and forward in the browser drive the router; reloading the page lands at the deep-link URL; sharing the URL out of the address bar takes a colleague to the same in-app location. + ## How it works: the build-time codegen pipeline Everything above sits on a single Maven-plugin pass. @@ -301,17 +355,11 @@ A small stub source is emitted under `target/generated-sources/cn1-annotations/` cn1-core ships a no-op stub of each generated index (`RoutesIndex`, `MappersIndex`, `BindersIndex`, `DaosIndex`) so application code compiles even when the project has no annotated classes. The build-time processor shadows each stub with the real implementation before packaging. -Three non-negotiable rules across every processor: - -- **No `Class.forName`** anywhere in generated code. -- **No service loader.** Everything is wired through the typed registry the codegen emits. -- **No field reflection.** Every read and write in the generated code is a direct symbol reference that ParparVM rename and R8 obfuscation rewrite together with the class they target. - -The SVG and Lottie transcoders sit on a parallel pipeline (declarative graphics files in place of annotations), but follow the same rules and emit code that obeys the same constraints. The practical effect is that the kind of code that historically required reflection at runtime (with all the obfuscation hazards and surprise allocations that come with that) now happens once at build time and produces direct, dead-code-eliminable, rename-safe symbol references. That is the shape Codename One projects are going to look more and more like over the next year. +The SVG and Lottie transcoders sit on a parallel pipeline (declarative graphics files in place of annotations), but they emit the same shape of code and obey the same constraints. The practical effect is that the kind of code that historically required reflection at runtime (with all the obfuscation hazards and surprise allocations that come with that) now happens once at build time and produces direct, dead-code-eliminable, rename-safe symbol references. ## Wrapping up -That closes the post series for this release. The next weekly index lands on Friday in the same short format. +That closes this release's post series. We already have some pretty big features lined up for **this Friday's** release post; the headline pieces are the most substantial things to land in months and worth checking back for. Back to the [weekly index](/blog/metal-default-new-build-cloud-and-a-new-format/). diff --git a/docs/website/static/blog/build-time-codegen/lottie-pulse-spinner.gif b/docs/website/static/blog/build-time-codegen/lottie-pulse-spinner.gif index 5f2d85a26e0626f21cd08544fde20b78f25fd448..78890247a756d0bafe4303d830e1c9ef8ac6fce0 100644 GIT binary patch literal 81494 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�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 H6@`BR)lq*^ literal 15739 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 From 6afaecd00d861be0bae50dd2845fbc5cf30802d6 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 29 May 2026 22:44:42 +0300 Subject: [PATCH 7/8] Build-time-codegen post: drop "knob", correct SVG coverage - Section heading "Sizing in millimeters is the important knob" shortened to "Sizing in millimeters". - The "Explicit non-coverage in v1" sentence was wrong: text and clip-path are supported in this release and visible in the static-SVG fixture screenshot we ship in the post. Rewritten to call out that text and clipPath landed via PR #5056, show what is supported (<text> / <tspan> with single-style fills and transforms; <clipPath> via clip-path="url(#id)" against rect / circle / path clip shapes), and accurately list what is still not covered (filter primitives, mask with alpha, radialGradient, CSS-in-SVG with selector style rules). --- docs/website/content/blog/build-time-codegen.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/website/content/blog/build-time-codegen.md b/docs/website/content/blog/build-time-codegen.md index 415d16747a..db0708eaa9 100644 --- a/docs/website/content/blog/build-time-codegen.md +++ b/docs/website/content/blog/build-time-codegen.md @@ -203,7 +203,7 @@ A grid of the static SVGs from the hellocodenameone fixture, rendered through th ![Static SVGs rendered by the build-time transcoder on iOS Metal: filled star, gradient-filled circle, path arrow, rounded button, two stroked wave paths, gradient-filled PRO badge, clipped badge](/blog/build-time-codegen/svg-static.png) -### Sizing in millimeters is the important knob +### Sizing in millimeters The SVG transcoder's most useful feature is also the one most easily missed: **size every SVG in millimeters from CSS**. SVGs in the wild routinely declare odd `width` / `height` attributes (a 1024×1024 export of a 24×24 icon, no dimensions at all, design-pixel values from one specific framework). Pinning the rendered size in millimeters sidesteps all of that. @@ -232,7 +232,9 @@ The transcoder is a `maven/svg-transcoder/` module that parses SVG with `javax.x SMIL animations are supported in the same pipeline: `<animate>`, `<animateTransform>` (`translate`, `scale`, `rotate`), and `<set>`. Time values interpolate against wall-clock time on every paint, with `from` / `to` / `values` / `begin` / `dur` / `repeatCount` / `fill="freeze"` honoured. -Explicit non-coverage in v1: SVG `text`, masks / clip-paths, filters, radial-gradient paint (falls back to first stop colour), CSS keyframe animations. +Text and clip-path landed in the [follow-up PR for the static SVG fixtures](https://github.com/codenameone/CodenameOne/pull/5056), and both are visible in the screenshot above (the "Codename One / build-time SVG" wordmark in the rounded button, the "PRO" badge text, and the clip-path-shaped rounded-corner badge underneath). `<text>` and `<tspan>` work with single-style fills and transforms; `<clipPath>` referenced via `clip-path="url(#id)"` works against `rect`, `circle`, and `path` clip shapes (nested clip refs are ignored). + +What is still not supported: SVG `filter` primitives, `<mask>` (treated as a clip, so alpha masking falls back to opaque), `<radialGradient>` (falls back to the first-stop colour), and CSS-in-SVG (style rules inside the SVG document; the transcoder reads presentation attributes and the inline `style="..."` attribute, but a `<style>` element with selectors is not parsed). **If you hit an SVG that does not transcode the way you expect**, please open an issue at [github.com/codenameone/CodenameOne/issues](https://github.com/codenameone/CodenameOne/issues) and **attach the source file**. The fastest way to extend the coverage is for us to run the failing case through the test fixtures and watch the output. Every SVG we ship test goldens for started as somebody else's "this doesn't render right" report. From 24ecfc4cf19e56a0847845ae38a231089d704af1 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sat, 30 May 2026 08:58:42 +0300 Subject: [PATCH 8/8] Build-time-codegen post: shift to 2026-06-01 Tighter daily cadence; the codegen post moves from Wednesday 2026-06-03 to Monday 2026-06-01. - Front-matter date: 2026-06-03 -> 2026-06-01. - Intro recap line "Saturday's was about how you iterate; Monday's was about new platform APIs" -> "Saturday's was about how you iterate; yesterday's was about new platform APIs". Today is now Monday. - "this Friday's release post" wrap-up tease unchanged; that refers to the next weekly release index post and Friday is unchanged. --- docs/website/content/blog/build-time-codegen.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/website/content/blog/build-time-codegen.md b/docs/website/content/blog/build-time-codegen.md index db0708eaa9..7ef2a1abbd 100644 --- a/docs/website/content/blog/build-time-codegen.md +++ b/docs/website/content/blog/build-time-codegen.md @@ -2,7 +2,7 @@ title: "OpenAPI, ORM, SVG and Lottie" slug: build-time-codegen url: /blog/build-time-codegen/ -date: '2026-06-03' +date: '2026-06-01' author: Shai Almog description: An OpenAPI 3.x client generator that turns a spec into typed Codename One code, a JPA-shaped SQLite ORM, JAXB-shaped JSON / XML mappers, build-time SVG and Lottie transcoders, plus a declarative router and deep-link API. All ride on the same build-time codegen pipeline. feed_html: '<img src="https://www.codenameone.com/blog/build-time-codegen.jpg" alt="OpenAPI, ORM, SVG and Lottie" /> An OpenAPI client generator, a JPA-shaped SQLite ORM, JAXB-shaped JSON / XML mappers, build-time SVG / Lottie transcoders, and a declarative router with deep links. All on the same build-time codegen pipeline.' @@ -10,7 +10,7 @@ feed_html: '<img src="https://www.codenameone.com/blog/build-time-codegen.jpg" a ![OpenAPI, ORM, SVG and Lottie](/blog/build-time-codegen.jpg) -This is the third follow-up to [Friday's release post](/blog/metal-default-new-build-cloud-and-a-new-format/). Saturday's was about how you iterate; Monday's was about new platform APIs in the core; today's is about a run of pieces that change how you write the structural parts of an app. +This is the third follow-up to [Friday's release post](/blog/metal-default-new-build-cloud-and-a-new-format/). Saturday's was about how you iterate; yesterday's was about new platform APIs in the core; today's is about a run of pieces that change how you write the structural parts of an app. The pieces are an OpenAPI client generator, a SQLite ORM, JSON and XML mappers, a component binder with validation, build-time SVG and Lottie transcoders, and a declarative router with deep links. All ride on a single **build-time codegen pipeline**: a Maven-plugin pass that reads annotations or declarative source files at build time and emits typed Java that compiles into your binary. No reflection, no service loader, no `Class.forName`. The "How it works" section at the end of this post covers the codegen plumbing once you have seen what it powers.