Просмотр исходного кода

feat!: replace SSR engine with Statum extensions - auth/user-management library, ready-made actions, spry CLI with templates and Docker support

clanker 1 неделя назад
Родитель
Сommit
1ec844ecb1
100 измененных файлов с 1652 добавлено и 24143 удалено
  1. 0 24
      .dockerignore
  2. 0 105
      Dockerfile
  3. 190 0
      README.md
  4. 0 33
      demo/Components/CodeBlockComponent.vala
  5. 0 128
      demo/Components/DemoHostComponent.vala
  6. 0 88
      demo/Components/NavSidebarComponent.vala
  7. 0 106
      demo/DemoComponents/ProgressDemo.vala
  8. 0 53
      demo/DemoComponents/SimpleCounterDemo.vala
  9. 0 178
      demo/DemoComponents/TodoListDemo.vala
  10. 0 86
      demo/Main.vala
  11. 0 49
      demo/MainTemplate.vala
  12. 0 318
      demo/Pages/ComponentsActionsPage.vala
  13. 0 268
      demo/Pages/ComponentsContinuationsPage.vala
  14. 0 393
      demo/Pages/ComponentsMkconstPage.vala
  15. 0 270
      demo/Pages/ComponentsOutletsPage.vala
  16. 0 230
      demo/Pages/ComponentsOverviewPage.vala
  17. 0 372
      demo/Pages/ComponentsTemplateSyntaxPage.vala
  18. 0 120
      demo/Pages/HomePage.vala
  19. 0 269
      demo/Pages/PageComponentsOverviewPage.vala
  20. 0 421
      demo/Pages/PageTemplatesPage.vala
  21. 0 416
      demo/Pages/StaticResourcesMkssrPage.vala
  22. 0 261
      demo/Pages/StaticResourcesOverviewPage.vala
  23. 0 1190
      demo/Static/docs.css
  24. 0 41
      demo/meson.build
  25. 0 138
      examples/ContentInjectionExample.vala
  26. 0 577
      examples/CounterComponent.vala
  27. 0 193
      examples/ProgressExample.vala
  28. 0 120
      examples/SimpleExample.vala
  29. 0 692
      examples/TemplateExample.vala
  30. 0 488
      examples/TodoComponent.vala
  31. 0 20
      examples/UserContentComponent.vala
  32. 0 1
      examples/UserContentComponent.vala.html
  33. 0 1071
      examples/UsersExample.vala
  34. 0 50
      examples/meson.build
  35. 0 5
      generate-static-resources.sh
  36. 0 592
      important-details.md
  37. 0 399
      important-notes-on-writing-documentation-pages.md
  38. 0 453
      invercargill-format-migration-details.md
  39. 4 4
      meson.build
  40. 0 1324
      plans/auth-refactor-architecture.md
  41. 0 658
      plans/authentication-implexus-analysis.md
  42. 0 1258
      plans/invercargill-sql-migration-plan.md
  43. 0 406
      plans/response-state-design.md
  44. 0 804
      plans/user-management-component-redesign.md
  45. 122 0
      src/Actions/AlterUserAction.vala
  46. 79 0
      src/Actions/ChangePasswordAction.vala
  47. 48 0
      src/Actions/DeleteUserAction.vala
  48. 57 0
      src/Actions/GrantPermissionAction.vala
  49. 43 0
      src/Actions/LoginAction.vala
  50. 25 0
      src/Actions/LogoutAction.vala
  51. 137 0
      src/Actions/ProfileValidation.vala
  52. 109 0
      src/Actions/RegisterAction.vala
  53. 58 0
      src/Actions/RevokePermissionAction.vala
  54. 51 0
      src/Actions/SetUserEnabledAction.vala
  55. 21 0
      src/Actions/UserActionPrivate.vala
  56. 78 0
      src/Actions/UserManagementAction.vala
  57. 306 0
      src/Auth.vala
  58. 0 30
      src/Authentication/AuthenticationModule.vala
  59. 0 70
      src/Authentication/Components/LoginComponent.vala
  60. 0 105
      src/Authentication/Components/UserComponent.vala
  61. 0 63
      src/Authentication/Components/UserEditComponent.vala
  62. 0 132
      src/Authentication/Components/UserManagementComponent.vala
  63. 31 27
      src/Authentication/UserEntity.vala
  64. 0 26
      src/Authentication/UserIdentityProvider.vala
  65. 1 1
      src/Authentication/UserPermissionEntity.vala
  66. 49 49
      src/Authentication/UserProjection.vala
  67. 211 121
      src/Authentication/UserService.vala
  68. 0 25
      src/Authorisation/AuthorisationContext.vala
  69. 0 35
      src/Authorisation/AuthorisationError.vala
  70. 0 40
      src/Authorisation/AuthorisationPipelineComponent.vala
  71. 0 44
      src/Authorisation/AuthorisationService.vala
  72. 0 82
      src/Authorisation/AuthorisationToken.vala
  73. 0 41
      src/Authorisation/Identity.vala
  74. 0 32
      src/Authorisation/IdentityProvider.vala
  75. 0 64
      src/Authorisation/PermissionMatcher.vala
  76. 0 664
      src/Component.vala
  77. 0 115
      src/ComponentContextService.vala
  78. 0 60
      src/ComponentEndpoint.vala
  79. 0 39
      src/ComponentFactory.vala
  80. 0 12
      src/Context.vala
  81. 0 49
      src/ContinuationContext.vala
  82. 0 66
      src/ContinuationProvider.vala
  83. 0 103
      src/CryptographyProvider.vala
  84. 0 64
      src/PageComponent.vala
  85. 0 32
      src/PageTemplate.vala
  86. 0 50
      src/PathProvider.vala
  87. 0 10
      src/Renderable.vala
  88. 0 213
      src/ResponseState.vala
  89. 0 66
      src/Spry.vala
  90. 32 0
      src/SpryModule.vala
  91. 0 32
      src/Static/ConstantStaticResource.vala
  92. 0 126
      src/Static/FileStaticResource.vala
  93. 0 7
      src/Static/Htmx.vala
  94. 0 6221
      src/Static/HtmxResource.vala
  95. 0 415
      src/Static/HtmxSseResource.vala
  96. 0 90
      src/Static/MemoryStaticResource.vala
  97. 0 0
      src/Static/Sources/htmx-sse.min.js
  98. 0 0
      src/Static/Sources/htmx.min.js
  99. 0 15
      src/Static/StaticResource.vala
  100. 0 35
      src/Static/StaticResourceProvider.vala

+ 0 - 24
.dockerignore

@@ -1,24 +0,0 @@
-# Build directory
-builddir/
-
-# Git
-.git/
-.gitignore
-
-# IDE/Editor files
-.vscode/
-.idea/
-*.swp
-*.swo
-*~
-
-# Documentation
-*.md
-!README.md
-
-# Any compiled objects
-*.o
-*.a
-
-# Test files
-tests/

+ 0 - 105
Dockerfile

@@ -1,105 +0,0 @@
-# Multi-stage Dockerfile for Spry Framework Demo Website
-# Build stage: Compile the Vala application
-FROM fedora:43 AS builder
-
-# Install build dependencies
-RUN dnf install -y \
-    meson \
-    ninja-build \
-    gcc \
-    vala \
-    glib2-devel \
-    gobject-introspection-devel \
-    json-glib-devel \
-    libxml2-devel \
-    zlib-devel \
-    libzstd-devel \
-    libgee-devel \
-    brotli-devel \
-    libmicrohttpd-devel \
-    libsodium-devel \
-    git \
-    pkg-config \
-    && dnf clean all
-
-# Clone and build invercargill library
-WORKDIR /build
-RUN git clone -b expressions https://fabrica.unitatem.net/Tilo15/Invercargill.git invercargill && \
-    cd invercargill && \
-    meson setup src builddir --prefix=/usr && \
-    ninja -C builddir && \
-    ninja -C builddir install && echo hi
-
-# Clone and build invercargill-json library
-RUN git clone https://git.sr.ht/~tilo15/Invercargill-Json invercargill-json && \
-    cd invercargill-json && \
-    meson setup src builddir --prefix=/usr && \
-    ninja -C builddir && \
-    ninja -C builddir install
-
-# Clone and build inversion library (depends on invercargill)
-RUN git clone https://fabrica.unitatem.net/Tilo15/inversion.git inversion && \
-    cd inversion && \
-    meson setup builddir --prefix=/usr && \
-    ninja -C builddir && \
-    ninja -C builddir install
-
-# Clone and build astralis library (depends on invercargill, invercargill-json, inversion)
-RUN git clone https://fabrica.unitatem.net/Tilo15/astralis.git astralis && \
-    cd astralis && \
-    meson setup builddir --prefix=/usr && \
-    ninja -C builddir && \
-    ninja -C builddir install
-
-# Copy the Spry project source
-COPY . /build/spry
-
-# Build the Spry library and demo
-WORKDIR /build/spry
-RUN meson setup builddir --prefix=/usr && \
-    ninja -C builddir && \
-    ninja -C builddir install
-
-# Runtime stage: Minimal image with only necessary runtime libraries
-FROM fedora:43 AS runtime
-
-# Install runtime dependencies only
-RUN dnf install -y \
-    glib2 \
-    json-glib \
-    libxml2 \
-    zlib \
-    libzstd \
-    brotli \
-    libmicrohttpd \
-    libgee \
-    libsodium \
-    && dnf clean all
-
-# Copy built libraries and executable from builder
-COPY --from=builder /usr/lib64/libinvercargill*.so* /usr/lib64/
-COPY --from=builder /usr/lib64/libinvercargill-json*.so* /usr/lib64/
-COPY --from=builder /usr/lib64/libinversion*.so* /usr/lib64/
-COPY --from=builder /usr/lib64/libastralis*.so* /usr/lib64/
-COPY --from=builder /usr/lib64/libspry*.so* /usr/lib64/
-COPY --from=builder /usr/lib64/girepository-1.0/*.typelib /usr/lib64/girepository-1.0/
-COPY --from=builder /usr/bin/spry-demo /usr/bin/
-
-# Copy demo source files for DemoHostComponent to display in the demo viewer
-# These paths must match what DemoHostComponent.source_file expects
-COPY --from=builder /build/spry/demo/DemoComponents /app/demo/DemoComponents
-
-# Set working directory so relative paths in DemoHostComponent resolve correctly
-WORKDIR /app
-
-# Update library cache
-RUN ldconfig
-
-# Expose the default port
-EXPOSE 8080
-
-# Set environment variables
-ENV PORT=8080
-
-# Run the demo website
-CMD ["spry-demo", "8080"]

+ 190 - 0
README.md

@@ -0,0 +1,190 @@
+# Spry
+
+Spry is a library of **extensions to Statum**: authentication and
+user-management services plus ready-made, subclassable Statum actions. Spry no
+longer renders anything — pages, layouts and static resources are Statum's
+job, and auth UI arrives as app-owned templates generated by the `spry` CLI
+(`spry add login`, `spry add register`, `spry add user-management`).
+
+## The stack
+
+```
+astralis                     HTTP request handling
+└─ Statum                    pages, slots/state, directives, client JS
+   └─ Spry                   THIS LIBRARY: users, auth slot, actions, guards
+      ├─ Invercargill-Sql    spry_users / spry_user_permissions schema
+      └─ Inversion           module + service wiring
+```
+
+## Module usage
+
+```vala
+var application = new Astralis.Application(...);
+
+application.add_module<StatumModule>();
+application.add_module<SpryModule>();          // UserService + schema + migrations
+
+var statum = application.configure_with<StatumConfigurator>();
+SpryAuth.register_actions(statum);             // or hand-pick with statum.action<T>()
+```
+
+`SpryModule` registers no endpoints. It wires the M0001 migration
+(`spry_users`, `spry_user_permissions`), the `UserEntity`/`UserPermissionEntity`
+mappings, the `UserProjection` projection and the scoped `UserService`.
+
+Seed an admin at startup (idempotent — safe on every boot):
+
+```vala
+var scope = application.container.create_scope();
+yield SpryAuth.ensure_admin(scope.resolve<UserService>(),
+    "admin", "admin@example.com", "change-me");
+```
+
+`ensure_admin` looks the account up by username (not a paged listing), so
+it stays correct past any user count, and grants `admin` only when absent
+(`set_user_permission` is itself idempotent).
+
+## The `auth` slot
+
+Identity is a signed Statum SESSION slot of type name `"auth"` — no cookies, no
+bearer tokens. It is written once at login
+(`SpryAuth.login`) and read on every request
+(`SpryAuth.current`).
+
+| Field | Location | Protection | Notes |
+|---|---|---|---|
+| `username` | public | signed (tamper-proof, browser-visible) | login name; bind for nav/guards |
+| `display_name` | public | signed | forename + surname, falling back to username |
+| `permissions` | public | signed | `string[]` of permission patterns; `admin`/`*` match everything, `prefix*` wildcards |
+| `logout` | public | signed | embedded `ActionDto` reference to `LogoutAction` for logout buttons |
+| `user_id` | private | **signed + encrypted** (never reaches the browser) | authoritative `spry_users.id` |
+
+Because `user_id` lives in the slot's encrypted private data, a stolen browser
+copy of the public data cannot impersonate another user, and because the whole
+slot is signed (static keys in `web-config.json`), sessions survive a server
+restart.
+
+## Resolving identity and guarding handlers
+
+```vala
+public class ProfileEntrypoint : StatumEntrypoint {
+
+    protected UserService users = inject<UserService>();
+
+    public override async DirectiveBuilder handle() throws GLib.Error {
+        var guard = yield SpryAuth.require_login(directives(), request, users);
+        if (guard != null) {
+            return (!)guard;                       // navigate("/login")
+        }
+
+        var me = SpryAuth.current(request);
+        if (!me.has_permission("reports.read")) {  // admin / users.* wildcards work
+            ...
+        }
+        ...
+    }
+}
+```
+
+- `SpryAuth.current(request)` → `CurrentUser` (`user_id`, `username`,
+  `display_name`, `permissions`, `is_anonymous`, `has_permission(string)`).
+  Anonymous when no `auth` slot is held. This is the cheap **display
+  identity**: it reflects the signed slot snapshot minted at login, so a
+  disabled/revoked account still resolves until its slot is cleared.
+- `SpryAuth.require_login(directives, request, users, redirect = "/login")`
+  → `null` when the held slot's user id still maps to a live, enabled
+  account, else a `navigate(redirect)` builder. Async — `yield` it.
+- `SpryAuth.require_permission(directives, request, users, permission, redirect = "/login")`
+  → same shape, with the permission set **re-derived from the store**.
+- Guards are authoritative: they take the caller's `UserService` and
+  re-validate on every guarded request, so disabling, deleting or
+  revoking takes effect immediately (no stale login-time snapshot). A
+  store failure fails closed (treated as logged out) after logging a
+  warning.
+- Guards take the caller's `DirectiveBuilder` (from the framework-provided
+  `directives()`) because `DirectiveBuilder` construction is internal to
+  Statum; the builder-in/builder-out shape keeps chaining fluent.
+
+`has_permission` (and the guards' matcher `SpryAuth.permission_matches`)
+preserve the old `PermissionMatcher` semantics exactly: `admin` and `*`
+are super-user patterns, `prefix*` matches any permission with that
+prefix, everything else is an exact match.
+
+## Shipped actions (Spry.Actions)
+
+All are `StatumAction` subclasses designed for subclassing: redirect URIs and
+every notification message are `protected virtual` properties, and `handle()`
+stays a thin delegate to `SpryAuth`/`UserService`.
+
+| Action | Form fields | Guard |
+|---|---|---|
+| `LoginAction` | `username`, `password` | — |
+| `RegisterAction` | `username`, `email`, `forename`, `surname`, `date_of_birth`, `password`, `confirm_password` | — |
+| `LogoutAction` | — | — |
+| `ChangePasswordAction` | `current_password`, `new_password`, `confirm_password` | logged-in |
+| `SetUserEnabledAction` | `enabled`; target from sealed private data or `user_id` | `require_permission` (default `admin`) |
+| `GrantPermissionAction` | `permission`; target from sealed private data or `user_id` | `require_permission` (default `admin`) |
+| `RevokePermissionAction` | `permission`; target from sealed private data or `user_id` | `require_permission` (default `admin`); removes only the matching rows |
+| `AlterUserAction` | `username`, `email`, `forename`, `surname`, `date_of_birth`, `enabled`, `new_password` (optional); target from sealed private data or `user_id` | `require_permission` (default `admin`); refuses self-alter |
+| `DeleteUserAction` | — (sealed private data or `user_id`) | `require_permission` (default `admin`); refuses self-delete |
+
+Register them all with `SpryAuth.register_actions(statum)`, or individually
+with `statum.action<T>()` (e.g. your own `LoginAction` subclass with a
+different `landing_uri`).
+
+Register and Alter share one validator (`Spry.Actions.ProfileValidation`):
+username length, email shape, required names and a strict YYYY-MM-DD date
+of birth parse that rejects impossible calendar dates (31 February and
+friends) by round-tripping the parsed date. Both actions map uniqueness
+failures to the same friendly duplicate messages, so raw database errors
+never reach the client.
+
+### Sealed row actions (user management)
+
+The five management actions read their target `user_id` from **sealed
+private data**: a row action reference authored with
+
+```vala
+var target = new Spry.Actions.UserActionPrivate();
+target.user_id = row_user.id;
+row.grant = action_registry.author_private<Spry.Actions.GrantPermissionAction, Spry.Actions.UserActionPrivate>(target);
+```
+
+carries the id in an encrypted `X-Statum-Private` blob sealed under the
+action's own namespace, which the shipped action decrypts directly
+(`Spry.Actions.UserActionPrivate` is the shared private model — no app-side
+subclasses needed). The plain `user_id` form field still works when a
+request carries no blob, so hand-written forms keep functioning.
+`ChangePasswordAction` verifies its `current_password` form field against
+the stored hash (`UserService.authenticate_user`) before writing the new
+password.
+
+## The user store (`UserService`)
+
+Injected per-request (`inject<UserService>()`); every method is `async`
+and `throws Error`:
+
+| Method | Behaviour |
+|---|---|
+| `authenticate_user(username, password)` | `UserProjection?` — `null` for unknown username, wrong password **or disabled account** (same generic failure, no enumeration side channel; unknown usernames burn a dummy hash check so both paths take comparable time) |
+| `get_user(user_id)` / `get_user_by_username(username)` | `UserProjection?` with the user's permission patterns |
+| `register_user(...)` | inserts and returns the new `UserEntity` |
+| `set_password`, `alter_user`, `set_user_enabled`, `delete_user` | throw `UserServiceError.USER_NOT_FOUND` for a stale id instead of crashing |
+| `set_user_permission(user_id, permission)` | idempotent — no duplicate row when already held |
+| `remove_user_permission(user_id, permission)` | single targeted delete of the matching rows (other permissions untouched) |
+| `clear_user_permissions`, `get_user_permissions`, `list_users` | bulk read/clear, unchanged |
+
+Guards (`SpryAuth.require_login`/`require_permission`) build on
+`get_user` for their per-request re-validation.
+
+## Migrating from old Spry
+
+| Old (≤ 0.1) | New (0.2) |
+|---|---|
+| `AuthorisationContext` (injected) | `SpryAuth.current(request)` |
+| `AuthorisationService`/`AuthorisationToken`, cookies | the signed `auth` slot; `SpryAuth.login(...)` |
+| `authenticate_user` returning a token | returns `UserProjection?` |
+| `LoginComponent`/`UserManagementComponent` UI | `spry add login` / `spry add user-management` CLI templates bound to `Spry.Actions` |
+| `AuthenticationModule` | `SpryModule` |
+| `PermissionMatcher` | `CurrentUser.has_permission` |
+| `CryptographyProvider`, `UserIdentityProvider`, continuations, `spry-mkssr`/`spry-mkconst`, htmx resources | deleted — Statum handles signing/encryption, pages, resources and client JS |

+ 0 - 33
demo/Components/CodeBlockComponent.vala

@@ -1,33 +0,0 @@
-using Spry;
-
-/**
- * CodeBlockComponent - A styled code block with syntax highlighting
- * 
- * Displays code with a header showing language and window dots
- */
-public class CodeBlockComponent : Component {
-    
-    public string language { set; get; default = "Vala"; }
-    public string code { set; get; default = ""; }
-    
-    public override string markup { get {
-        return """
-        <div class="code-block">
-            <div class="code-header">
-                <div class="code-dots">
-                    <div class="code-dot red"></div>
-                    <div class="code-dot yellow"></div>
-                    <div class="code-dot green"></div>
-                </div>
-                <span class="code-lang" sid="language"></span>
-            </div>
-            <pre><code sid="code"></code></pre>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        this["language"].text_content = language;
-        this["code"].text_content = code;
-    }
-}

+ 0 - 128
demo/Components/DemoHostComponent.vala

@@ -1,128 +0,0 @@
-using Spry;
-using Inversion;
-using Invercargill.DataStructures;
-
-/**
- * DemoHostComponent - A component that hosts demo implementations with source/demo toggle
- * 
- * This component provides a frame for demo content with the ability to toggle
- * between viewing the demo and viewing the source code.
- * 
- * Usage:
- *   var host = factory.create<DemoHostComponent>();
- *   host.demo_component_name = "SimpleCounterDemo";
- *   host.source_file = "demo/DemoComponents/SimpleCounterDemo.vala";
- */
-public class DemoHostComponent : Component {
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    /// Name of the demo component to create and display
-    public string demo_component_name { get; set; }
-    
-    /// Path to the source file to display (relative to project root)
-    public string source_file { get; set; default = ""; }
-    
-    /// Toggle state - true when showing source code
-    public bool showing_source { get; set; default = false; }
-    
-    /// The loaded source code content (cached after first load)
-    private string? _source_content = null;
-    
-    public override string markup { get {
-        return """
-        <spry-context property="demo_component_name"/>
-        <spry-context property="source_file"/>
-        <div class="demo-host" sid="host" hx-swap="outerHTML">
-            <div class="demo-header">
-                <span class="demo-title" sid="title">Demo</span>
-                <div class="demo-toggle-group">
-                    <button class="demo-toggle-btn" spry-action=":ShowDemo" spry-target="host" 
-                            class-active-expr="!this.showing_source">Demo</button>
-                    <button class="demo-toggle-btn" spry-action=":ShowSource" spry-target="host"
-                            class-active-expr="this.showing_source">Source</button>
-                </div>
-            </div>
-            <div class="demo-content" sid="content">
-                <div spry-if="this.showing_source">
-                    <pre class="demo-source"><code sid="source-code"></code></pre>
-                </div>
-                <div spry-else>
-                    <spry-outlet sid="demo-outlet"/>
-                </div>
-            </div>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Update the title with the demo component name
-        if (demo_component_name != null) {
-            this["title"].text_content = demo_component_name;
-        }
-        
-        // Create the demo component and add it to the outlet when showing demo
-        if (!showing_source && source_file != null) {
-            var demo = factory.create_by_name(demo_component_name);
-            var series = new Series<Renderable>();
-            series.add(demo);
-            set_outlet_children("demo-outlet", series);
-        }
-        
-        // Update the source code display if we're showing source
-        if (showing_source && _source_content != null) {
-            this["source-code"].text_content = _source_content;
-        }
-    }
-    
-    public async override void handle_action(string action) throws Error {
-        switch (action) {
-            case "ShowDemo":
-                showing_source = false;
-                break;
-            case "ShowSource":
-                if (_source_content == null) {
-                    _source_content = yield load_source_file();
-                }
-                showing_source = true;
-                break;
-        }
-    }
-    
-    /**
-     * Load the source file from disk and escape HTML entities
-     */
-    private async string load_source_file() {
-        try {
-            var path = source_file;
-            // Try to read from the project root (relative path)
-            var file = File.new_for_path(path);
-            
-            if (!file.query_exists()) {
-                return @"Error: Source file not found: $path";
-            }
-            
-            uint8[] contents;
-            string etag_out;
-            yield file.load_contents_async(null, out contents, out etag_out);
-            
-            var source = (string)contents;
-            return escape_html(source);
-        } catch (Error e) {
-            return @"Error loading source file: $(e.message)";
-        }
-    }
-    
-    /**
-     * Escape HTML entities for safe display in <pre><code> blocks
-     */
-    private string escape_html(string input) {
-        var result = input
-            .replace("&", "&amp;")
-            .replace("<", "&lt;")
-            .replace(">", "&gt;")
-            .replace("\"", "&quot;")
-            .replace("'", "&#39;");
-        return result;
-    }
-}

+ 0 - 88
demo/Components/NavSidebarComponent.vala

@@ -1,88 +0,0 @@
-using Spry;
-
-/**
- * NavSidebarComponent - A simple navigation sidebar for the documentation site
- * 
- * Features:
- * - All items always visible (no collapsing)
- * - Current page highlighting
- */
-public class NavSidebarComponent : Component {
-    
-    public string current_path { get; set; default = "/"; }
-    
-    public override string markup { get {
-        return """
-        <aside class="nav-sidebar" sid="sidebar" hx-disinherit="*">
-            <!-- Home - Single link -->
-            <div class="nav-section">
-                <a href="/" class="nav-item" sid="home-link">Home</a>
-            </div>
-            
-            <!-- Components Section -->
-            <div class="nav-section">
-                <h3 class="nav-section-title">Components</h3>
-                <ul class="nav-items">
-                    <li><a href="/components/overview" class="nav-item" sid="components-overview">Overview</a></li>
-                    <li><a href="/components/template-syntax" class="nav-item" sid="components-template-syntax">Template Syntax</a></li>
-                    <li><a href="/components/actions" class="nav-item" sid="components-actions">Actions</a></li>
-                    <li><a href="/components/outlets" class="nav-item" sid="components-outlets">Outlets</a></li>
-                    <li><a href="/components/continuations" class="nav-item" sid="components-continuations">Continuations</a></li>
-                    <li><a href="/components/spry-mkconst" class="nav-item" sid="components-spry-mkconst">Using spry-mkconst</a></li>
-                </ul>
-            </div>
-            
-            <!-- Page Components Section -->
-            <div class="nav-section">
-                <h3 class="nav-section-title">Page Components</h3>
-                <ul class="nav-items">
-                    <li><a href="/page-components/overview" class="nav-item" sid="page-components-overview">Overview</a></li>
-                    <li><a href="/page-components/templates" class="nav-item" sid="page-components-templates">Page Templates</a></li>
-                </ul>
-            </div>
-            
-            <!-- Static Resources Section -->
-            <div class="nav-section">
-                <h3 class="nav-section-title">Static Resources</h3>
-                <ul class="nav-items">
-                    <li><a href="/static-resources/overview" class="nav-item" sid="static-resources-overview">Overview</a></li>
-                    <li><a href="/static-resources/spry-mkssr" class="nav-item" sid="static-resources-spry-mkssr">Using spry-mkssr</a></li>
-                </ul>
-            </div>
-        </aside>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Highlight the current page link
-        highlight_current_link();
-    }
-    
-    private void highlight_current_link() {
-        // Get the sid for the current path and add active class
-        string? sid = get_sid_for_path(current_path);
-        if (sid != null) {
-            var link = this[sid];
-            if (link != null) {
-                link.add_class("active");
-            }
-        }
-    }
-    
-    private string? get_sid_for_path(string path) {
-        switch (path) {
-            case "/": return "home-link";
-            case "/components/overview": return "components-overview";
-            case "/components/template-syntax": return "components-template-syntax";
-            case "/components/actions": return "components-actions";
-            case "/components/outlets": return "components-outlets";
-            case "/components/continuations": return "components-continuations";
-            case "/components/spry-mkconst": return "components-spry-mkconst";
-            case "/page-components/overview": return "page-components-overview";
-            case "/page-components/templates": return "page-components-templates";
-            case "/static-resources/overview": return "static-resources-overview";
-            case "/static-resources/spry-mkssr": return "static-resources-spry-mkssr";
-            default: return null;
-        }
-    }
-}

+ 0 - 106
demo/DemoComponents/ProgressDemo.vala

@@ -1,106 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * ProgressDemo - A progress bar demo for the Continuations documentation
- * 
- * Demonstrates:
- * - spry-continuation attribute for SSE
- * - spry-dynamic for updatable sections
- * - continuation() method for real-time updates
- * - ContinuationContext API
- */
-public class ProgressDemo : Component {
-    
-    public int percent { get; set; default = 0; }
-    public string status { get; set; default = "Ready"; }
-    public bool is_running { get; set; default = false; }
-    
-    public override string markup { get {
-        return """
-        <div sid="progress" spry-continuation class="demo-progress" style="padding: 20px; background: #f8f9fa; border-radius: 8px; border: 1px solid #e9ecef;">
-            <div spry-dynamic="progress-bar" class="progress-bar-container" style="background: #e0e0e0; border-radius: 8px; overflow: hidden; margin: 15px 0; height: 24px;">
-                <div sid="progress-bar" class="progress-bar"
-                     style-width-expr='format("{{this.percent}}%")'
-                     style="height: 100%; background: linear-gradient(90deg, #4CAF50, #8BC34A); transition: width 0.3s ease; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 12px; min-width: 40px;">
-                </div>
-            </div>
-            <div spry-dynamic="status" class="progress-info" style="display: flex; justify-content: space-between; align-items: center; margin: 15px 0;">
-                <span sid="percent-text" class="progress-percent" spry-unique content-expr='format("{{this.percent}}%")' style="font-weight: bold; color: #333; font-size: 18px;">0%</span>
-                <span sid="status-text" class="progress-status" spry-unique content-expr="this.status" style="color: #666; font-size: 14px; padding: 6px 12px; background: #e9ecef; border-radius: 4px; border-left: 3px solid #2196F3;">Ready</span>
-            </div>
-            <div class="progress-controls" style="display: flex; gap: 10px; margin-top: 15px;">
-                <button sid="start-btn" spry-action=":Start" spry-target="progress"
-                        class="progress-btn" style="padding: 10px 20px; background: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: 500; transition: background 0.2s;">Start Task</button>
-                <button sid="reset-btn" spry-action=":Reset" spry-target="progress"
-                        class="progress-btn secondary" style="padding: 10px 20px; background: #6c757d; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: 500; transition: background 0.2s;">Reset</button>
-            </div>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        this["status-text"].text_content = status;
-        this["percent-text"].text_content = @"$percent%";
-        
-        if (is_running) {
-            this["start-btn"].set_attribute("disabled", "disabled");
-            this["start-btn"].text_content = "Running...";
-        } else {
-            this["start-btn"].remove_attribute("disabled");
-            this["start-btn"].text_content = percent >= 100 ? "Complete!" : "Start Task";
-        }
-    }
-    
-    public async override void handle_action(string action) throws Error {
-        switch (action) {
-            case "Start":
-                if (!is_running && percent < 100) {
-                    is_running = true;
-                    status = "Starting...";
-                }
-                break;
-            case "Reset":
-                percent = 0;
-                status = "Ready";
-                is_running = false;
-                break;
-        }
-    }
-    
-    public async override void continuation(ContinuationContext ctx) throws Error {
-        if (!is_running) return;
-        
-        for (int i = percent; i <= 100; i += 5) {
-            percent = i;
-            
-            if (i < 30) {
-                status = @"Processing... $i%";
-            } else if (i < 60) {
-                status = @"Building... $i%";
-            } else if (i < 90) {
-                status = @"Finalizing... $i%";
-            } else {
-                status = @"Almost done... $i%";
-            }
-            
-            // Send updates via SSE to the dynamic sections
-            yield ctx.send_dynamic("progress-bar");
-            yield ctx.send_dynamic("status");
-            
-            // Simulate work
-            Timeout.add(200, () => {
-                continuation.callback();
-                return false;
-            });
-            yield;
-        }
-        
-        percent = 100;
-        status = "Complete!";
-        is_running = false;
-        
-        yield ctx.send_dynamic("progress-bar");
-        yield ctx.send_dynamic("status");
-    }
-}

+ 0 - 53
demo/DemoComponents/SimpleCounterDemo.vala

@@ -1,53 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * SimpleCounterDemo - A basic counter demo for the Actions documentation
- * 
- * Demonstrates:
- * - spry-action for same-component actions
- * - spry-target for scoped targeting
- * - State management via a singleton store
- */
-public class SimpleCounterDemo : Component {
-    
-    private CounterDemoStore store = inject<CounterDemoStore>();
-    
-    public override string markup { get {
-        return """
-        <div sid="counter" class="demo-counter">
-            <div class="counter-display" sid="display">0</div>
-            <div class="counter-controls">
-                <button class="counter-btn decrement" 
-                        spry-action=":Decrement" 
-                        spry-target="counter">−</button>
-                <button class="counter-btn increment" 
-                        spry-action=":Increment" 
-                        spry-target="counter">+</button>
-            </div>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        this["display"].text_content = store.count.to_string();
-    }
-    
-    public async override void handle_action(string action) throws Error {
-        switch (action) {
-            case "Increment":
-                store.count++;
-                break;
-            case "Decrement":
-                store.count--;
-                break;
-        }
-    }
-}
-
-/**
- * CounterDemoStore - Singleton store to persist counter state
- */
-public class CounterDemoStore : Object {
-    public int count { get; set; default = 0; }
-}

+ 0 - 178
demo/DemoComponents/TodoListDemo.vala

@@ -1,178 +0,0 @@
-using Spry;
-using Astralis;
-using Inversion;
-using Invercargill.DataStructures;
-
-/**
- * TodoListDemo - A todo list demo for the Outlets documentation
- * 
- * Demonstrates:
- * - Using spry-outlet for dynamic child components
- * - set_outlet_children() to populate outlets
- * - Parent/child component composition
- */
-public class TodoListDemo : Component {
-    
-    private TodoDemoStore store = inject<TodoDemoStore>();
-    private ComponentFactory factory = inject<ComponentFactory>();
-    private HttpContext http_context = inject<HttpContext>();
-    
-    public override string markup { get {
-        return """
-        <div sid="todo-list" class="demo-todo-list">
-            <div class="todo-header">
-                <h3>Todo List</h3>
-                <span class="todo-count" sid="count"></span>
-            </div>
-            <form class="todo-form" spry-action=":Add" spry-target="todo-list">
-                <input type="text" name="title" placeholder="Add a task..." sid="input"/>
-                <button type="submit" class="todo-add-btn">Add</button>
-            </form>
-            <ul class="todo-items" sid="items">
-                <spry-outlet sid="items-outlet"/>
-            </ul>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Update count
-        this["count"].text_content = @"$(store.items.length) items";
-        
-        // Build list items
-        var children = new Series<Renderable>();
-        foreach (var item in store.items) {
-            var component = factory.create<TodoItemDemo>();
-            component.item_id = item.id;
-            children.add(component);
-        }
-        set_outlet_children("items-outlet", children);
-    }
-    
-    public async override void handle_action(string action) throws Error {
-        if (action == "Add") {
-            var title = http_context.request.query_params.get_any_or_default("title");
-            if (title != null && title.strip().length > 0) {
-                store.add(title.strip());
-            }
-        }
-    }
-}
-
-/**
- * TodoItemDemo - Individual todo item component
- */
-public class TodoItemDemo : Component {
-    
-    private TodoDemoStore store = inject<TodoDemoStore>();
-    private HttpContext http_context = inject<HttpContext>();
-    
-    public int item_id { set; get; }
-    
-    public override string markup { get {
-        return """
-        <li sid="item" class="todo-item">
-            <span sid="title" class="todo-title"></span>
-            <button sid="toggle" spry-action=":Toggle" spry-target="item" 
-                    class="todo-toggle"></button>
-            <button sid="delete" spry-action=":Delete" spry-target="item"
-                    hx-swap="delete" class="todo-delete">×</button>
-        </li>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // If item_id is not set (fresh instance from action), try to get it from query params
-        if (item_id == 0) {
-            var id_str = http_context.request.query_params.get_any_or_default("id");
-            if (id_str != null) {
-                item_id = int.parse(id_str);
-            }
-        }
-        
-        var item = store.get_by_id(item_id);
-        if (item == null) return;
-        
-        this["title"].text_content = item.title;
-        this["item"].set_attribute("hx-vals", @"{\"id\":$item_id}");
-        
-        if (item.completed) {
-            this["item"].add_class("completed");
-            this["toggle"].text_content = "↩";
-        } else {
-            this["toggle"].text_content = "✓";
-        }
-    }
-    
-    public async override void handle_action(string action) throws Error {
-        var id_str = http_context.request.query_params.get_any_or_default("id");
-        var id = int.parse(id_str);
-        
-        switch (action) {
-            case "Toggle":
-                store.toggle(id);
-                break;
-            case "Delete":
-                store.remove(id);
-                break;
-        }
-    }
-}
-
-/**
- * TodoDemoStore - Singleton store for todo items
- */
-public class TodoDemoStore : Object {
-    
-    public Series<TodoDemoItem> items { get; set; default = new Series<TodoDemoItem>(); }
-    private int _next_id = 1;
-    
-    public TodoDemoStore() {
-        // Add some initial items
-        add("Learn Spry components");
-        add("Build a web app");
-        add("Deploy to production");
-    }
-    
-    public void add(string title) {
-        items.add(new TodoDemoItem(_next_id++, title));
-    }
-    
-    public TodoDemoItem? get_by_id(int id) {
-        foreach (var item in items) {
-            if (item.id == id) return item;
-        }
-        return null;
-    }
-    
-    public void toggle(int id) {
-        var item = get_by_id(id);
-        if (item != null) {
-            item.completed = !item.completed;
-        }
-    }
-    
-    public void remove(int id) {
-        // Build a new list without the item
-        var new_items = new Series<TodoDemoItem>();
-        foreach (var item in items) {
-            if (item.id != id) {
-                new_items.add(item);
-            }
-        }
-        items = new_items;
-    }
-}
-
-/**
- * TodoDemoItem - Single todo item data
- */
-public class TodoDemoItem : Object {
-    public int id { get; construct; }
-    public string title { get; construct set; }
-    public bool completed { get; set; default = false; }
-    
-    public TodoDemoItem(int id, string title) {
-        Object(id: id, title: title);
-    }
-}

+ 0 - 86
demo/Main.vala

@@ -1,86 +0,0 @@
-using Astralis;
-using Invercargill;
-using Invercargill.DataStructures;
-using Inversion;
-using Spry;
-using Demo.Static;
-
-void main(string[] args) {
-    int port = args.length > 1 ? int.parse(args[1]) : 8080;
-    
-    try {
-        var application = new WebApplication(port);
-        
-        // Enable compression
-        application.use_compression();
-        
-        // Add Spry module for component actions
-        application.add_module<SpryModule>();
-        
-        // Configure templates
-        var spry_cfg = application.configure_with<SpryConfigurator>();
-        spry_cfg.add_template<MainTemplate>("");
-
-        // Register static resources
-        application.container.register_startup<DocsCssResource>()
-            .as<Spry.StaticResource>();
-
-        // Register demo stores (singletons for state persistence)
-        application.add_singleton<CounterDemoStore>();
-        application.add_singleton<TodoDemoStore>();
-        
-        // Add Components
-        application.add_transient<CodeBlockComponent>();
-        application.add_transient<DemoHostComponent>();
-        application.add_transient<NavSidebarComponent>();
-        
-        // Add Demo Components
-        application.add_transient<SimpleCounterDemo>();
-        application.add_transient<TodoListDemo>();
-        application.add_transient<TodoItemDemo>();
-        application.add_transient<ProgressDemo>();
-        
-        // Register page components
-        application.add_transient<HomePage>();
-        application.add_endpoint<HomePage>(new EndpointRoute("/"));
-        
-        // Components documentation pages
-        application.add_transient<ComponentsOverviewPage>();
-        application.add_endpoint<ComponentsOverviewPage>(new EndpointRoute("/components/overview"));
-        
-        application.add_transient<ComponentsTemplateSyntaxPage>();
-        application.add_endpoint<ComponentsTemplateSyntaxPage>(new EndpointRoute("/components/template-syntax"));
-        
-        application.add_transient<ComponentsActionsPage>();
-        application.add_endpoint<ComponentsActionsPage>(new EndpointRoute("/components/actions"));
-        
-        application.add_transient<ComponentsOutletsPage>();
-        application.add_endpoint<ComponentsOutletsPage>(new EndpointRoute("/components/outlets"));
-        
-        application.add_transient<ComponentsContinuationsPage>();
-        application.add_endpoint<ComponentsContinuationsPage>(new EndpointRoute("/components/continuations"));
-        
-        application.add_transient<ComponentsMkconstPage>();
-        application.add_endpoint<ComponentsMkconstPage>(new EndpointRoute("/components/spry-mkconst"));
-        
-        // Page Components documentation pages
-        application.add_transient<PageComponentsOverviewPage>();
-        application.add_endpoint<PageComponentsOverviewPage>(new EndpointRoute("/page-components/overview"));
-        
-        application.add_transient<PageTemplatesPage>();
-        application.add_endpoint<PageTemplatesPage>(new EndpointRoute("/page-components/templates"));
-        
-        // Static Resources documentation pages
-        application.add_transient<StaticResourcesOverviewPage>();
-        application.add_endpoint<StaticResourcesOverviewPage>(new EndpointRoute("/static-resources/overview"));
-        
-        application.add_transient<StaticResourcesMkssrPage>();
-        application.add_endpoint<StaticResourcesMkssrPage>(new EndpointRoute("/static-resources/spry-mkssr"));
-        
-        application.run();
-        
-    } catch (Error e) {
-        printerr("Error: %s\n", e.message);
-        Process.exit(1);
-    }
-}

+ 0 - 49
demo/MainTemplate.vala

@@ -1,49 +0,0 @@
-using Astralis;
-using Spry;
-using Inversion;
-
-/**
- * MainTemplate - The base template for documentation pages
- * 
- * Provides a clean, minimal HTML structure for documentation:
- * - HTML5 document structure
- * - NavSidebarComponent for navigation
- * - docs.css stylesheet for documentation styling
- * - htmx.js and htmx-sse.js for interactive components
- * - Template outlet for page content
- */
-public class MainTemplate : PageTemplate {
-    
-    private NavSidebarComponent nav;
-    private RouteContext route_context = inject<RouteContext>();
-    
-    public override string markup { get {
-        return """
-        <!DOCTYPE html>
-        <html lang="en">
-        <head>
-            <meta charset="utf-8">
-            <meta name="viewport" content="width=device-width, initial-scale=1">
-            <title>Spry Documentation</title>
-            <link rel="stylesheet" spry-res="docs.css">
-        </head>
-        <body>
-            <div class="page-container">
-                <spry-component name="NavSidebarComponent" sid="nav"/>
-                <main class="main-content">
-                    <spry-content />
-                </main>
-            </div>
-            <script spry-res="htmx.js"></script>
-            <script spry-res="htmx-sse.js"></script>
-        </body>
-        </html>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Get the nav component and set the current path from the route context
-        nav = get_component_child<NavSidebarComponent>("nav");
-        nav.current_path = route_context.requested_path;
-    }
-}

+ 0 - 318
demo/Pages/ComponentsActionsPage.vala

@@ -1,318 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * ComponentsActionsPage - Documentation for Spry component actions
- * 
- * This page covers how actions work, the spry-action attribute syntax,
- * and how to handle user interactions in components.
- */
-public class ComponentsActionsPage : PageComponent {
-    
-    public override string title { get { return "Actions - Spry"; } }
-    
-    public const string ROUTE = "/components/actions";
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <div sid="page" class="doc-content">
-            <h1>Actions</h1>
-            
-            <section class="doc-section">
-                <p>
-                    Actions are the primary way to handle user interactions in Spry. When a user
-                    clicks a button, submits a form, or triggers any HTMX event, an action is sent
-                    to the server and handled by your component.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>How Actions Work</h2>
-                <p>
-                    The flow of an action request:
-                </p>
-                <ol>
-                    <li>User interacts with an element that has <code>spry-action</code></li>
-                    <li>HTMX sends a request to the Spry action endpoint</li>
-                    <li>Spry creates a <strong>new</strong> component instance and calls <code>handle_action()</code></li>
-                    <li>Your component modifies state in stores (not instance variables!)</li>
-                    <li>Spry calls <code>prepare()</code> to update the template from store data</li>
-                    <li>The updated HTML is sent back and swapped into the page</li>
-                </ol>
-                
-                <div class="warning-box">
-                    <p>
-                        <strong>⚠️ Critical:</strong> A <strong>new component instance</strong> is created for each action request.
-                        Any instance variables (like <code>is_on</code>, <code>count</code>) will NOT retain their values.
-                        Always store state in singleton stores, not component instance fields.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>The <code>spry-action</code> Attribute</h2>
-                <p>
-                    The <code>spry-action</code> attribute specifies which action to trigger. There are
-                    two syntaxes depending on whether you're targeting the same component or a different one.
-                </p>
-                
-                <h3>Same-Component Actions</h3>
-                <p>
-                    Use <code>:ActionName</code> to trigger an action on the same component type that contains
-                    the element.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="same-action-html"/>
-                <spry-component name="CodeBlockComponent" sid="same-action-vala"/>
-                
-                <h3>Cross-Component Actions</h3>
-                <p>
-                    Use <code>ComponentName:ActionName</code> to trigger an action on a different component type.
-                    This is useful when an interaction in one component should update another.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="cross-action-html"/>
-                <spry-component name="CodeBlockComponent" sid="cross-action-vala"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>The <code>spry-target</code> Attribute</h2>
-                <p>
-                    The <code>spry-target</code> attribute specifies which element should be replaced
-                    when the action completes. It uses the <code>sid</code> of an element within the
-                    same component.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="target-example"/>
-                
-                <div class="info-box">
-                    <p>
-                        <strong>💡 Tip:</strong> <code>spry-target</code> only works within the same component.
-                        For cross-component targeting, use <code>hx-target="#element-id"</code> with a
-                        global <code>id</code> attribute.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Passing Data with <code>hx-vals</code></h2>
-                <p>
-                    Since a new component instance is created for each request, you need to pass data
-                    explicitly using <code>hx-vals</code>. This data becomes available in query parameters,
-                    allowing you to identify which item to operate on.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="hx-vals-html"/>
-                <spry-component name="CodeBlockComponent" sid="hx-vals-vala"/>
-                
-                <div class="info-box">
-                    <p>
-                        <strong>💡 Tip:</strong> Set <code>hx-vals</code> on a parent element - it will be
-                        inherited by all child elements. This avoids repetition and keeps your code clean.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Swap Strategies</h2>
-                <p>
-                    Control how the response is inserted with <code>hx-swap</code>:
-                </p>
-                
-                <table class="doc-table">
-                    <thead>
-                        <tr>
-                            <th>Value</th>
-                            <th>Description</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        <tr>
-                            <td><code>outerHTML</code></td>
-                            <td>Replace the entire target element (default for most cases)</td>
-                        </tr>
-                        <tr>
-                            <td><code>innerHTML</code></td>
-                            <td>Replace only the content inside the target</td>
-                        </tr>
-                        <tr>
-                            <td><code>delete</code></td>
-                            <td>Remove the target element (no response content needed)</td>
-                        </tr>
-                        <tr>
-                            <td><code>beforebegin</code></td>
-                            <td>Insert content before the target element</td>
-                        </tr>
-                        <tr>
-                            <td><code>afterend</code></td>
-                            <td>Insert content after the target element</td>
-                        </tr>
-                    </tbody>
-                </table>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Complete Example: Toggle with Store</h2>
-                <p>
-                    Here's a complete example showing proper state management using a store.
-                    The store is a singleton that persists state across requests:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="store-example"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Live Demo: Counter</h2>
-                <p>
-                    Try this interactive counter to see actions in action. The counter state
-                    is stored in a singleton store, so it persists between requests:
-                </p>
-                
-                <spry-component name="DemoHostComponent" sid="counter-demo"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Next Steps</h2>
-                <div class="nav-cards">
-                    <a href="/components/outlets" class="nav-card">
-                        <h3>Outlets →</h3>
-                        <p>Compose components with outlets</p>
-                    </a>
-                    <a href="/components/continuations" class="nav-card">
-                        <h3>Continuations →</h3>
-                        <p>Real-time updates with SSE</p>
-                    </a>
-                    <a href="/components/template-syntax" class="nav-card">
-                        <h3>Template Syntax ←</h3>
-                        <p>Review template attributes</p>
-                    </a>
-                </div>
-            </section>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Same-component action examples
-        var same_action_html = get_component_child<CodeBlockComponent>("same-action-html");
-        same_action_html.language = "HTML";
-        same_action_html.code = "<div sid=\"item\">\n" +
-            "    <span sid=\"status\">Off</span>\n" +
-            "    <button spry-action=\":Toggle\" spry-target=\"item\">Toggle</button>\n" +
-            "</div>";
-        
-        var same_action_vala = get_component_child<CodeBlockComponent>("same-action-vala");
-        same_action_vala.language = "Vala";
-        same_action_vala.code = "public async override void handle_action(string action) throws Error {\n" +
-            "    // Get item ID from hx-vals (passed via query params)\n" +
-            "    var id = get_id_from_query_params();\n\n" +
-            "    if (action == \"Toggle\") {\n" +
-            "        // Modify state in the STORE, not instance variables!\n" +
-            "        store.toggle(id);\n" +
-            "    }\n" +
-            "    // prepare() is called automatically to update template from store\n" +
-            "}";
-        
-        // Cross-component action examples
-        var cross_action_html = get_component_child<CodeBlockComponent>("cross-action-html");
-        cross_action_html.language = "HTML";
-        cross_action_html.code = "<!-- In AddFormComponent -->\n" +
-            "<form spry-action=\"TodoList:Add\" hx-target=\"#todo-list\" hx-swap=\"outerHTML\">\n" +
-            "    <input name=\"title\" type=\"text\"/>\n" +
-            "    <button type=\"submit\">Add</button>\n" +
-            "</form>";
-        
-        var cross_action_vala = get_component_child<CodeBlockComponent>("cross-action-vala");
-        cross_action_vala.language = "Vala";
-        cross_action_vala.code = "// In TodoListComponent\n" +
-            "public async override void handle_action(string action) throws Error {\n" +
-            "    if (action == \"Add\") {\n" +
-            "        var title = http_context.request.query_params.get_any_or_default(\"title\");\n" +
-            "        // Modify state in the store\n" +
-            "        store.add(title);\n" +
-            "    }\n" +
-            "    // prepare() rebuilds the list from store data\n" +
-            "}";
-        
-        // Target example
-        var target_example = get_component_child<CodeBlockComponent>("target-example");
-        target_example.language = "HTML";
-        target_example.code = "<div sid=\"item\" class=\"item\">\n" +
-            "    <span sid=\"title\">Item Title</span>\n" +
-            "    <button spry-action=\":Delete\" spry-target=\"item\" hx-swap=\"delete\">\n" +
-            "        Delete\n" +
-            "    </button>\n" +
-            "</div>";
-        
-        // hx-vals examples
-        var hx_vals_html = get_component_child<CodeBlockComponent>("hx-vals-html");
-        hx_vals_html.language = "HTML";
-        hx_vals_html.code = "<div sid=\"item\" hx-vals='{\"id\": 42}'>\n" +
-            "    <!-- Children inherit hx-vals -->\n" +
-            "    <button spry-action=\":Toggle\" spry-target=\"item\">Toggle</button>\n" +
-            "    <button spry-action=\":Delete\" spry-target=\"item\">Delete</button>\n" +
-            "</div>";
-        
-        var hx_vals_vala = get_component_child<CodeBlockComponent>("hx-vals-vala");
-        hx_vals_vala.language = "Vala";
-        hx_vals_vala.code = "public async override void handle_action(string action) throws Error {\n" +
-            "    // Get the id from query params (passed via hx-vals)\n" +
-            "    var id_str = http_context.request.query_params.get_any_or_default(\"id\");\n" +
-            "    var id = int.parse(id_str);\n\n" +
-            "    // Use the id to find and modify the item IN THE STORE\n" +
-            "    switch (action) {\n" +
-            "        case \"Toggle\":\n" +
-            "            store.toggle(id);\n" +
-            "            break;\n" +
-            "        case \"Delete\":\n" +
-            "            store.remove(id);\n" +
-            "            break;\n" +
-            "    }\n" +
-            "}";
-        
-        // Complete example with store
-        var store_example = get_component_child<CodeBlockComponent>("store-example");
-        store_example.language = "Vala";
-        store_example.code = "// First, define a store (singleton) to hold state\n" +
-            "public class ToggleStore : Object {\n" +
-            "    private bool _is_on = false;\n" +
-            "    public bool is_on { get { return _is_on; } }\n\n" +
-            "    public void toggle() {\n" +
-            "        _is_on = !_is_on;\n" +
-            "    }\n" +
-            "}\n\n" +
-            "// Register as singleton in your app:\n" +
-            "// application.add_singleton<ToggleStore>();\n\n" +
-            "// Then use it in your component:\n" +
-            "public class ToggleComponent : Component {\n" +
-            "    private ToggleStore store = inject<ToggleStore>();  // Inject singleton\n\n" +
-            "    public override string markup { get {\n" +
-            "        return \"\"\"\n" +
-            "        <div sid=\"toggle\" class=\"toggle-container\">\n" +
-            "            <span sid=\"status\" class=\"status\"></span>\n" +
-            "            <button sid=\"btn\" spry-action=\":Toggle\" spry-target=\"toggle\">\n" +
-            "            </button>\n" +
-            "        </div>\n" +
-            "        \"\"\";\n" +
-            "    }}\n\n" +
-            "    public override void prepare() throws Error {\n" +
-            "        // Read state from store\n" +
-            "        this[\"status\"].text_content = store.is_on ? \"ON\" : \"OFF\";\n" +
-            "        this[\"btn\"].text_content = store.is_on ? \"Turn Off\" : \"Turn On\";\n" +
-            "    }\n\n" +
-            "    public async override void handle_action(string action) throws Error {\n" +
-            "        if (action == \"Toggle\") {\n" +
-            "            // Modify state in the store - this persists!\n" +
-            "            store.toggle();\n" +
-            "        }\n" +
-            "    }\n" +
-            "}";
-        
-        // Set up the counter demo
-        var demo = get_component_child<DemoHostComponent>("counter-demo");
-        demo.demo_component_name = "SimpleCounterDemo";
-        demo.source_file = "demo/DemoComponents/SimpleCounterDemo.vala";
-    }
-}

+ 0 - 268
demo/Pages/ComponentsContinuationsPage.vala

@@ -1,268 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * ComponentsContinuationsPage - Documentation for Spry continuations (SSE)
- * 
- * This page covers what continuations are, the spry-continuation attribute,
- * and how to send real-time updates to clients.
- */
-public class ComponentsContinuationsPage : PageComponent {
-    
-    public override string title { get { return "Continuations - Spry"; } }
-    
-    public const string ROUTE = "/components/continuations";
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <div sid="page" class="doc-content">
-            <h1>Continuations</h1>
-            
-            <section class="doc-section">
-                <p>
-                    Continuations enable real-time updates from server to client using Server-Sent Events (SSE).
-                    They're perfect for progress indicators, live status updates, and any scenario where
-                    the server needs to push updates to the client over time.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>What are Continuations?</h2>
-                <p>
-                    A continuation is a long-running server process that can send multiple updates
-                    to the client over a single HTTP connection. Unlike regular requests that return
-                    once, continuations can push updates as they happen.
-                </p>
-                
-                <div class="info-box">
-                    <p>
-                        <strong>💡 Use Cases:</strong> Progress bars, build status, live logs,
-                        real-time notifications, file upload progress, long-running task monitoring.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>The <code>spry-continuation</code> Attribute</h2>
-                <p>
-                    Add <code>spry-continuation</code> to an element to enable SSE for its children.
-                    This attribute is shorthand for:
-                </p>
-                <ul>
-                    <li><code>hx-ext="sse"</code> - Enable HTMX SSE extension</li>
-                    <li><code>sse-connect="(auto-endpoint)"</code> - Connect to SSE endpoint</li>
-                    <li><code>sse-close="_spry-close"</code> - Close event name</li>
-                </ul>
-                
-                <spry-component name="CodeBlockComponent" sid="continuation-attr"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>The <code>spry-dynamic</code> Attribute</h2>
-                <p>
-                    Mark child elements with <code>spry-dynamic="name"</code> to make them updatable.
-                    When you call <code>send_dynamic("name")</code>, that element's HTML is sent to
-                    the client and swapped in place.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="dynamic-attr"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>The <code>continuation()</code> Method</h2>
-                <p>
-                    Override <code>continuation(ContinuationContext context)</code> in your component
-                    to implement long-running processes that send updates.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="continuation-method"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>ContinuationContext API</h2>
-                <p>
-                    The <code>ContinuationContext</code> parameter provides methods for sending updates:
-                </p>
-                
-                <table class="doc-table">
-                    <thead>
-                        <tr>
-                            <th>Method</th>
-                            <th>Description</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        <tr>
-                            <td><code>send_dynamic(name)</code></td>
-                            <td>Send a dynamic section (by spry-dynamic name) as an SSE event</td>
-                        </tr>
-                        <tr>
-                            <td><code>send_json(event_type, node)</code></td>
-                            <td>Send JSON data as an SSE event</td>
-                        </tr>
-                        <tr>
-                            <td><code>send_string(event_type, data)</code></td>
-                            <td>Send raw string data as an SSE event</td>
-                        </tr>
-                        <tr>
-                            <td><code>send_full_update(event_type)</code></td>
-                            <td>Send the entire component document</td>
-                        </tr>
-                        <tr>
-                            <td><code>send_event(event)</code></td>
-                            <td>Send a custom SseEvent</td>
-                        </tr>
-                    </tbody>
-                </table>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Required Scripts</h2>
-                <p>
-                    Include the HTMX SSE extension in your page for continuations to work:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="scripts"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>The <code>spry-unique</code> Attribute</h2>
-                <p>
-                    Use <code>spry-unique</code> on elements that need stable IDs for targeting.
-                    Spry generates unique IDs automatically.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="unique-attr"/>
-                
-                <div class="warning-box">
-                    <p>
-                        <strong>⚠️ Restrictions:</strong> Cannot use <code>spry-unique</code> with an
-                        explicit <code>id</code> attribute, or inside <code>spry-per-*</code> loops.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Cancellation Handling</h2>
-                <p>
-                    Override <code>continuation_canceled()</code> to clean up resources when the
-                    client disconnects:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="canceled-method"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Live Demo: Progress Bar</h2>
-                <p>
-                    This demo shows a progress bar that updates in real-time using SSE.
-                    Click "Start Task" to see continuations in action!
-                </p>
-                
-                <spry-component name="DemoHostComponent" sid="progress-demo"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Next Steps</h2>
-                <div class="nav-cards">
-                    <a href="/page-components/overview" class="nav-card">
-                        <h3>Page Components →</h3>
-                        <p>Learn about page-level components</p>
-                    </a>
-                    <a href="/components/outlets" class="nav-card">
-                        <h3>Outlets ←</h3>
-                        <p>Component composition</p>
-                    </a>
-                    <a href="/components/actions" class="nav-card">
-                        <h3>Actions ←</h3>
-                        <p>Handle user interactions</p>
-                    </a>
-                </div>
-            </section>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // spry-continuation attribute example
-        var continuation_attr = get_component_child<CodeBlockComponent>("continuation-attr");
-        continuation_attr.language = "HTML";
-        continuation_attr.code = "<div spry-continuation>\n" +
-            "    <!-- Children can receive SSE updates -->\n" +
-            "    <div spry-dynamic=\"progress-bar\">\n" +
-            "        <div class=\"progress-bar\" style-width-expr='format(\"{{this.percent}}%\")'>\n" +
-            "        </div>\n" +
-            "    </div>\n" +
-            "    <div spry-dynamic=\"status\">\n" +
-            "        <strong>Status:</strong> <span spry-unique content-expr=\"this.status\">Ready</span>\n" +
-            "    </div>\n" +
-            "</div>";
-        
-        // spry-dynamic attribute example
-        var dynamic_attr = get_component_child<CodeBlockComponent>("dynamic-attr");
-        dynamic_attr.language = "HTML";
-        dynamic_attr.code = "<!-- spry-dynamic marks elements for SSE swapping -->\n" +
-            "<div class=\"progress-container\" spry-dynamic=\"progress-bar\">\n" +
-            "    <div class=\"progress-bar\">...</div>\n" +
-            "</div>\n\n" +
-            "<div class=\"status\" spry-dynamic=\"status\">\n" +
-            "    <strong>Status:</strong> <span>Processing...</span>\n" +
-            "</div>\n\n" +
-            "<!-- Automatically gets: sse-swap=\"_spry-dynamic-{name}\" hx-swap=\"outerHTML\" -->";
-        
-        // continuation() method example
-        var continuation_method = get_component_child<CodeBlockComponent>("continuation-method");
-        continuation_method.language = "Vala";
-        continuation_method.code = "public async override void continuation(ContinuationContext ctx) throws Error {\n" +
-            "    for (int i = 0; i <= 100; i += 10) {\n" +
-            "        percent = i;\n" +
-            "        status = @\"Processing... $(i)%\";\n\n" +
-            "        // Send dynamic section updates to the client\n" +
-            "        yield ctx.send_dynamic(\"progress-bar\");\n" +
-            "        yield ctx.send_dynamic(\"status\");\n\n" +
-            "        // Simulate async work\n" +
-            "        Timeout.add(500, () => {\n" +
-            "            continuation.callback();\n" +
-            "            return false;\n" +
-            "        });\n" +
-            "        yield;\n" +
-            "    }\n\n" +
-            "    status = \"Complete!\";\n" +
-            "    yield ctx.send_dynamic(\"status\");\n" +
-            "}";
-        
-        // Required scripts example
-        var scripts = get_component_child<CodeBlockComponent>("scripts");
-        scripts.language = "HTML";
-        scripts.code = "<!-- In your page template or component -->\n" +
-            "<script spry-res=\"htmx.js\"></script>\n" +
-            "<script spry-res=\"htmx-sse.js\"></script>";
-        
-        // spry-unique attribute example
-        var unique_attr = get_component_child<CodeBlockComponent>("unique-attr");
-        unique_attr.language = "HTML";
-        unique_attr.code = "<!-- spry-unique generates a stable unique ID -->\n" +
-            "<div class=\"progress-bar\" spry-unique>\n" +
-            "    <!-- Gets ID like: _spry-unique-0-abc123 -->\n" +
-            "</div>\n\n" +
-            "<!-- Use with content-expr for dynamic content -->\n" +
-            "<span spry-unique content-expr=\"this.status\">Loading...</span>";
-        
-        // continuation_canceled example
-        var canceled_method = get_component_child<CodeBlockComponent>("canceled-method");
-        canceled_method.language = "Vala";
-        canceled_method.code = "public async override void continuation_canceled() throws Error {\n" +
-            "    // Client disconnected - clean up resources\n" +
-            "    cancel_background_task();\n" +
-            "    release_file_handles();\n" +
-            "    log_message(\"Task canceled by client\");\n" +
-            "}";
-        
-        // Set up the demo host
-        var demo = get_component_child<DemoHostComponent>("progress-demo");
-        demo.demo_component_name = "ProgressDemo";
-        demo.source_file = "demo/DemoComponents/ProgressDemo.vala";
-    }
-}

+ 0 - 393
demo/Pages/ComponentsMkconstPage.vala

@@ -1,393 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * ComponentsMkconstPage - Documentation for the spry-mkconst tool
- * 
- * This page explains how to use spry-mkconst to convert HTML files
- * to Vala string constants that can be referenced in component markup properties.
- */
-public class ComponentsMkconstPage : PageComponent {
-    
-    public override string title { get { return "spry-mkconst Tool - Spry"; } }
-    
-    public const string ROUTE = "/components/spry-mkconst";
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <div sid="page" class="doc-content">
-            <h1>spry-mkconst Tool</h1>
-            
-            <section class="doc-section">
-                <h2>What is spry-mkconst?</h2>
-                <p>
-                    <code>spry-mkconst</code> is a command-line tool that converts file contents
-                    (typically HTML templates) into Vala string constants. This allows you to:
-                </p>
-                <ul>
-                    <li>Keep HTML templates in separate files for easier editing</li>
-                    <li>Maintain valid Vala syntax that the Vala language server can recognize</li>
-                    <li>Reference generated constants from your component's <code>markup</code> property</li>
-                </ul>
-                <p>
-                    Unlike the previous <code>spry-mkcomponent</code> approach which modified Vala files,
-                    <code>spry-mkconst</code> generates separate constant declarations, keeping your
-                    original Vala files intact and recognizable by IDEs and language servers.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Command-Line Usage</h2>
-                
-                <spry-component name="CodeBlockComponent" sid="usage-code"/>
-                
-                <h3>Options</h3>
-                <table class="doc-table">
-                    <thead>
-                        <tr>
-                            <th>Option</th>
-                            <th>Description</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        <tr>
-                            <td><code>-o, --output FILE</code></td>
-                            <td>Output file path (default: stdout)</td>
-                        </tr>
-                        <tr>
-                            <td><code>--ns NAMESPACE</code></td>
-                            <td>Wrap const in a namespace</td>
-                        </tr>
-                        <tr>
-                            <td><code>-n, --name NAME</code></td>
-                            <td>Override const name (default: derived from filename)</td>
-                        </tr>
-                        <tr>
-                            <td><code>-v, --version</code></td>
-                            <td>Show version information</td>
-                        </tr>
-                        <tr>
-                            <td><code>--help</code></td>
-                            <td>Show help message</td>
-                        </tr>
-                    </tbody>
-                </table>
-            </section>
-            
-            <section class="doc-section">
-                <h2>How It Works</h2>
-                <p>
-                    The tool takes a single input file and generates a Vala const declaration:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="workflow-diagram"/>
-                
-                <div class="info-box">
-                    <p>
-                        <strong>💡 Key Concept:</strong> The const name is automatically derived from the
-                        filename using CAPITAL_SNAKE_CASE. For example, <code>UserContentComponent.vala.html</code>
-                        becomes <code>USER_CONTENT_COMPONENT_VALA_HTML</code>.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Example Transformation</h2>
-                <p>
-                    Here's a complete example showing how the tool works:
-                </p>
-                
-                <h3>Input HTML File (<code>UserContentComponent.vala.html</code>)</h3>
-                <spry-component name="CodeBlockComponent" sid="input-html"/>
-                
-                <h3>Generated Output (stdout or file)</h3>
-                <spry-component name="CodeBlockComponent" sid="output-const"/>
-                
-                <h3>Your Vala Component (unchanged, valid Vala)</h3>
-                <spry-component name="CodeBlockComponent" sid="vala-component"/>
-                
-                <p>
-                    The key advantage is that your Vala file remains valid, parseable Vala code.
-                    The Vala language server can still recognize it, provide autocomplete, and
-                    show errors. The generated constant is referenced via <code>return USER_CONTENT_COMPONENT_VALA_HTML;</code>
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Integrating with Meson</h2>
-                <p>
-                    The recommended way to use spry-mkconst is with meson's build system.
-                    You generate a separate Vala file containing the const declarations,
-                    then include it in your build.
-                </p>
-                
-                <h3>Basic meson.build Setup</h3>
-                <spry-component name="CodeBlockComponent" sid="meson-basic"/>
-                
-                <h3>With Namespace</h3>
-                <spry-component name="CodeBlockComponent" sid="meson-namespace"/>
-                
-                <h3>Complete Example</h3>
-                <spry-component name="CodeBlockComponent" sid="meson-complete"/>
-                
-                <div class="info-box">
-                    <p>
-                        <strong>💡 Tip:</strong> The generated file should be included in your
-                        executable's sources. Meson will run spry-mkconst automatically before
-                        compilation.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>HTML Template Guidelines</h2>
-                <p>
-                    When creating HTML templates for use with spry-mkconst, follow these guidelines:
-                </p>
-                
-                <ul>
-                    <li>
-                        <strong>Use <code>sid</code> attributes</strong> - Add <code>sid="name"</code>
-                        to elements you need to access from Vala code via <code>this["name"]</code>
-                    </li>
-                    <li>
-                        <strong>Name templates consistently</strong> - Use <code>ComponentName.vala.html</code>
-                        for clear association with the component
-                    </li>
-                    <li>
-                        <strong>Use HTMX attributes</strong> - Add <code>hx-*</code> attributes for
-                        interactivity without writing JavaScript
-                    </li>
-                    <li>
-                        <strong>Avoid complex logic</strong> - Keep templates focused on structure;
-                        use Vala for conditional rendering
-                    </li>
-                </ul>
-                
-                <spry-component name="CodeBlockComponent" sid="html-guidelines"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Why spry-mkconst vs spry-mkcomponent?</h2>
-                <p>
-                    The previous <code>spry-mkcomponent</code> tool modified Vala source files by
-                    injecting HTML into the markup getter. This had a significant drawback:
-                    the Vala language server couldn't recognize the modified files as valid Vala
-                    during development.
-                </p>
-                
-                <p>
-                    <code>spry-mkconst</code> solves this by:
-                </p>
-                
-                <ul>
-                    <li>Keeping your Vala files as valid, parseable Vala code</li>
-                    <li>Generating constants in a separate file that's included at build time</li>
-                    <li>Allowing the language server to provide full IDE support</li>
-                    <li>Using <code>public override string markup { get { return CONSTANT_NAME; } }</code>
-                        which is valid Vala syntax</li>
-                </ul>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Workflow Integration</h2>
-                <p>
-                    A typical development workflow with spry-mkconst looks like this:
-                </p>
-                
-                <ol>
-                    <li><strong>Create</strong> your HTML template file (e.g., <code>MyComponent.vala.html</code>)</li>
-                    <li><strong>Write</strong> your Vala component referencing the generated constant name</li>
-                    <li><strong>Configure</strong> meson to generate the const file</li>
-                    <li><strong>Build</strong> your project - meson runs spry-mkconst automatically</li>
-                    <li><strong>Iterate</strong> - Edit the HTML file; changes are picked up on rebuild</li>
-                </ol>
-                
-                <p>
-                    During development, you can run the tool manually to see the generated output:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="manual-run"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>When to Use spry-mkconst</h2>
-                
-                <h3>✅ Good Use Cases</h3>
-                <ul>
-                    <li>Components with substantial HTML markup</li>
-                    <li>When you need Vala language server support (autocomplete, errors)</li>
-                    <li>Teams where designers work on HTML separately from developers</li>
-                    <li>Keeping Vala files focused on logic</li>
-                </ul>
-                
-                <h3>❌ When to Skip It</h3>
-                <ul>
-                    <li>Simple components with minimal markup (inline is fine)</li>
-                    <li>Quick prototypes where separation isn't beneficial</li>
-                    <li>Components with dynamically generated markup</li>
-                </ul>
-                
-                <div class="info-box">
-                    <p>
-                        <strong>💡 Remember:</strong> You can always inline markup directly in your
-                        Vala files using triple-quoted strings. spry-mkconst is opt-in - use it
-                        when the separation provides value for your project.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Next Steps</h2>
-                <div class="nav-cards">
-                    <a href="/components/template-syntax" class="nav-card">
-                        <h3>← Template Syntax</h3>
-                        <p>Learn about component template syntax</p>
-                    </a>
-                    <a href="/components/actions" class="nav-card">
-                        <h3>Actions →</h3>
-                        <p>Handle user interactions in components</p>
-                    </a>
-                </div>
-            </section>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        var usage_code = get_component_child<CodeBlockComponent>("usage-code");
-        usage_code.language = "Bash";
-        usage_code.code = "spry-mkconst [OPTIONS] <INPUT_FILE>\n\n" +
-            "# Examples:\n" +
-            "spry-mkconst Templates/UserContent.html\n" +
-            "spry-mkconst -o generated/constants.vala Templates/UserContent.html\n" +
-            "spry-mkconst --ns MyApp.Templates Templates/UserContent.html\n" +
-            "spry-mkconst -n CUSTOM_NAME Templates/UserContent.html";
-        
-        var workflow_diagram = get_component_child<CodeBlockComponent>("workflow-diagram");
-        workflow_diagram.language = "Text";
-        workflow_diagram.code = "┌─────────────────────────────────────┐\n" +
-            "│   UserContentComponent.vala.html   │\n" +
-            "│   (HTML template)                  │\n" +
-            "└─────────────┬───────────────────────┘\n" +
-            "              │\n" +
-            "              ▼\n" +
-            "        ┌───────────────┐\n" +
-            "        │ spry-mkconst  │\n" +
-            "        └───────┬───────┘\n" +
-            "                │\n" +
-            "                ▼\n" +
-            "┌─────────────────────────────────────────────────┐\n" +
-            "│ const string USER_CONTENT_COMPONENT_VALA_HTML   │\n" +
-            "│     = \"\"\"<html>...</html>\"\"\";                   │\n" +
-            "└─────────────────────────────────────────────────┘";
-        
-        var input_html = get_component_child<CodeBlockComponent>("input-html");
-        input_html.language = "HTML";
-        input_html.code = "<p>You said: <strong sid=\"message\"></strong> <em>(via <span sid=\"action\"></span>)</em></p>";
-        
-        var output_const = get_component_child<CodeBlockComponent>("output-const");
-        output_const.language = "Vala";
-        output_const.code = "const string USER_CONTENT_COMPONENT_VALA_HTML = \"\"\"\n" +
-            "<p>You said: <strong sid=\"message\"></strong> <em>(via <span sid=\"action\"></span>)</em></p>\n" +
-            "\"\"\";";
-        
-        var vala_component = get_component_child<CodeBlockComponent>("vala-component");
-        vala_component.language = "Vala";
-        vala_component.code = "// This file is valid Vala - the language server recognizes it!\n" +
-            "class UserContentComponent : Component {\n" +
-            "    public override string markup { get { return USER_CONTENT_COMPONENT_VALA_HTML; } }\n\n" +
-            "    public async override void handle_action(string action) throws Error {\n" +
-            "        this[\"message\"].text_content = \"Hello, World!\";\n" +
-            "    }\n" +
-            "}";
-        
-        var meson_basic = get_component_child<CodeBlockComponent>("meson-basic");
-        meson_basic.language = "Meson";
-        meson_basic.code = "# Find the tool\n" +
-            "spry_mkconst = find_program('spry-mkconst')\n\n" +
-            "# Generate constants from HTML templates\n" +
-            "markup_constants = custom_target('markup-constants',\n" +
-            "    input: 'Templates/UserContentComponent.vala.html',\n" +
-            "    output: 'UserContentConstants.vala',\n" +
-            "    command: [spry_mkconst, '@INPUT@', '-o', '@OUTPUT@']\n" +
-            ")\n\n" +
-            "# Include in your executable\n" +
-            "executable('myapp',\n" +
-            "    sources: ['Main.vala', 'UserContentComponent.vala', markup_constants],\n" +
-            "    dependencies: [spry_dep]\n" +
-            ")";
-        
-        var meson_namespace = get_component_child<CodeBlockComponent>("meson-namespace");
-        meson_namespace.language = "Meson";
-        meson_namespace.code = "# Generate constants with namespace\n" +
-            "spry_mkconst = find_program('spry-mkconst')\n\n" +
-            "markup_constants = custom_target('markup-constants',\n" +
-            "    input: 'Templates/UserContentComponent.vala.html',\n" +
-            "    output: 'UserContentConstants.vala',\n" +
-            "    command: [spry_mkconst, '@INPUT@', '-o', '@OUTPUT@',\n" +
-            "              '--ns', 'MyApp.Markup']\n" +
-            ")\n\n" +
-            "# In your Vala file, use:\n" +
-            "# public override string markup { get { return MyApp.Markup.USER_CONTENT_COMPONENT_VALA_HTML; } }";
-        
-        var meson_complete = get_component_child<CodeBlockComponent>("meson-complete");
-        meson_complete.language = "Meson";
-        meson_complete.code = "# Find the spry-mkconst tool\n" +
-            "spry_mkconst = find_program('spry-mkconst')\n\n" +
-            "# Collect all HTML template files\n" +
-            "template_files = files(\n" +
-            "    'Templates/HeaderComponent.vala.html',\n" +
-            "    'Templates/FooterComponent.vala.html',\n" +
-            "    'Templates/UserContentComponent.vala.html',\n" +
-            ")\n\n" +
-            "# Generate a single constants file from all templates\n" +
-            "# Note: You can also generate separate files per template\n" +
-            "markup_constants = custom_target('markup-constants',\n" +
-            "    input: template_files,\n" +
-            "    output: 'MarkupConstants.vala',\n" +
-            "    command: [spry_mkconst, '@INPUT@', '-o', '@OUTPUT@', '--ns', 'Markup']\n" +
-            ")\n\n" +
-            "# Component source files (reference the constants)\n" +
-            "component_sources = files(\n" +
-            "    'Components/HeaderComponent.vala',\n" +
-            "    'Components/FooterComponent.vala',\n" +
-            "    'Components/UserContentComponent.vala',\n" +
-            ")\n\n" +
-            "# Build executable\n" +
-            "executable('myapp',\n" +
-            "    sources: ['Main.vala', component_sources, markup_constants],\n" +
-            "    dependencies: [spry_dep],\n" +
-            ")";
-        
-        var html_guidelines = get_component_child<CodeBlockComponent>("html-guidelines");
-        html_guidelines.language = "HTML";
-        html_guidelines.code = "<!-- Good: Use sid attributes for elements you need to access -->\n" +
-            "<div class=\"user-card\">\n" +
-            "    <h2 sid=\"username\"></h2>\n" +
-            "    <p sid=\"email\"></p>\n" +
-            "    <button sid=\"delete-btn\" hx-post=\"/delete\" hx-target=\"closest .user-card\">\n" +
-            "        Delete\n" +
-            "    </button>\n" +
-            "</div>\n\n" +
-            "<!-- Good: Keep it simple and focused on structure -->\n" +
-            "<form sid=\"login-form\" hx-post=\"/login\">\n" +
-            "    <input type=\"text\" name=\"username\" sid=\"username-input\"/>\n" +
-            "    <input type=\"password\" name=\"password\" sid=\"password-input\"/>\n" +
-            "    <button type=\"submit\">Login</button>\n" +
-            "</form>";
-        
-        var manual_run = get_component_child<CodeBlockComponent>("manual-run");
-        manual_run.language = "Bash";
-        manual_run.code = "# Run manually to see generated output\n" +
-            "spry-mkconst Templates/MyComponent.vala.html\n\n" +
-            "# Save to a file\n" +
-            "spry-mkconst Templates/MyComponent.vala.html -o generated/MyComponentMarkup.vala\n\n" +
-            "# View the result\n" +
-            "cat generated/MyComponentMarkup.vala\n\n" +
-            "# Generate with namespace\n" +
-            "spry-mkconst Templates/MyComponent.vala.html --ns MyApp.Templates";
-    }
-}

+ 0 - 270
demo/Pages/ComponentsOutletsPage.vala

@@ -1,270 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * ComponentsOutletsPage - Documentation for Spry outlets
- * 
- * This page covers what outlets are, how to use them for component
- * composition, and the parent/child component pattern.
- */
-public class ComponentsOutletsPage : PageComponent {
-    
-    public override string title { get { return "Outlets - Spry"; } }
-    
-    public const string ROUTE = "/components/outlets";
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <div sid="page" class="doc-content">
-            <h1>Outlets</h1>
-            
-            <section class="doc-section">
-                <p>
-                    Outlets are placeholders in your component templates where child components
-                    can be dynamically inserted. They enable powerful component composition
-                    patterns, especially for lists and dynamic content.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>What are Outlets?</h2>
-                <p>
-                    An outlet is a special element in your markup that acts as a insertion point
-                    for child components. Think of it like a socket where you can plug in
-                    different components at runtime.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="outlet-syntax"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Using <code>set_outlet_children()</code></h2>
-                <p>
-                    The <code>set_outlet_children(sid, children)</code> method populates an outlet
-                    with child components. Call it in your <code>prepare()</code> method after
-                    creating child components with the ComponentFactory.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="set-outlet-vala"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Parent/Child Component Pattern</h2>
-                <p>
-                    The typical pattern for outlets involves:
-                </p>
-                <ol>
-                    <li>A <strong>parent component</strong> with an outlet and a method to set children</li>
-                    <li>A <strong>child component</strong> that displays individual items</li>
-                    <li>A <strong>store</strong> that holds the data</li>
-                </ol>
-                
-                <h3>Parent Component</h3>
-                <spry-component name="CodeBlockComponent" sid="parent-component"/>
-                
-                <h3>Child Component</h3>
-                <spry-component name="CodeBlockComponent" sid="child-component"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Creating Lists with Outlets</h2>
-                <p>
-                    Outlets are perfect for rendering dynamic lists. Here's the complete pattern:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="list-pattern"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Outlets vs <code>&lt;spry-component&gt;</code></h2>
-                <p>
-                    When should you use outlets vs declarative child components?
-                </p>
-                
-                <table class="doc-table">
-                    <thead>
-                        <tr>
-                            <th>Feature</th>
-                            <th><code>&lt;spry-outlet&gt;</code></th>
-                            <th><code>&lt;spry-component&gt;</code></th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        <tr>
-                            <td>Use Case</td>
-                            <td>Dynamic lists, multiple items</td>
-                            <td>Single, known child components</td>
-                        </tr>
-                        <tr>
-                            <td>Population</td>
-                            <td><code>set_outlet_children()</code> in prepare()</td>
-                            <td>Automatic, configured via properties</td>
-                        </tr>
-                        <tr>
-                            <td>Access</td>
-                            <td>Not directly accessible</td>
-                            <td><code>get_component_child<T>()</code></td>
-                        </tr>
-                        <tr>
-                            <td>Examples</td>
-                            <td>Todo lists, data tables, feeds</td>
-                            <td>Headers, sidebars, fixed sections</td>
-                        </tr>
-                    </tbody>
-                </table>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Live Demo: Todo List</h2>
-                <p>
-                    This interactive demo shows outlets in action. The todo list uses an outlet
-                    to render individual todo items. Try adding, toggling, and deleting items!
-                </p>
-                
-                <spry-component name="DemoHostComponent" sid="todo-demo"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Next Steps</h2>
-                <div class="nav-cards">
-                    <a href="/components/continuations" class="nav-card">
-                        <h3>Continuations →</h3>
-                        <p>Real-time updates with SSE</p>
-                    </a>
-                    <a href="/components/actions" class="nav-card">
-                        <h3>Actions ←</h3>
-                        <p>Handle user interactions</p>
-                    </a>
-                    <a href="/components/template-syntax" class="nav-card">
-                        <h3>Template Syntax ←</h3>
-                        <p>Review template attributes</p>
-                    </a>
-                </div>
-            </section>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Outlet syntax example
-        var outlet_syntax = get_component_child<CodeBlockComponent>("outlet-syntax");
-        outlet_syntax.language = "HTML";
-        outlet_syntax.code = "<div sid=\"list\">\n" +
-            "    <!-- This outlet will be filled with child components -->\n" +
-            "    <spry-outlet sid=\"items\"/>\n" +
-            "</div>";
-        
-        // set_outlet_children example
-        var set_outlet_vala = get_component_child<CodeBlockComponent>("set-outlet-vala");
-        set_outlet_vala.language = "Vala";
-        set_outlet_vala.code = "public override async void prepare() throws Error {\n" +
-            "    var factory = inject<ComponentFactory>();\n" +
-            "    var store = inject<TodoStore>();\n\n" +
-            "    // Create child components for each item\n" +
-            "    var children = new Series<Renderable>();\n" +
-            "    foreach (var item in store.items) {\n" +
-            "        var component = factory.create<TodoItemComponent>();\n" +
-            "        component.item_id = item.id;  // Pass data to child\n" +
-            "        children.add(component);\n" +
-            "    }\n\n" +
-            "    // Populate the outlet\n" +
-            "    set_outlet_children(\"items\", children);\n" +
-            "}";
-        
-        // Parent component example
-        var parent_component = get_component_child<CodeBlockComponent>("parent-component");
-        parent_component.language = "Vala";
-        parent_component.code = "public class TodoListComponent : Component {\n" +
-            "    private TodoStore store = inject<TodoStore>();\n" +
-            "    private ComponentFactory factory = inject<ComponentFactory>();\n\n" +
-            "    public override string markup { get {\n" +
-            "        return \"\"\"\n" +
-            "        <div sid=\"list\" class=\"todo-list\">\n" +
-            "            <ul sid=\"items\">\n" +
-            "                <spry-outlet sid=\"items-outlet\"/>\n" +
-            "            </ul>\n" +
-            "        </div>\n" +
-            "        \"\"\";\n" +
-            "    }}\n\n" +
-            "    public override async void prepare() throws Error {\n" +
-            "        var children = new Series<Renderable>();\n" +
-            "        foreach (var item in store.items) {\n" +
-            "            var component = factory.create<TodoItemComponent>();\n" +
-            "            component.item_id = item.id;\n" +
-            "            children.add(component);\n" +
-            "        }\n" +
-            "        set_outlet_children(\"items-outlet\", children);\n" +
-            "    }\n" +
-            "}";
-        
-        // Child component example
-        var child_component = get_component_child<CodeBlockComponent>("child-component");
-        child_component.language = "Vala";
-        child_component.code = "public class TodoItemComponent : Component {\n" +
-            "    private TodoStore store = inject<TodoStore>();\n" +
-            "    private HttpContext http_context = inject<HttpContext>();\n\n" +
-            "    public int item_id { get; set; }  // Set by parent\n\n" +
-            "    public override string markup { get {\n" +
-            "        return \"\"\"\n" +
-            "        <li sid=\"item\" class=\"todo-item\">\n" +
-            "            <span sid=\"title\"></span>\n" +
-            "            <button spry-action=\":Toggle\" spry-target=\"item\">Toggle</button>\n" +
-            "        </li>\n" +
-            "        \"\"\";\n" +
-            "    }}\n\n" +
-            "    public override void prepare() throws Error {\n" +
-            "        var item = store.get_by_id(item_id);\n" +
-            "        this[\"title\"].text_content = item.title;\n" +
-            "        // Pass item_id via hx-vals for handle_action\n" +
-            "        this[\"item\"].set_attribute(\"hx-vals\", @\"{\\\"id\\\":$item_id}\");\n" +
-            "    }\n\n" +
-            "    public async override void handle_action(string action) throws Error {\n" +
-            "        var id = int.parse(http_context.request.query_params.get_any_or_default(\"id\"));\n" +
-            "        if (action == \"Toggle\") {\n" +
-            "            store.toggle(id);\n" +
-            "        }\n" +
-            "    }\n" +
-            "}";
-        
-        // List pattern example
-        var list_pattern = get_component_child<CodeBlockComponent>("list-pattern");
-        list_pattern.language = "Vala";
-        list_pattern.code = "// 1. Define a store to hold data\n" +
-            "public class TodoStore : Object {\n" +
-            "    public Series<TodoItem> items { get; default = new Series<TodoItem>(); }\n\n" +
-            "    public void add(string title) { /* ... */ }\n" +
-            "    public void toggle(int id) { /* ... */ }\n" +
-            "    public void remove(int id) { /* ... */ }\n" +
-            "}\n\n" +
-            "// 2. Register as singleton\n" +
-            "application.add_singleton<TodoStore>();\n\n" +
-            "// 3. Parent component uses outlet\n" +
-            "public class TodoListComponent : Component {\n" +
-            "    private TodoStore store = inject<TodoStore>();\n\n" +
-            "    public override string markup { get {\n" +
-            "        return \"<ul><spry-outlet sid=\"items\"/></ul>\";\n" +
-            "    }}\n\n" +
-            "    public override async void prepare() throws Error {\n" +
-            "        var children = new Series<Renderable>();\n" +
-            "        foreach (var item in store.items) {\n" +
-            "            var child = factory.create<TodoItemComponent>();\n" +
-            "            child.item_id = item.id;\n" +
-            "            children.add(child);\n" +
-            "        }\n" +
-            "        set_outlet_children(\"items\", children);\n" +
-            "    }\n" +
-            "}\n\n" +
-            "// 4. Child component handles individual items\n" +
-            "public class TodoItemComponent : Component {\n" +
-            "    public int item_id { get; set; }\n" +
-            "    // ... markup and methods\n" +
-            "}";
-        
-        // Set up the demo host
-        var demo = get_component_child<DemoHostComponent>("todo-demo");
-        demo.demo_component_name = "TodoListDemo";
-        demo.source_file = "demo/DemoComponents/TodoListDemo.vala";
-    }
-}

+ 0 - 230
demo/Pages/ComponentsOverviewPage.vala

@@ -1,230 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * ComponentsOverviewPage - Introduction to Spry Components
- * 
- * This page provides a comprehensive overview of what Spry components are,
- * their lifecycle, key methods, and basic usage patterns.
- */
-public class ComponentsOverviewPage : PageComponent {
-    
-    public override string title { get { return "Components Overview - Spry"; } }
-    
-    public const string ROUTE = "/components/overview";
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <div sid="page" class="doc-content">
-            <h1>Components Overview</h1>
-            
-            <section class="doc-section">
-                <h2>What are Spry Components?</h2>
-                <p>
-                    Spry components are the building blocks of your web application. They combine
-                    HTML templates with behavior logic in a single, cohesive Vala class. Each component
-                    is self-contained with its own markup, state management, and action handling.
-                </p>
-                <p>
-                    Unlike traditional web frameworks where templates and logic are separated,
-                    Spry components embrace a component-based architecture where everything related
-                    to a UI element lives in one place.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Component Lifecycle</h2>
-                <p>
-                    Understanding the component lifecycle is crucial for building effective Spry applications.
-                    The template DOM is <strong>fresh on every request</strong>, meaning state is not
-                    persisted between requests.
-                </p>
-                
-                <div class="lifecycle-diagram">
-                    <div class="lifecycle-step">
-                        <div class="step-number">1</div>
-                        <div class="step-content">
-                            <h4>Component Creation</h4>
-                            <p>Component is instantiated via ComponentFactory</p>
-                        </div>
-                    </div>
-                    <div class="lifecycle-arrow">↓</div>
-                    <div class="lifecycle-step">
-                        <div class="step-number">2</div>
-                        <div class="step-content">
-                            <h4>prepare_once()</h4>
-                            <p>One-time initialization (called only before first prepare)</p>
-                        </div>
-                    </div>
-                    <div class="lifecycle-arrow">↓</div>
-                    <div class="lifecycle-step">
-                        <div class="step-number">3</div>
-                        <div class="step-content">
-                            <h4>prepare()</h4>
-                            <p>Fetch data from stores, populate template elements</p>
-                        </div>
-                    </div>
-                    <div class="lifecycle-arrow">↓</div>
-                    <div class="lifecycle-step">
-                        <div class="step-number">4</div>
-                        <div class="step-content">
-                            <h4>handle_action()</h4>
-                            <p>Handle user interactions (if action triggered)</p>
-                        </div>
-                    </div>
-                    <div class="lifecycle-arrow">↓</div>
-                    <div class="lifecycle-step">
-                        <div class="step-number">5</div>
-                        <div class="step-content">
-                            <h4>Serialization</h4>
-                            <p>Template is rendered to HTML and sent to client</p>
-                        </div>
-                    </div>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Key Methods</h2>
-                <p>
-                    Every component inherits from the base <code>Component</code> class and can
-                    override these key methods:
-                </p>
-                
-                <table class="doc-table">
-                    <thead>
-                        <tr>
-                            <th>Method</th>
-                            <th>Description</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        <tr>
-                            <td><code>markup</code></td>
-                            <td>Property returning the HTML template string with Spry attributes</td>
-                        </tr>
-                        <tr>
-                            <td><code>prepare()</code></td>
-                            <td>Called before serialization. Fetch data and populate template here.</td>
-                        </tr>
-                        <tr>
-                            <td><code>prepare_once()</code></td>
-                            <td>Called only once before the first prepare(). For one-time initialization.</td>
-                        </tr>
-                        <tr>
-                            <td><code>handle_action()</code></td>
-                            <td>Called when HTMX triggers an action. Modify state here.</td>
-                        </tr>
-                        <tr>
-                            <td><code>continuation()</code></td>
-                            <td>For real-time updates via Server-Sent Events (SSE).</td>
-                        </tr>
-                    </tbody>
-                </table>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Basic Component Example</h2>
-                <p>
-                    Here's a simple counter component demonstrating the core concepts:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="example-code"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Important: Template State is Not Persisted</h2>
-                <div class="warning-box">
-                    <p>
-                        <strong>⚠️ Critical Concept:</strong> The template DOM is fresh on every request.
-                        Any state set via setters (like <code>title</code>, <code>completed</code>) is
-                        NOT available in <code>handle_action()</code>.
-                    </p>
-                    <p>
-                        Always use <code>prepare()</code> to fetch data from stores and set up the template.
-                        To pass data to actions, use one of these approaches:
-                    </p>
-                </div>
-                
-                <div class="info-box">
-                    <h4>Option 1: spry-context (Recommended for Properties)</h4>
-                    <p>
-                        Use <code>&lt;spry-context property="name"/&gt;</code> to automatically preserve
-                        property values across requests.
-                    </p>
-                    <ul>
-                        <li>Properties are encrypted and included in action URLs automatically</li>
-                        <li>Values are restored to properties before <code>handle_action()</code> is called</li>
-                        <li>Example: <code>&lt;spry-context property="item_id"/&gt;</code></li>
-                    </ul>
-                </div>
-                
-                <div class="info-box">
-                    <h4>Option 2: hx-vals (Manual Query Parameters)</h4>
-                    <p>
-                        Use the <code>hx-vals</code> attribute to pass data as query parameters.
-                    </p>
-                    <ul>
-                        <li>Values are included in the request as query parameters</li>
-                        <li>Must be read manually via <code>http_context.request.query_params.get_any_or_default("key")</code></li>
-                        <li>Example: <code>hx-vals='{"id": "123"}'</code></li>
-                    </ul>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Next Steps</h2>
-                <div class="nav-cards">
-                    <a href="/components/template-syntax" class="nav-card">
-                        <h3>Template Syntax →</h3>
-                        <p>Learn about Spry's special HTML attributes</p>
-                    </a>
-                    <a href="/components/actions" class="nav-card">
-                        <h3>Actions →</h3>
-                        <p>Handle user interactions with actions</p>
-                    </a>
-                    <a href="/components/outlets" class="nav-card">
-                        <h3>Outlets →</h3>
-                        <p>Compose components with outlets</p>
-                    </a>
-                </div>
-            </section>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        var code = get_component_child<CodeBlockComponent>("example-code");
-        code.language = "Vala";
-        code.code = "using Spry;\n\n" +
-            "public class CounterComponent : Component {\n" +
-            "    private CounterStore store = inject<CounterStore>();\n\n" +
-            "    public override string markup { get {\n" +
-            "        return \"\"\"\n" +
-            "        <div sid=\"counter\" class=\"counter\">\n" +
-            "            <span sid=\"count\"></span>\n" +
-            "            <button sid=\"inc\" spry-action=\":Increment\"\n" +
-            "                    spry-target=\"counter\">+</button>\n" +
-            "            <button sid=\"dec\" spry-action=\":Decrement\"\n" +
-            "                    spry-target=\"counter\">-</button>\n" +
-            "        </div>\n" +
-            "        \"\"\";\n" +
-            "    }}\n\n" +
-            "    public override void prepare() throws Error {\n" +
-            "        this[\"count\"].text_content = store.count.to_string();\n" +
-            "    }\n\n" +
-            "    public async override void handle_action(string action) throws Error {\n" +
-            "        switch (action) {\n" +
-            "            case \"Increment\":\n" +
-            "                store.count++;\n" +
-            "                break;\n" +
-            "            case \"Decrement\":\n" +
-            "                store.count--;\n" +
-            "                break;\n" +
-            "        }\n" +
-            "        // prepare() is called automatically after handle_action()\n" +
-            "    }\n" +
-            "}";
-    }
-}

+ 0 - 372
demo/Pages/ComponentsTemplateSyntaxPage.vala

@@ -1,372 +0,0 @@
-using Spry;
-
-/**
- * ComponentsTemplateSyntaxPage - Documentation for Spry template syntax
- * 
- * This page covers all the special HTML attributes and elements used in
- * Spry component templates.
- */
-public class ComponentsTemplateSyntaxPage : PageComponent {
-    
-    public override string title { get { return "Template Syntax - Spry"; } }
-    
-    public const string ROUTE = "/components/template-syntax";
-    
-    public override string markup { get {
-        return """
-        <div sid="page" class="doc-content">
-            <h1>Template Syntax</h1>
-            
-            <section class="doc-section">
-                <p>
-                    Spry extends HTML with special attributes that enable reactive behavior,
-                    component composition, and dynamic content. This page covers all the
-                    template syntax available in Spry components.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Special Attributes</h2>
-                
-                <h3><code>sid</code> - Spry ID</h3>
-                <p>
-                    The <code>sid</code> attribute assigns a unique identifier to an element within
-                    a component. Use it to select and manipulate elements in your Vala code.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="sid-html"/>
-                <spry-component name="CodeBlockComponent" sid="sid-vala"/>
-            </section>
-            
-            <section class="doc-section">
-                <h3><code>spry-action</code> - HTMX Action Binding</h3>
-                <p>
-                    The <code>spry-action</code> attribute binds an element to trigger a component action
-                    when interacted with. The action is sent to the server via HTMX.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="action-example"/>
-                
-                <p>
-                    See the <a href="/components/actions">Actions</a> page for more details.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h3><code>spry-target</code> - Scoped Targeting</h3>
-                <p>
-                    The <code>spry-target</code> attribute specifies which element should be replaced
-                    when an action completes. It targets elements by their <code>sid</code> within the
-                    same component.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="target-example"/>
-            </section>
-            
-            <section class="doc-section">
-                <h3><code>spry-global</code> - Out-of-Band Swaps</h3>
-                <p>
-                    The <code>spry-global</code> attribute marks an element for out-of-band updates.
-                    When included in a response, HTMX will swap this element anywhere on the page
-                    that has a matching <code>id</code>.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="global-html"/>
-                <spry-component name="CodeBlockComponent" sid="global-vala"/>
-            </section>
-            
-            <section class="doc-section">
-                <h3><code>*-expr</code> - Expression Attributes</h3>
-                <p>
-                    Expression attributes dynamically set HTML attributes based on component properties.
-                    Use <code>content-expr</code> for text content, <code>class-*-expr</code> for
-                    conditional classes, and <code>any-attr-expr</code> for any other attribute.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="expr-example"/>
-            </section>
-            
-            <section class="doc-section">
-                <h3><code>spry-if</code> / <code>spry-else-if</code> / <code>spry-else</code> - Conditionals</h3>
-                <p>
-                    Use these attributes for conditional rendering. Only elements with truthy
-                    conditions will be included in the output.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="conditional-example"/>
-            </section>
-            
-            <section class="doc-section">
-                <h3><code>spry-per-*</code> - Loop Rendering</h3>
-                <p>
-                    Use <code>spry-per-{varname}="expression"</code> to iterate over collections.
-                    The variable name becomes available in nested expressions.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="loop-example"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Special Elements</h2>
-                
-                <h3><code>&lt;spry-outlet&gt;</code> - Child Component Outlets</h3>
-                <p>
-                    Outlets are placeholders where child components can be inserted dynamically.
-                    Use <code>set_outlet_children()</code> to populate outlets.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="outlet-example"/>
-                
-                <p>
-                    See the <a href="/components/outlets">Outlets</a> page for more details.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h3><code>&lt;spry-component&gt;</code> - Declarative Child Components</h3>
-                <p>
-                    Use <code>&lt;spry-component&gt;</code> to declare child components directly in
-                    your template. Access them with <code>get_component_child&lt;T&gt;()</code>.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="component-html"/>
-                <spry-component name="CodeBlockComponent" sid="component-vala"/>
-            </section>
-            
-            <section class="doc-section">
-                <h3><code>&lt;spry-content&gt;</code> - Parent-Specified Content</h3>
-                <p>
-                    The <code>&lt;spry-content&gt;</code> tag allows child components to define insertion points
-                    where parent components can inject content. When a parent uses <code>&lt;spry-component&gt;</code>
-                    with nested elements, those elements replace the <code>&lt;spry-content/&gt;</code> tag in the
-                    child component's rendered output.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="content-example"/>
-                
-                <h4>Use Cases</h4>
-                <p>
-                    This pattern is ideal for wrapper components that provide structure while allowing
-                    flexible content:
-                </p>
-                <ul>
-                    <li><strong>Cards</strong> - Wrap content in styled containers with headers/footers</li>
-                    <li><strong>Modals</strong> - Provide overlay structure with custom content</li>
-                    <li><strong>Alerts</strong> - Style messages with consistent formatting</li>
-                    <li><strong>Panels</strong> - Create collapsible or tabbed sections</li>
-                </ul>
-            </section>
-            
-            <section class="doc-section">
-                <h3><code>&lt;spry-context&gt;</code> - Context Property Preservation</h3>
-                <p>
-                    The <code>&lt;spry-context&gt;</code> tag marks a property to be preserved across
-                    action requests. When a component action is triggered, properties marked with this
-                    tag are encrypted and included in the action URL, then restored when the action
-                    is handled.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="context-example"/>
-                
-                <h4>How It Works</h4>
-                <ul>
-                    <li>Properties marked with <code>&lt;spry-context property="name"/&gt;</code> are tracked</li>
-                    <li>When an action is triggered, these properties are encrypted using <code>CryptographyProvider</code></li>
-                    <li>The encrypted context is included in the action URL</li>
-                    <li>The server decrypts and restores the properties before calling <code>handle_action()</code></li>
-                </ul>
-                
-                <div class="warning-box">
-                    <h4>⚠️ Security Warning: Replay Attacks</h4>
-                    <p>
-                        The encrypted context can be captured and replayed by malicious actors. While the
-                        data cannot be tampered with (it's cryptographically signed), an attacker could
-                        capture a valid request and replay it later.
-                    </p>
-                    <ul>
-                        <li><strong>Do not</strong> use context for sensitive data that could be exploited if replayed</li>
-                        <li><strong>Do not</strong> use context for authentication or authorization decisions</li>
-                        <li><strong>Consider</strong> adding timestamps or expiration for time-sensitive operations</li>
-                    </ul>
-                    <p>
-                        <strong>Example attack:</strong> If context contains admin privileges, an attacker
-                        could capture a request from an admin session and replay it to gain unauthorized access.
-                    </p>
-                </div>
-                
-                <h4>Best Practices</h4>
-                <ul>
-                    <li>Use context for non-sensitive data like IDs, flags, or UI configuration</li>
-                    <li>Validate context data on the server before using it</li>
-                    <li>Keep context data minimal - only include what's needed</li>
-                </ul>
-            </section>
-            
-            <section class="doc-section">
-                <h3><code>spry-res</code> - Static Resources</h3>
-                <p>
-                    Use <code>spry-res</code> to reference Spry's built-in static resources.
-                    This resolves to <code>/_spry/res/{resource-name}</code> automatically.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="res-example"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Next Steps</h2>
-                <div class="nav-cards">
-                    <a href="/components/actions" class="nav-card">
-                        <h3>Actions →</h3>
-                        <p>Handle user interactions with actions</p>
-                    </a>
-                    <a href="/components/outlets" class="nav-card">
-                        <h3>Outlets →</h3>
-                        <p>Compose components with outlets</p>
-                    </a>
-                    <a href="/components/continuations" class="nav-card">
-                        <h3>Continuations →</h3>
-                        <p>Real-time updates with SSE</p>
-                    </a>
-                </div>
-            </section>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // sid examples
-        var sid_html = get_component_child<CodeBlockComponent>("sid-html");
-        sid_html.language = "HTML";
-        sid_html.code = """<div sid="container">
-    <span sid="title">Hello</span>
-    <button sid="submit-btn">Submit</button>
-</div>""";
-        
-        var sid_vala = get_component_child<CodeBlockComponent>("sid-vala");
-        sid_vala.language = "Vala";
-        sid_vala.code = """// Access elements by sid in prepare() or handle_action()
-this["title"].text_content = "Updated Title";
-this["submit-btn"].set_attribute("disabled", "true");""";
-        
-        // spry-action example
-        var action_example = get_component_child<CodeBlockComponent>("action-example");
-        action_example.language = "HTML";
-        action_example.code = """<!-- Same-component action -->
-<button spry-action=":Toggle">Toggle</button>
-
-<!-- Cross-component action -->
-<button spry-action="ListComponent:Add">Add Item</button>""";
-        
-        // spry-target example
-        var target_example = get_component_child<CodeBlockComponent>("target-example");
-        target_example.language = "HTML";
-        target_example.code = """<div sid="item" class="item">
-    <span sid="title">Item Title</span>
-    <button spry-action=":Delete" spry-target="item">Delete</button>
-</div>""";
-        
-        // spry-global examples
-        var global_html = get_component_child<CodeBlockComponent>("global-html");
-        global_html.language = "HTML";
-        global_html.code = """<!-- In HeaderComponent -->
-<div id="header" spry-global="header">
-    <h1>Todo App</h1>
-    <span sid="count">0 items</span>
-</div>""";
-        
-        var global_vala = get_component_child<CodeBlockComponent>("global-vala");
-        global_vala.language = "Vala";
-        global_vala.code = """// In another component's handle_action()
-add_globals_from(header);  // Includes header in response for OOB swap""";
-        
-        // Expression attributes example
-        var expr_example = get_component_child<CodeBlockComponent>("expr-example");
-        expr_example.language = "HTML";
-        expr_example.code = """<!-- Content expression -->
-<span content-expr='format("{{this.percent}}%")'>0%</span>
-
-<!-- Style expression -->
-<div style-width-expr='format("{{this.percent}}%")'></div>
-
-<!-- Conditional class -->
-<div class-completed-expr="this.is_completed">Task</div>
-
-<!-- Any attribute expression -->
-<input disabled-expr="this.is_readonly">""";
-        
-        // Conditional example
-        var conditional_example = get_component_child<CodeBlockComponent>("conditional-example");
-        conditional_example.language = "HTML";
-        conditional_example.code = """<div spry-if="this.is_admin">Admin Panel</div>
-<div spry-else-if="this.is_moderator">Moderator Panel</div>
-<div spry-else>User Panel</div>""";
-        
-        // Loop example
-        var loop_example = get_component_child<CodeBlockComponent>("loop-example");
-        loop_example.language = "HTML";
-        loop_example.code = """<ul>
-    <li spry-per-task="this.tasks">
-        <span content-expr="task.name"></span>
-        <span content-expr="task.status"></span>
-    </li>
-</ul>""";
-        
-        // Outlet example
-        var outlet_example = get_component_child<CodeBlockComponent>("outlet-example");
-        outlet_example.language = "HTML";
-        outlet_example.code = """<div sid="list">
-    <spry-outlet sid="items"/>
-</div>""";
-        
-        // Component examples
-        var component_html = get_component_child<CodeBlockComponent>("component-html");
-        component_html.language = "HTML";
-        component_html.code = """<div>
-    <spry-component name="HeaderComponent" sid="header"/>
-    <spry-component name="TodoListComponent" sid="todo-list"/>
-    <spry-component name="FooterComponent" sid="footer"/>
-</div>""";
-        
-        var component_vala = get_component_child<CodeBlockComponent>("component-vala");
-        component_vala.language = "Vala";
-        component_vala.code = """public override async void prepare() throws Error {
-    var header = get_component_child<HeaderComponent>("header");
-    header.title = "My App";
-}""";
-        
-        // Content example
-        var content_example = get_component_child<CodeBlockComponent>("content-example");
-        content_example.language = "HTML";
-        content_example.code = """<!-- CardComponent template - defines where content goes -->
-<div class="card">
-    <h2>Card Title</h2>
-    <div class="card-body">
-        <spry-content/>  <!-- Parent's nested content appears here -->
-    </div>
-</div>
-
-<!-- Parent component using CardComponent with injected content -->
-<spry-component name="CardComponent" sid="my-card">
-    <p>This paragraph is injected into the card's spry-content area.</p>
-    <button spry-action=":DoSomething">Click me</button>
-</spry-component>""";
-        
-        // Context example
-        var context_example = get_component_child<CodeBlockComponent>("context-example");
-        context_example.language = "HTML";
-        context_example.code = """<!-- Mark properties to be preserved across actions -->
-<spry-context property="demo_component_name"/>
-<spry-context property="source_file"/>
-
-<div sid="host">
-    <span content-expr="this.demo_component_name">Demo</span>
-    <button spry-action=":ShowSource" spry-target="host">Show Source</button>
-</div>""";
-        
-        // Static resources example
-        var res_example = get_component_child<CodeBlockComponent>("res-example");
-        res_example.language = "HTML";
-        res_example.code = """<script spry-res="htmx.js"></script>
-<script spry-res="htmx-sse.js"></script>""";
-    }
-}

+ 0 - 120
demo/Pages/HomePage.vala

@@ -1,120 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * HomePage - Documentation landing page for the Spry framework
- * 
- * Clean, minimal design focused on helping developers get started
- * with Spry quickly.
- */
-public class HomePage : PageComponent {
-    
-    public override string title { get { return "Spry - A Component-Based Web Framework for Vala"; } }
-    
-    public const string ROUTE = "/";
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <div class="doc-content">
-            
-            <!-- Hero Section -->
-            <section class="home-hero">
-                <h1 class="hero-title">Spry</h1>
-                <p class="hero-tagline">A component-based web framework for Vala</p>
-            </section>
-            
-            <!-- Introduction -->
-            <section class="doc-section">
-                <p class="intro">
-                    Spry is a web framework that lets you build dynamic, interactive web applications
-                    using Vala. It features HTMX integration for reactive UIs, dependency injection
-                    for clean architecture, and a component model that keeps markup and logic together.
-                </p>
-                <p>
-                    Whether you're building a simple web service or a complex interactive application,
-                    Spry provides the tools you need with full type safety and native performance.
-                </p>
-            </section>
-            
-            <!-- Quick Links -->
-            <section class="doc-section">
-                <h2>Documentation</h2>
-                <div class="quick-links">
-                    <a href="/components/overview" class="quick-link-card">
-                        <h3>Components</h3>
-                        <p>Learn about Spry's component model, lifecycle, and how to build interactive UIs.</p>
-                    </a>
-                    <a href="/page-components/overview" class="quick-link-card">
-                        <h3>Page Components</h3>
-                        <p>Understand how to create pages and use templates for consistent layouts.</p>
-                    </a>
-                    <a href="/static-resources/overview" class="quick-link-card">
-                        <h3>Static Resources</h3>
-                        <p>Serve CSS, JavaScript, images, and other static assets efficiently.</p>
-                    </a>
-                </div>
-            </section>
-            
-            <!-- Get Started Code Example -->
-            <section class="doc-section">
-                <h2>Get Started</h2>
-                <p>
-                    Here's a minimal "Hello World" Spry application to get you started:
-                </p>
-                <spry-component name="CodeBlockComponent" sid="hello-code"/>
-            </section>
-            
-            <!-- Features -->
-            <section class="doc-section">
-                <h2>Why Spry?</h2>
-                <ul class="features-list">
-                    <li>
-                        <strong>Type-Safe</strong> — Full Vala type safety catches errors at compile time,
-                        not runtime.
-                    </li>
-                    <li>
-                        <strong>Component-Based</strong> — Build encapsulated, reusable components with
-                        markup and logic in one place.
-                    </li>
-                    <li>
-                        <strong>HTMX Integration</strong> — Create dynamic interfaces without writing
-                        JavaScript. HTMX handles the complexity.
-                    </li>
-                    <li>
-                        <strong>Dependency Injection</strong> — Clean architecture with Inversion of
-                        Control for services and stores.
-                    </li>
-                    <li>
-                        <strong>Native Performance</strong> — Compiled to native code for maximum
-                        throughput and minimal resource usage.
-                    </li>
-                    <li>
-                        <strong>Free & Open Source</strong> — Released under a permissive license,
-                        free to use for any project.
-                    </li>
-                </ul>
-            </section>
-            
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        var helloCode = get_component_child<CodeBlockComponent>("hello-code");
-        helloCode.language = "Vala";
-        helloCode.code = "public class HelloPage : PageComponent {\n" +
-        "    public override string markup { get {\n" +
-        "        return \"\"\"<!DOCTYPE html>\n" +
-        "<html>\n" +
-        "<body>\n" +
-        "    <h1>Hello, Spry!</h1>\n" +
-        "</body>\n" +
-        "</html>\"\"\";\n" +
-        "    }}\n" +
-        "}\n\n" +
-        "// In Main.vala\n" +
-        "spry_cfg.add_page<HelloPage>(new EndpointRoute(\"/\"));";
-    }
-}

+ 0 - 269
demo/Pages/PageComponentsOverviewPage.vala

@@ -1,269 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * PageComponentsOverviewPage - Introduction to PageComponent
- * 
- * This page explains what PageComponents are, how they differ from regular
- * Components, and when to use them.
- */
-public class PageComponentsOverviewPage : PageComponent {
-    
-    public override string title { get { return "Page Components - Spry"; } }
-    
-    public const string ROUTE = "/page-components/overview";
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <div class="doc-content">
-            <div class="doc-hero">
-                <h1>Page Components</h1>
-                <p class="doc-subtitle">Combine Component and Endpoint into a single powerful abstraction</p>
-            </div>
-            
-            <section class="doc-section">
-                <h2>What are Page Components?</h2>
-                <p>
-                    A <code>PageComponent</code> is a special type of component that acts as both a 
-                    <strong>Component</strong> AND an <strong>Endpoint</strong>. This means it can render
-                    HTML templates <em>and</em> handle HTTP requests at a specific route.
-                </p>
-                <p>
-                    In traditional web frameworks, you often need separate classes for routes/endpoints
-                    and for rendering views. PageComponent eliminates this duplication by combining
-                    both responsibilities into a single cohesive class.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>PageComponent vs Component</h2>
-                <p>
-                    Understanding when to use <code>PageComponent</code> vs <code>Component</code> is essential:
-                </p>
-                
-                <table class="doc-table">
-                    <thead>
-                        <tr>
-                            <th>Feature</th>
-                            <th>Component</th>
-                            <th>PageComponent</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        <tr>
-                            <td>Has markup</td>
-                            <td>✓ Yes</td>
-                            <td>✓ Yes</td>
-                        </tr>
-                        <tr>
-                            <td>Handles HTTP routes</td>
-                            <td>✗ No</td>
-                            <td>✓ Yes</td>
-                        </tr>
-                        <tr>
-                            <td>Can be nested in outlets</td>
-                            <td>✓ Yes</td>
-                            <td>✗ No (top-level only)</td>
-                        </tr>
-                        <tr>
-                            <td>Implements Endpoint</td>
-                            <td>✗ No</td>
-                            <td>✓ Yes</td>
-                        </tr>
-                        <tr>
-                            <td>Wrapped by templates</td>
-                            <td>✗ No</td>
-                            <td>✓ Yes</td>
-                        </tr>
-                    </tbody>
-                </table>
-            </section>
-            
-            <section class="doc-section">
-                <h2>When to Use Each</h2>
-                
-                <div class="feature-grid">
-                    <div class="feature-card">
-                        <h3>Use PageComponent when:</h3>
-                        <ul>
-                            <li>Creating top-level pages (routes)</li>
-                            <li>Building documentation pages</li>
-                            <li>Rendering full HTML documents</li>
-                            <li>The component needs its own URL</li>
-                        </ul>
-                    </div>
-                    <div class="feature-card">
-                        <h3>Use Component when:</h3>
-                        <ul>
-                            <li>Building reusable UI elements</li>
-                            <li>Creating widgets or cards</li>
-                            <li>Nesting inside other components</li>
-                            <li>Rendering partial content</li>
-                        </ul>
-                    </div>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Basic PageComponent Example</h2>
-                <p>
-                    Here's how to create a simple PageComponent:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="basic-example"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Route Registration</h2>
-                <p>
-                    PageComponents are registered as endpoints in your application's Main.vala.
-                    You register both the component type and its route:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="route-registration"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Dependency Injection in Pages</h2>
-                <p>
-                    PageComponents support the same dependency injection patterns as regular components.
-                    Use <code>inject<T>()</code> to access services, stores, and factories:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="di-example"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Template Wrapping</h2>
-                <p>
-                    One of the most powerful features of PageComponents is automatic template wrapping.
-                    When a PageComponent renders, it is automatically wrapped by matching 
-                    <code>PageTemplate</code> instances.
-                </p>
-                <p>
-                    This means your PageComponent markup only needs to contain the <em>content</em>
-                    of the page, not the full HTML document structure. The template provides the
-                    <code><html></code>, <code><head></code>, <code><body></code>,
-                    navigation, and footer.
-                </p>
-                
-                <div class="info-box">
-                    <p>
-                        <strong>💡 Tip:</strong> Learn more about templates in the 
-                        <a href="/page-components/templates">Page Templates</a> documentation.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>How handle_request() Works</h2>
-                <p>
-                    The <code>PageComponent</code> base class implements the <code>Endpoint</code>
-                    interface's <code>handle_request()</code> method. This method:
-                </p>
-                
-                <ol class="doc-list">
-                    <li>Collects all matching <code>PageTemplate</code> instances sorted by prefix depth</li>
-                    <li>Renders each template in order</li>
-                    <li>Finds <code>&lt;spry-content/&gt;</code> elements in each template</li>
-                    <li>Nests the content into the outlet, building the complete document</li>
-                    <li>Returns the final HTML as an <code>HttpResult</code></li>
-                </ol>
-                
-                <p>
-                    You typically don't need to override <code>handle_request()</code> - the default
-                    implementation handles everything for you.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Next Steps</h2>
-                <div class="nav-cards">
-                    <a href="/page-components/templates" class="nav-card">
-                        <h3>Page Templates →</h3>
-                        <p>Learn how to create layout templates that wrap your pages</p>
-                    </a>
-                    <a href="/components/overview" class="nav-card">
-                        <h3>Components Overview →</h3>
-                        <p>Review the basics of Spry components</p>
-                    </a>
-                </div>
-            </section>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Basic PageComponent example
-        var basic_example = get_component_child<CodeBlockComponent>("basic-example");
-        basic_example.language = "vala";
-        basic_example.code = "using Spry;\n" +
-            "using Inversion;\n\n" +
-            "public class DocumentationPage : PageComponent {\n" +
-            "    \n" +
-            "    // Dependency injection works the same as Component\n" +
-            "    private ComponentFactory factory = inject<ComponentFactory>();\n" +
-            "    \n" +
-            "    public override string markup { get {\n" +
-            "        return \"\"\"\n" +
-            "        <div class=\"page-content\">\n" +
-            "            <h1>My Documentation Page</h1>\n" +
-            "            <p>This page handles its own route.</p>\n" +
-            "        </div>\n" +
-            "        \"\"\";\n" +
-            "    }}\n" +
-            "    \n" +
-            "    public override async void prepare() throws Error {\n" +
-            "        // Set up page content\n" +
-            "    }\n" +
-            "}";
-        
-        // Route registration example
-        var route_reg = get_component_child<CodeBlockComponent>("route-registration");
-        route_reg.language = "vala";
-        route_reg.code = "// In Main.vala:\n\n" +
-            "// Register the page component with the dependency container\n" +
-            "application.add_transient<DocumentationPage>();\n\n" +
-            "// Register the page as an endpoint at a specific route\n" +
-            "application.add_endpoint<DocumentationPage>(\n" +
-            "    new EndpointRoute(\"/docs/page\")\n" +
-            ");\n\n" +
-            "// Now visiting /docs/page will render DocumentationPage\n" +
-            "// automatically wrapped by any matching PageTemplate";
-        
-        // Dependency injection example
-        var di_example = get_component_child<CodeBlockComponent>("di-example");
-        di_example.language = "vala";
-        di_example.code = "public class UserProfilePage : PageComponent {\n" +
-            "    \n" +
-            "    // Inject services you need\n" +
-            "    private ComponentFactory factory = inject<ComponentFactory>();\n" +
-            "    private UserStore user_store = inject<UserStore>();\n" +
-            "    private HttpContext http_context = inject<HttpContext>();\n" +
-            "    \n" +
-            "    public override string markup { get {\n" +
-            "        return \"\"\"\n" +
-            "        <div class=\"profile-page\">\n" +
-            "            <h2 sid=\"username\"></h2>\n" +
-            "            <p sid=\"email\"></p>\n" +
-            "        </div>\n" +
-            "        \"\"\";\n" +
-            "    }}\n" +
-            "    \n" +
-            "    public override async void prepare() throws Error {\n" +
-            "        // Access route parameters from http_context\n" +
-            "        var user_id = http_context.request.query_params\n" +
-            "            .get_any_or_default(\"id\", \"guest\");\n" +
-            "        \n" +
-            "        // Use injected store to fetch data\n" +
-            "        var user = yield user_store.get_user(user_id);\n" +
-            "        \n" +
-            "        // Populate template\n" +
-            "        this[\"username\"].text_content = user.name;\n" +
-            "        this[\"email\"].text_content = user.email;\n" +
-            "    }\n" +
-            "}";
-    }
-}

+ 0 - 421
demo/Pages/PageTemplatesPage.vala

@@ -1,421 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * PageTemplatesPage - Documentation for Page Templates
- * 
- * This page explains how PageTemplates work, how to create them,
- * and how they wrap PageComponents to provide site-wide layouts.
- */
-public class PageTemplatesPage : PageComponent {
-    
-    public override string title { get { return "Page Templates - Spry"; } }
-    
-    public const string ROUTE = "/page-components/templates";
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <div class="doc-content">
-            <div class="doc-hero">
-                <h1>Page Templates</h1>
-                <p class="doc-subtitle">Create reusable layouts that wrap your page components</p>
-            </div>
-            
-            <section class="doc-section">
-                <h2>What are Page Templates?</h2>
-                <p>
-                    A <code>PageTemplate</code> is a special component that provides the outer HTML
-                    structure for your pages. Templates define the <code><html></code>,
-                    <code><head></code>, <code><body></code>, and common elements like
-                    navigation headers and footers.
-                </p>
-                <p>
-                    The key feature of a PageTemplate is the <code>&lt;spry-content/&gt;</code>
-                    element, which marks where page content will be inserted. When a PageComponent
-                    renders, it automatically gets nested inside matching templates.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>The Template Outlet</h2>
-                <p>
-                    The <code>&lt;spry-content/&gt;</code> element is the placeholder where
-                    page content gets inserted. Every PageTemplate must include at least one outlet.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="outlet-example"/>
-                
-                <div class="info-box">
-                    <p>
-                        <strong>💡 How it works:</strong> When rendering, Spry finds all templates
-                        matching the current route, renders them in order of specificity, and nests
-                        each one's content into the previous template's outlet.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Creating a MainTemplate</h2>
-                <p>
-                    Here's a complete example of a site-wide template that provides the HTML
-                    document structure, head elements, navigation, and footer:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="main-template"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Template Registration</h2>
-                <p>
-                    Templates are registered with a <strong>prefix</strong> that determines which
-                    routes they apply to. The prefix is passed via metadata during registration:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="template-registration"/>
-                
-                <p>
-                    In this example, the <code>TemplateRoutePrefix("")</code> with an empty string
-                    matches <strong>all routes</strong>, making it the default site-wide template.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Route Prefix Matching</h2>
-                <p>
-                    Templates can target specific sections of your site using route prefixes.
-                    The prefix determines which routes the template will wrap:
-                </p>
-                
-                <table class="doc-table">
-                    <thead>
-                        <tr>
-                            <th>Prefix</th>
-                            <th>Matches Routes</th>
-                            <th>Use Case</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        <tr>
-                            <td><code>""</code> (empty)</td>
-                            <td>All routes</td>
-                            <td>Site-wide default template</td>
-                        </tr>
-                        <tr>
-                            <td><code>"/admin"</code></td>
-                            <td>/admin/*, /admin/settings, etc.</td>
-                            <td>Admin section layout</td>
-                        </tr>
-                        <tr>
-                            <td><code>"/docs"</code></td>
-                            <td>/docs/*, /docs/getting-started, etc.</td>
-                            <td>Documentation section</td>
-                        </tr>
-                        <tr>
-                            <td><code>"/api"</code></td>
-                            <td>/api/* routes</td>
-                            <td>API documentation or explorer</td>
-                        </tr>
-                    </tbody>
-                </table>
-                
-                <h3>How Matching Works</h3>
-                <p>
-                    The <code>TemplateRoutePrefix.matches_route()</code> method compares the template's
-                    prefix segments against the route segments. A template matches if its prefix
-                    segments are a prefix of the route segments.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="matching-logic"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Multiple Templates</h2>
-                <p>
-                    You can have multiple templates for different sections of your site.
-                    Templates are sorted by <strong>rank</strong> (prefix depth) and applied
-                    from lowest to highest rank:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="multiple-templates"/>
-                
-                <h3>Template Nesting Order</h3>
-                <p>
-                    For a route like <code>/admin/users</code>, templates would be applied in order:
-                </p>
-                
-                <ol class="doc-list">
-                    <li><strong>MainTemplate</strong> (prefix: "") - rank 0</li>
-                    <li><strong>AdminTemplate</strong> (prefix: "/admin") - rank 1</li>
-                    <li><strong>PageComponent</strong> - The actual page content</li>
-                </ol>
-                
-                <p>
-                    Each template's outlet receives the content from the next item in the chain,
-                    creating nested layouts.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Section-Specific Template Example</h2>
-                <p>
-                    Here's an example of a template specifically for the admin section that
-                    adds an admin sidebar:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="admin-template"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Head Content Merging</h2>
-                <p>
-                    When templates wrap pages, the <code><head></code> elements are automatically
-                    merged. If a PageComponent or nested template has <code><head></code> content,
-                    those elements are appended to the outer template's head.
-                </p>
-                
-                <p>
-                    This allows pages to add their own stylesheets, scripts, or meta tags while
-                    still benefiting from the template's common head elements.
-                </p>
-                
-                <div class="warning-box">
-                    <p>
-                        <strong>⚠️ Note:</strong> Head merging only works when templates render
-                        actual <code><head></code> elements. Make sure your templates include
-                        a proper HTML structure with head and body sections.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Template vs Component</h2>
-                
-                <table class="doc-table">
-                    <thead>
-                        <tr>
-                            <th>Feature</th>
-                            <th>PageTemplate</th>
-                            <th>Component</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        <tr>
-                            <td>Base class</td>
-                            <td><code>Component</code></td>
-                            <td><code>Component</code></td>
-                        </tr>
-                        <tr>
-                            <td>Has markup</td>
-                            <td>✓ Yes</td>
-                            <td>✓ Yes</td>
-                        </tr>
-                        <tr>
-                            <td>Contains outlet</td>
-                            <td>✓ Required</td>
-                            <td>✗ Optional</td>
-                        </tr>
-                        <tr>
-                            <td>Route matching</td>
-                            <td>By prefix</td>
-                            <td>N/A</td>
-                        </tr>
-                        <tr>
-                            <td>Wraps pages</td>
-                            <td>✓ Yes</td>
-                            <td>✗ No</td>
-                        </tr>
-                    </tbody>
-                </table>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Best Practices</h2>
-                
-                <ul class="doc-list">
-                    <li><strong>Keep templates focused:</strong> Each template should handle one level of layout (site-wide, section-specific)</li>
-                    <li><strong>Use semantic HTML:</strong> Include proper <code><header></code>, <code><main></code>, <code><footer></code> elements</li>
-                    <li><strong>Include common resources:</strong> Add shared stylesheets and scripts in your main template</li>
-                    <li><strong>Plan your prefix hierarchy:</strong> Design your URL structure to work with template prefixes</li>
-                    <li><strong>Don't duplicate content:</strong> Let templates handle repeated elements like navigation</li>
-                </ul>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Next Steps</h2>
-                <div class="nav-cards">
-                    <a href="/page-components/overview" class="nav-card">
-                        <h3>← Page Components</h3>
-                        <p>Learn about PageComponent basics</p>
-                    </a>
-                    <a href="/components/outlets" class="nav-card">
-                        <h3>Component Outlets →</h3>
-                        <p>Use outlets for nested components</p>
-                    </a>
-                </div>
-            </section>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Outlet example
-        var outlet_example = get_component_child<CodeBlockComponent>("outlet-example");
-        outlet_example.language = "xml";
-        outlet_example.code = "<!DOCTYPE html>\n" +
-            "<html lang=\"en\">\n" +
-            "<head>\n" +
-            "    <title>My Site</title>\n" +
-            "    <link rel=\"stylesheet\" href=\"/styles/main.css\">\n" +
-            "</head>\n" +
-            "<body>\n" +
-            "    <header>\n" +
-            "        <nav><!-- Site navigation --></nav>\n" +
-            "    </header>\n" +
-            "    \n" +
-            "    <main>\n" +
-            "        <!-- Page content is inserted here -->\n" +
-            "        <spry-content />\n" +
-            "    </main>\n" +
-            "    \n" +
-            "    <footer>\n" +
-            "        <p>&copy; 2024 My Site</p>\n" +
-            "    </footer>\n" +
-            "</body>\n" +
-            "</html>";
-        
-        // Main template example
-        var main_template = get_component_child<CodeBlockComponent>("main-template");
-        main_template.language = "vala";
-        main_template.code = "using Spry;\n\n" +
-            "/**\n" +
-            " * MainTemplate - Site-wide layout template\n" +
-            " * \n" +
-            " * Wraps all pages with common HTML structure,\n" +
-            " * navigation, and footer.\n" +
-            " */\n" +
-            "public class MainTemplate : PageTemplate {\n" +
-            "    \n" +
-            "    public override string markup { get {\n" +
-            "        return \"\"\"\n" +
-            "        <!DOCTYPE html>\n" +
-            "        <html lang=\"en\">\n" +
-            "        <head>\n" +
-            "            <meta charset=\"UTF-8\">\n" +
-            "            <meta name=\"viewport\" \n" +
-            "                  content=\"width=device-width, initial-scale=1.0\">\n" +
-            "            <title>My Spry Application</title>\n" +
-            "            <link rel=\"stylesheet\" href=\"/styles/main.css\">\n" +
-            "            <script spry-res=\"htmx.js\"></script>\n" +
-            "        </head>\n" +
-            "        <body>\n" +
-            "            <header class=\"site-header\">\n" +
-            "                <nav>\n" +
-            "                    <a href=\"/\" class=\"logo\">My App</a>\n" +
-            "                    <ul>\n" +
-            "                        <li><a href=\"/docs\">Docs</a></li>\n" +
-            "                        <li><a href=\"/about\">About</a></li>\n" +
-            "                    </ul>\n" +
-            "                </nav>\n" +
-            "            </header>\n" +
-            "            \n" +
-            "            <main>\n" +
-            "                <spry-content />\n" +
-            "            </main>\n" +
-            "            \n" +
-            "            <footer class=\"site-footer\">\n" +
-            "                <p>&copy; 2024 My App. Built with Spry.</p>\n" +
-            "            </footer>\n" +
-            "        </body>\n" +
-            "        </html>\n" +
-            "        \"\"\";\n" +
-            "    }}\n" +
-            "}";
-        
-        // Template registration
-        var template_reg = get_component_child<CodeBlockComponent>("template-registration");
-        template_reg.language = "vala";
-        template_reg.code = "// In Main.vala:\n\n" +
-            "var spry_cfg = application.configure_with<SpryConfigurator>();\n\n" +
-            "// Register template with empty prefix (matches all routes)\n" +
-            "spry_cfg.add_template<MainTemplate>(\"\");\n\n" +
-            "// The TemplateRoutePrefix is created internally from the string\n" +
-            "// and used for route matching";
-        
-        // Matching logic
-        var matching_logic = get_component_child<CodeBlockComponent>("matching-logic");
-        matching_logic.language = "vala";
-        matching_logic.code = "// TemplateRoutePrefix matching logic (simplified)\n\n" +
-            "public class TemplateRoutePrefix : Object {\n" +
-            "    public uint rank { get; private set; }\n" +
-            "    public string prefix { get; private set; }\n" +
-            "    \n" +
-            "    public TemplateRoutePrefix(string prefix) {\n" +
-            "        this.prefix = prefix;\n" +
-            "        // Rank is the number of path segments\n" +
-            "        rank = prefix.split(\"/\").length - 1;\n" +
-            "    }\n" +
-            "    \n" +
-            "    public bool matches_route(RouteContext context) {\n" +
-            "        // Returns true if prefix segments match\n" +
-            "        // the beginning of the route segments\n" +
-            "        return context.matched_route.route_segments\n" +
-            "            .starts_with(this.prefix_segments);\n" +
-            "    }\n" +
-            "}\n\n" +
-            "// Example: prefix \"/admin\" matches:\n" +
-            "//   /admin          ✓ (exact match)\n" +
-            "//   /admin/users    ✓ (prefix match)\n" +
-            "//   /admin/settings ✓ (prefix match)\n" +
-            "//   /user/admin     ✗ (not a prefix match)";
-        
-        // Multiple templates
-        var multiple_templates = get_component_child<CodeBlockComponent>("multiple-templates");
-        multiple_templates.language = "vala";
-        multiple_templates.code = "// In Main.vala:\n\n" +
-            "var spry_cfg = application.configure_with<SpryConfigurator>();\n\n" +
-            "// Site-wide template (rank 0, matches everything)\n" +
-            "spry_cfg.add_template<MainTemplate>(\"\");\n\n" +
-            "// Admin section template (rank 1, matches /admin/*)\n" +
-            "spry_cfg.add_template<AdminTemplate>(\"/admin\");\n\n" +
-            "// Documentation template (rank 1, matches /docs/*)\n" +
-            "spry_cfg.add_template<DocsTemplate>(\"/docs\");\n\n" +
-            "// API docs template (rank 2, matches /docs/api/*)\n" +
-            "spry_cfg.add_template<ApiDocsTemplate>(\"/docs/api\");";
-        
-        // Admin template example
-        var admin_template = get_component_child<CodeBlockComponent>("admin-template");
-        admin_template.language = "vala";
-        admin_template.code = "using Spry;\n\n" +
-            "/**\n" +
-            " * AdminTemplate - Layout for admin section\n" +
-            " * \n" +
-            " * Adds an admin sidebar to all /admin/* pages.\n" +
-            " */\n" +
-            "public class AdminTemplate : PageTemplate {\n" +
-            "    \n" +
-            "    public override string markup { get {\n" +
-            "        return \"\"\"\n" +
-            "        <div class=\"admin-layout\">\n" +
-            "            <aside class=\"admin-sidebar\">\n" +
-            "                <h3>Admin</h3>\n" +
-            "                <nav>\n" +
-            "                    <a href=\"/admin\">Dashboard</a>\n" +
-            "                    <a href=\"/admin/users\">Users</a>\n" +
-            "                    <a href=\"/admin/settings\">Settings</a>\n" +
-            "                </nav>\n" +
-            "            </aside>\n" +
-            "            \n" +
-            "            <div class=\"admin-content\">\n" +
-            "                <!-- Page content inserted here -->\n" +
-            "                <spry-content />\n" +
-            "            </div>\n" +
-            "        </div>\n" +
-            "        \"\"\";\n" +
-            "    }}\n" +
-            "}\n\n" +
-            "// Register with /admin prefix\n" +
-            "// spry_cfg.add_template<AdminTemplate>(\"/admin\");";
-    }
-}

+ 0 - 416
demo/Pages/StaticResourcesMkssrPage.vala

@@ -1,416 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * StaticResourcesMkssrPage - Documentation for the spry-mkssr tool
- * 
- * This page explains how to use spry-mkssr to generate static resources
- * for Spry applications.
- */
-public class StaticResourcesMkssrPage : PageComponent {
-    
-    public override string title { get { return "spry-mkssr Tool - Spry"; } }
-    
-    public const string ROUTE = "/static-resources/spry-mkssr";
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <div sid="page" class="doc-content">
-            <h1>spry-mkssr Tool</h1>
-            
-            <section class="doc-section">
-                <h2>What is spry-mkssr?</h2>
-                <p>
-                    <code>spry-mkssr</code> is a command-line tool that generates Spry Static Resource
-                    files from any input file. It handles compression, hashing, and metadata generation
-                    so your web application can serve optimized static content efficiently.
-                </p>
-                <p>
-                    The tool can generate two types of output:
-                </p>
-                <ul>
-                    <li><strong>SSR files</strong> (<code>.ssr</code>) - Pre-compiled resource files read at runtime</li>
-                    <li><strong>Vala source files</strong> - Embedded resources compiled into your binary</li>
-                </ul>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Command-Line Usage</h2>
-                
-                <spry-component name="CodeBlockComponent" sid="usage-code"/>
-                
-                <h3>Options</h3>
-                <table class="doc-table">
-                    <thead>
-                        <tr>
-                            <th>Option</th>
-                            <th>Description</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        <tr>
-                            <td><code>-o, --output=FILE</code></td>
-                            <td>Output file name (default: input.ssr or ClassNameResource.vala)</td>
-                        </tr>
-                        <tr>
-                            <td><code>-c, --content-type=TYPE</code></td>
-                            <td>Override content type (e.g., text/css, application/javascript)</td>
-                        </tr>
-                        <tr>
-                            <td><code>-n, --name=NAME</code></td>
-                            <td>Override resource name (default: input filename)</td>
-                        </tr>
-                        <tr>
-                            <td><code>--vala</code></td>
-                            <td>Generate Vala source file instead of SSR</td>
-                        </tr>
-                        <tr>
-                            <td><code>--ns=NAMESPACE</code></td>
-                            <td>Namespace for generated Vala class (requires --vala)</td>
-                        </tr>
-                        <tr>
-                            <td><code>-v, --version</code></td>
-                            <td>Show version information</td>
-                        </tr>
-                    </tbody>
-                </table>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Generating SSR Files</h2>
-                <p>
-                    By default, spry-mkssr generates <code>.ssr</code> files that can be read
-                    at runtime by <code>FileStaticResource</code>:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="ssr-example"/>
-                
-                <p>
-                    The generated SSR file contains:
-                </p>
-                <ul>
-                    <li><strong>Magic header</strong> - "spry-sr\0" identifier</li>
-                    <li><strong>Resource name</strong> - Used in URLs</li>
-                    <li><strong>Content type</strong> - MIME type for HTTP headers</li>
-                    <li><strong>SHA-512 hash</strong> - For ETag generation</li>
-                    <li><strong>Encoding headers</strong> - Offset and size for each encoding</li>
-                    <li><strong>Compressed data</strong> - gzip, zstd, brotli, and identity</li>
-                </ul>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Generating Vala Source Files</h2>
-                <p>
-                    Use the <code>--vala</code> flag to generate a Vala source file that embeds
-                    the resource directly into your binary:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="vala-example"/>
-                
-                <p>
-                    This creates a class that extends <code>ConstantStaticResource</code> with
-                    the resource data embedded as <code>const uint8[]</code> arrays.
-                </p>
-                
-                <h3>Namespace Configuration</h3>
-                <p>
-                    Use <code>--ns</code> to place the generated class in a namespace:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="namespace-example"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Generated Vala Class Structure</h2>
-                <p>
-                    The generated Vala class follows this structure:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="class-structure"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Integrating with Meson</h2>
-                <p>
-                    The recommended way to use spry-mkssr is with meson's 
-                    <code>custom_target</code> to generate resources at build time:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="meson-example"/>
-                
-                <h3>Complete meson.build Example</h3>
-                <spry-component name="CodeBlockComponent" sid="meson-complete"/>
-                
-                <div class="info-box">
-                    <p>
-                        <strong>💡 Tip:</strong> The <code>@INPUT@</code> and <code>@OUTPUT@</code>
-                        placeholders are automatically replaced by meson with the actual file paths.
-                    </p>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Compression Details</h2>
-                <p>
-                    spry-mkssr compresses resources with the highest compression levels:
-                </p>
-                
-                <table class="doc-table">
-                    <thead>
-                        <tr>
-                            <th>Encoding</th>
-                            <th>Level</th>
-                            <th>Best For</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        <tr>
-                            <td>gzip</td>
-                            <td>9 (maximum)</td>
-                            <td>Universal compatibility</td>
-                        </tr>
-                        <tr>
-                            <td>zstd</td>
-                            <td>19 (maximum)</td>
-                            <td>Modern browsers, fast decompression</td>
-                        </tr>
-                        <tr>
-                            <td>brotli</td>
-                            <td>11 (maximum)</td>
-                            <td>Best compression for text assets</td>
-                        </tr>
-                        <tr>
-                            <td>identity</td>
-                            <td>N/A</td>
-                            <td>No compression (always included)</td>
-                        </tr>
-                    </tbody>
-                </table>
-                
-                <p>
-                    Encodings are only included if they result in smaller file sizes than
-                    the original. The tool reports compression statistics during generation:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="compression-output"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Content Type Detection</h2>
-                <p>
-                    spry-mkssr automatically detects content types based on file extensions
-                    using GLib's content type guessing. You can override this with the
-                    <code>-c</code> flag:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="content-type-example"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Resource Naming</h2>
-                <p>
-                    By default, the resource name is derived from the input filename. For
-                    Vala source generation, the class name is created by converting the
-                    resource name to PascalCase and appending "Resource":
-                </p>
-                
-                <table class="doc-table">
-                    <thead>
-                        <tr>
-                            <th>Input File</th>
-                            <th>Resource Name</th>
-                            <th>Generated Class</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        <tr>
-                            <td>docs.css</td>
-                            <td>docs.css</td>
-                            <td>DocsResource.vala → DocsResource</td>
-                        </tr>
-                        <tr>
-                            <td>htmx.min.js</td>
-                            <td>htmx.min.js</td>
-                            <td>HtmxMinResource.vala → HtmxMinResource</td>
-                        </tr>
-                        <tr>
-                            <td>-n htmx.js htmx.min.js</td>
-                            <td>htmx.js</td>
-                            <td>HtmxResource.vala → HtmxResource</td>
-                        </tr>
-                    </tbody>
-                </table>
-                
-                <p>
-                    Use the <code>-n</code> flag to set a specific resource name:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="naming-example"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Next Steps</h2>
-                <div class="nav-cards">
-                    <a href="/static-resources/overview" class="nav-card">
-                        <h3>← Static Resources Overview</h3>
-                        <p>Back to static resources introduction</p>
-                    </a>
-                </div>
-            </section>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        var usage_code = get_component_child<CodeBlockComponent>("usage-code");
-        usage_code.language = "Bash";
-        usage_code.code = "spry-mkssr [OPTION?] INPUT_FILE\n\n" +
-            "# Examples:\n" +
-            "spry-mkssr styles.css                    # Creates styles.css.ssr\n" +
-            "spry-mkssr -o bundle.ssr app.js          # Creates bundle.ssr\n" +
-            "spry-mkssr --vala logo.png               # Creates LogoResource.vala\n" +
-            "spry-mkssr --vala --ns=MyApp styles.css  # Creates StylesResource.vala in MyApp namespace";
-        
-        var ssr_example = get_component_child<CodeBlockComponent>("ssr-example");
-        ssr_example.language = "Bash";
-        ssr_example.code = "# Generate an SSR file from a CSS file\n" +
-            "spry-mkssr styles.css\n" +
-            "# Output: styles.css.ssr\n\n" +
-            "# Generate with custom output name\n" +
-            "spry-mkssr -o resources/bundle.css.ssr styles.css\n" +
-            "# Output: resources/bundle.css.ssr\n\n" +
-            "# The resource name in URLs will be \"styles.css\"\n" +
-            "# URL: /_spry/res/styles.css";
-        
-        var vala_example = get_component_child<CodeBlockComponent>("vala-example");
-        vala_example.language = "Bash";
-        vala_example.code = "# Generate a Vala source file for embedding\n" +
-            "spry-mkssr --vala styles.css\n" +
-            "# Output: StylesResource.vala\n\n" +
-            "# The generated class name is derived from the filename\n" +
-            "# styles.css → StylesResource";
-        
-        var namespace_example = get_component_child<CodeBlockComponent>("namespace-example");
-        namespace_example.language = "Bash";
-        namespace_example.code = "# Generate with namespace\n" +
-            "spry-mkssr --vala --ns=MyApp.Static styles.css\n" +
-            "# Output: StylesResource.vala\n\n" +
-            "# Generated class:\n" +
-            "# namespace MyApp.Static {\n" +
-            "#     public class StylesResource : ConstantStaticResource {\n" +
-            "#         ...\n" +
-            "#     }\n" +
-            "# }";
-        
-        var class_structure = get_component_child<CodeBlockComponent>("class-structure");
-        class_structure.language = "Vala";
-        class_structure.code = "// Generated by spry-mkssr\n" +
-            "public class DocsResource : ConstantStaticResource {\n\n" +
-            "    // Resource metadata\n" +
-            "    public override string name { get { return \"docs.css\"; } }\n" +
-            "    public override string file_hash { get { return \"a1b2c3d4...\"; } }\n" +
-            "    public override string content_type { get { return \"text/css\"; } }\n\n" +
-            "    // Select best encoding based on client support\n" +
-            "    public override string get_best_encoding(Set<string> supported) {\n" +
-            "        if (supported.has(\"br\")) return \"br\";\n" +
-            "        if (supported.has(\"zstd\")) return \"zstd\";\n" +
-            "        if (supported.has(\"gzip\")) return \"gzip\";\n" +
-            "        return \"identity\";\n" +
-            "    }\n\n" +
-            "    // Return the data for a specific encoding\n" +
-            "    public override unowned uint8[] get_encoding(string encoding) {\n" +
-            "        switch (encoding) {\n" +
-            "            case \"br\": return BR_DATA;\n" +
-            "            case \"zstd\": return ZSTD_DATA;\n" +
-            "            case \"gzip\": return GZIP_DATA;\n" +
-            "            default: return IDENTITY_DATA;\n" +
-            "        }\n" +
-            "    }\n\n" +
-            "    // Embedded compressed data\n" +
-            "    private const uint8[] IDENTITY_DATA = { /* ... */ };\n" +
-            "    private const uint8[] GZIP_DATA = { /* ... */ };\n" +
-            "    private const uint8[] ZSTD_DATA = { /* ... */ };\n" +
-            "    private const uint8[] BR_DATA = { /* ... */ };\n" +
-            "}";
-        
-        var meson_example = get_component_child<CodeBlockComponent>("meson-example");
-        meson_example.language = "Meson";
-        meson_example.code = "# Generate a Vala resource file from CSS\n" +
-            "docs_css_resource = custom_target('docs-css-resource',\n" +
-            "    input: 'Static/docs.css',\n" +
-            "    output: 'DocsCssResource.vala',\n" +
-            "    command: [spry_mkssr, '--vala', '--ns=Demo.Static', \n" +
-            "              '-n', 'docs.css', '-c', 'text/css', \n" +
-            "              '-o', '@OUTPUT@', '@INPUT@']\n" +
-            ")\n\n" +
-            "# Then include in your executable sources:\n" +
-            "executable('my-app',\n" +
-            "    app_sources,\n" +
-            "    docs_css_resource,  # Add generated file\n" +
-            "    dependencies: [spry_dep]\n" +
-            ")";
-        
-        var meson_complete = get_component_child<CodeBlockComponent>("meson-complete");
-        meson_complete.language = "Meson";
-        meson_complete.code = "# Find the spry-mkssr tool\n" +
-            "spry_mkssr = find_program('spry-mkssr')\n\n" +
-            "# Generate multiple resources\n" +
-            "css_resource = custom_target('css-resource',\n" +
-            "    input: 'Static/styles.css',\n" +
-            "    output: 'StylesResource.vala',\n" +
-            "    command: [spry_mkssr, '--vala', '--ns=MyApp.Resources',\n" +
-            "              '-o', '@OUTPUT@', '@INPUT@']\n" +
-            ")\n\n" +
-            "js_resource = custom_target('js-resource',\n" +
-            "    input: 'Static/app.js',\n" +
-            "    output: 'AppResource.vala',\n" +
-            "    command: [spry_mkssr, '--vala', '--ns=MyApp.Resources',\n" +
-            "              '-c', 'application/javascript',\n" +
-            "              '-o', '@OUTPUT@', '@INPUT@']\n" +
-            ")\n\n" +
-            "# Build executable with embedded resources\n" +
-            "executable('my-app',\n" +
-            "    'Main.vala',\n" +
-            "    css_resource,\n" +
-            "    js_resource,\n" +
-            "    dependencies: [spry_dep]\n" +
-            ")";
-        
-        var compression_output = get_component_child<CodeBlockComponent>("compression-output");
-        compression_output.language = "Bash";
-        compression_output.code = "$ spry-mkssr --vala docs.css\n" +
-            "Compressing with gzip...\n" +
-            "  gzip: 16094 -> 3245 bytes (20.2%)\n" +
-            "Compressing with zstd...\n" +
-            "  zstd: 16094 -> 2987 bytes (18.6%)\n" +
-            "Compressing with brotli...\n" +
-            "  brotli: 16094 -> 2654 bytes (16.5%)\n" +
-            "Generated: DocsResource.vala";
-        
-        var content_type_example = get_component_child<CodeBlockComponent>("content-type-example");
-        content_type_example.language = "Bash";
-        content_type_example.code = "# Automatic detection (recommended)\n" +
-            "spry-mkssr styles.css        # → text/css\n" +
-            "spry-mkssr app.js            # → application/javascript\n" +
-            "spry-mkssr logo.png          # → image/png\n\n" +
-            "# Manual override\n" +
-            "spry-mkssr -c text/plain data.json   # Force text/plain\n" +
-            "spry-mkssr -c application/wasm module.wasm  # Custom MIME type";
-        
-        var naming_example = get_component_child<CodeBlockComponent>("naming-example");
-        naming_example.language = "Bash";
-        naming_example.code = "# Default naming\n" +
-            "spry-mkssr --vala htmx.min.js\n" +
-            "# Resource: \"htmx.min.js\", Class: HtmxMinResource\n\n" +
-            "# Custom resource name\n" +
-            "spry-mkssr --vala -n htmx.js htmx.min.js\n" +
-            "# Resource: \"htmx.js\", Class: HtmxResource\n" +
-            "# URL: /_spry/res/htmx.js\n\n" +
-            "# This is useful for:\n" +
-            "# - Hiding .min suffix from URLs\n" +
-            "# - Using versioned files with clean names\n" +
-            "# - Renaming resources for organization";
-    }
-}

+ 0 - 261
demo/Pages/StaticResourcesOverviewPage.vala

@@ -1,261 +0,0 @@
-using Spry;
-using Inversion;
-
-/**
- * StaticResourcesOverviewPage - Introduction to Spry Static Resources
- * 
- * This page provides a comprehensive overview of static resource handling in Spry,
- * including the different types of resources and how to use them.
- */
-public class StaticResourcesOverviewPage : PageComponent {
-    
-    public override string title { get { return "Static Resources - Spry"; } }
-    
-    public const string ROUTE = "/static-resources/overview";
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <div sid="page" class="doc-content">
-            <h1>Static Resources Overview</h1>
-            
-            <section class="doc-section">
-                <h2>What are Static Resources?</h2>
-                <p>
-                    Spry provides a built-in system for serving static assets like CSS, JavaScript,
-                    images, and fonts. The static resource system handles content negotiation,
-                    compression, and caching automatically.
-                </p>
-                <p>
-                    Unlike traditional web frameworks that serve static files directly from disk,
-                    Spry's static resources are pre-compressed and can be embedded directly into
-                    your binary for single-binary deployments.
-                </p>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Types of Static Resources</h2>
-                <p>
-                    Spry provides three implementations of the 
-                    <code>StaticResource</code> interface:
-                </p>
-                
-                <div class="resource-types">
-                    <div class="resource-type-card">
-                        <h3>FileStaticResource</h3>
-                        <p>
-                            Reads pre-compiled <code>.ssr</code> (Spry Static Resource) files from
-                            disk at runtime. These files contain the resource data along with
-                            pre-compressed versions (gzip, zstd, brotli) and metadata.
-                        </p>
-                        <ul>
-                            <li>Loaded from <code>.ssr</code> files generated by spry-mkssr</li>
-                            <li>Contains all compression variants in a single file</li>
-                            <li>Includes SHA-512 hash for ETags</li>
-                        </ul>
-                    </div>
-                    
-                    <div class="resource-type-card">
-                        <h3>MemoryStaticResource</h3>
-                        <p>
-                            Holds static resource data entirely in memory. Useful for
-                            dynamically generated resources or when you want to load
-                            resources from a custom source.
-                        </p>
-                        <ul>
-                            <li>All data held in RAM</li>
-                            <li>Supports all compression formats</li>
-                            <li>Created programmatically at runtime</li>
-                        </ul>
-                    </div>
-                    
-                    <div class="resource-type-card">
-                        <h3>ConstantStaticResource</h3>
-                        <p>
-                            Embeds static resources directly into your binary at compile time.
-                            The resource data becomes part of your executable, enabling true
-                            single-binary deployments.
-                        </p>
-                        <ul>
-                            <li>Compiled into your binary</li>
-                            <li>Generated by spry-mkssr with <code>--vala</code> flag</li>
-                            <li>Zero runtime file I/O</li>
-                        </ul>
-                    </div>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>The StaticResource Interface</h2>
-                <p>
-                    All static resources implement the <code>StaticResource</code> interface,
-                    which defines the contract for serving static content:
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="interface-code"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>The StaticResourceProvider Endpoint</h2>
-                <p>
-                    Spry includes a built-in endpoint for serving static resources. The
-                    <code>StaticResourceProvider</code> handles all the complexity of content
-                    negotiation and caching.
-                </p>
-                
-                <h3>Route Pattern</h3>
-                <p>
-                    Static resources are served from the route:
-                </p>
-                <div class="code-inline">
-                    <code>/_spry/res/{resource}</code>
-                </div>
-                <p>
-                    Where <code>{resource}</code> is the name of the resource (e.g., 
-                    <code>docs.css</code>, <code>htmx.js</code>).
-                </p>
-                
-                <h3>Content Negotiation</h3>
-                <p>
-                    The provider automatically selects the best compression format based on
-                    the client's <code>Accept-Encoding</code> header. Supported encodings:
-                </p>
-                <ul>
-                    <li><strong>gzip</strong> - Universal browser support</li>
-                    <li><strong>zstd</strong> - Modern, high-performance compression</li>
-                    <li><strong>br</strong> (Brotli) - Best compression ratios for text</li>
-                    <li><strong>identity</strong> - No compression (always available)</li>
-                </ul>
-                
-                <h3>ETag-Based Caching</h3>
-                <p>
-                    Each resource generates an ETag based on its content hash and encoding.
-                    The provider handles <code>If-None-Match</code> requests, returning
-                    <code>304 Not Modified</code> when the client's cached version is current.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="etag-code"/>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Using Resources in Templates</h2>
-                <p>
-                    Spry provides the <code>spry-res</code> attribute for easily referencing
-                    static resources in your HTML templates. This attribute automatically
-                    generates the correct URL for your resource.
-                </p>
-                
-                <spry-component name="CodeBlockComponent" sid="template-usage"/>
-                
-                <p>
-                    The <code>spry-res</code> attribute works with any element that has
-                    <code>href</code> or <code>src</code> attributes:
-                </p>
-                <ul>
-                    <li><code><link></code> for stylesheets</li>
-                    <li><code><script></code> for JavaScript</li>
-                    <li><code><img></code> for images</li>
-                    <li><code><source></code> for media elements</li>
-                </ul>
-            </section>
-            
-            <section class="doc-section">
-                <h2>How It Works</h2>
-                <div class="lifecycle-diagram">
-                    <div class="lifecycle-step">
-                        <div class="step-number">1</div>
-                        <div class="step-content">
-                            <h4>Build Time</h4>
-                            <p>Use spry-mkssr to generate .ssr files or Vala source files</p>
-                        </div>
-                    </div>
-                    <div class="lifecycle-arrow">↓</div>
-                    <div class="lifecycle-step">
-                        <div class="step-number">2</div>
-                        <div class="step-content">
-                            <h4>Registration</h4>
-                            <p>Register resources via dependency injection</p>
-                        </div>
-                    </div>
-                    <div class="lifecycle-arrow">↓</div>
-                    <div class="lifecycle-step">
-                        <div class="step-number">3</div>
-                        <div class="step-content">
-                            <h4>Request</h4>
-                            <p>Client requests /_spry/res/resource-name</p>
-                        </div>
-                    </div>
-                    <div class="lifecycle-arrow">↓</div>
-                    <div class="lifecycle-step">
-                        <div class="step-number">4</div>
-                        <div class="step-content">
-                            <h4>Negotiation</h4>
-                            <p>Server selects best encoding based on Accept-Encoding</p>
-                        </div>
-                    </div>
-                    <div class="lifecycle-arrow">↓</div>
-                    <div class="lifecycle-step">
-                        <div class="step-number">5</div>
-                        <div class="step-content">
-                            <h4>Response</h4>
-                            <p>Compressed content sent with ETag for caching</p>
-                        </div>
-                    </div>
-                </div>
-            </section>
-            
-            <section class="doc-section">
-                <h2>Next Steps</h2>
-                <div class="nav-cards">
-                    <a href="/static-resources/spry-mkssr" class="nav-card">
-                        <h3>spry-mkssr Tool →</h3>
-                        <p>Learn how to generate static resources</p>
-                    </a>
-                </div>
-            </section>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        var interface_code = get_component_child<CodeBlockComponent>("interface-code");
-        interface_code.language = "Vala";
-        interface_code.code = "public interface StaticResource : Object {\n" +
-            "    // The unique name of this resource (e.g., \"docs.css\")\n" +
-            "    public abstract string name { get; }\n\n" +
-            "    // Returns the best encoding supported by the client\n" +
-            "    public abstract string get_best_encoding(Set<string> supported);\n\n" +
-            "    // Returns the ETag for a specific encoding\n" +
-            "    public abstract string get_etag_for(string encoding);\n\n" +
-            "    // Converts the resource to an HTTP result\n" +
-            "    public abstract HttpResult to_result(string encoding, \n" +
-            "                                         StatusCode status = StatusCode.OK) \n" +
-            "        throws Error;\n" +
-            "}";
-        
-        var etag_code = get_component_child<CodeBlockComponent>("etag-code");
-        etag_code.language = "Vala";
-        etag_code.code = "// ETag format: \"{encoding}-{hash}\"\n" +
-            "// Example: \"br-a1b2c3d4e5f6...\"\n\n" +
-            "// The provider checks If-None-Match automatically:\n" +
-            "if (request.headers.get_or_empty(\"If-None-Match\").contains(etag)) {\n" +
-            "    return new HttpEmptyResult(StatusCode.NOT_MODIFIED);\n" +
-            "}\n\n" +
-            "// Fresh content is returned with the ETag header\n" +
-            "response.set_header(\"ETag\", etag);";
-        
-        var template_usage = get_component_child<CodeBlockComponent>("template-usage");
-        template_usage.language = "HTML";
-        template_usage.code = "<!-- Stylesheets -->\n" +
-            "<link rel=\"stylesheet\" spry-res=\"docs.css\">\n\n" +
-            "<!-- JavaScript -->\n" +
-            "<script spry-res=\"htmx.js\"></script>\n" +
-            "<script spry-res=\"htmx-sse.js\"></script>\n\n" +
-            "<!-- Images -->\n" +
-            "<img spry-res=\"logo.png\" alt=\"Logo\">\n\n" +
-            "<!-- Results in URLs like: -->\n" +
-            "<!-- /_spry/res/docs.css -->\n" +
-            "<!-- /_spry/res/htmx.js -->";
-    }
-}

+ 0 - 1190
demo/Static/docs.css

@@ -1,1190 +0,0 @@
-/* ==========================================================================
-   Documentation Site CSS Theme
-   A clean, minimal theme for documentation sites
-   ========================================================================== */
-
-/* ==========================================================================
-   CSS Custom Properties (Variables)
-   ========================================================================== */
-
-:root {
-  /* Colors - Light Mode */
-  --color-background: #ffffff;
-  --color-sidebar-bg: #f8f9fa;
-  --color-text: #24292f;
-  --color-text-muted: #57606a;
-  --color-primary: #0969da;
-  --color-primary-hover: #0550ae;
-  --color-border: #d0d7de;
-  --color-code-bg: #f6f8fa;
-  --color-code-border: #d0d7de;
-  --color-table-header-bg: #f6f8fa;
-  --color-blockquote-border: #d0d7de;
-  --color-blockquote-bg: #f6f8fa;
-  --color-hover-bg: #eaeef2;
-  --color-active-bg: #ddf4ff;
-  --color-active-border: #0969da;
-
-  /* Layout */
-  --sidebar-width: 280px;
-  --content-max-width: 800px;
-  --sidebar-padding: 1.5rem;
-  --content-padding: 2rem;
-
-  /* Typography */
-  --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
-  --font-family-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
-  --font-size-base: 16px;
-  --font-size-small: 0.875rem;
-  --font-size-smaller: 0.75rem;
-  --line-height-base: 1.65;
-  --line-height-heading: 1.25;
-
-  /* Spacing */
-  --spacing-xs: 0.25rem;
-  --spacing-sm: 0.5rem;
-  --spacing-md: 1rem;
-  --spacing-lg: 1.5rem;
-  --spacing-xl: 2rem;
-  --spacing-xxl: 3rem;
-
-  /* Transitions */
-  --transition-fast: 150ms ease;
-  --transition-normal: 250ms ease;
-}
-
-/* ==========================================================================
-   Base Reset & Typography
-   ========================================================================== */
-
-*,
-*::before,
-*::after {
-  box-sizing: border-box;
-}
-
-html {
-  font-size: var(--font-size-base);
-  scroll-behavior: smooth;
-}
-
-body {
-  margin: 0;
-  padding: 0;
-  font-family: var(--font-family);
-  font-size: 1rem;
-  line-height: var(--line-height-base);
-  color: var(--color-text);
-  background-color: var(--color-background);
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-}
-
-/* Headings */
-h1, h2, h3, h4, h5, h6 {
-  margin: var(--spacing-xxl) 0 var(--spacing-md);
-  font-weight: 600;
-  line-height: var(--line-height-heading);
-  color: var(--color-text);
-}
-
-h1 {
-  font-size: 2rem;
-  padding-bottom: var(--spacing-md);
-  border-bottom: 1px solid var(--color-border);
-}
-
-h2 {
-  font-size: 1.5rem;
-  padding-bottom: var(--spacing-sm);
-  border-bottom: 1px solid var(--color-border);
-}
-
-h3 {
-  font-size: 1.25rem;
-}
-
-h4 {
-  font-size: 1.125rem;
-}
-
-h5 {
-  font-size: 1rem;
-}
-
-h6 {
-  font-size: var(--font-size-small);
-  color: var(--color-text-muted);
-  text-transform: uppercase;
-  letter-spacing: 0.05em;
-}
-
-/* First heading should not have top margin */
-h1:first-child,
-h2:first-child,
-h3:first-child {
-  margin-top: 0;
-}
-
-/* Paragraphs */
-p {
-  margin: var(--spacing-md) 0;
-}
-
-/* ==========================================================================
-   Layout
-   ========================================================================== */
-
-.docs-container {
-  display: flex;
-  min-height: 100vh;
-}
-
-/* Sidebar Navigation */
-.docs-sidebar {
-  position: fixed;
-  top: 0;
-  left: 0;
-  width: var(--sidebar-width);
-  height: 100vh;
-  background-color: var(--color-sidebar-bg);
-  border-right: 1px solid var(--color-border);
-  overflow-y: auto;
-  padding: var(--sidebar-padding);
-  z-index: 100;
-}
-
-.docs-sidebar-header {
-  padding-bottom: var(--spacing-md);
-  margin-bottom: var(--spacing-md);
-  border-bottom: 1px solid var(--color-border);
-}
-
-.docs-sidebar-logo {
-  font-size: 1.25rem;
-  font-weight: 600;
-  color: var(--color-text);
-  text-decoration: none;
-}
-
-.docs-sidebar-logo:hover {
-  color: var(--color-primary);
-}
-
-/* Main Content Area */
-.docs-main {
-  margin-left: var(--sidebar-width);
-  flex: 1;
-  min-width: 0;
-}
-
-.docs-content {
-  max-width: var(--content-max-width);
-  margin: 0 auto;
-  padding: var(--content-padding);
-}
-
-/* ==========================================================================
-   Navigation Sidebar
-   ========================================================================== */
-
-/* NavSidebarComponent styles */
-.nav-sidebar {
-  position: fixed;
-  top: 0;
-  left: 0;
-  width: var(--sidebar-width);
-  height: 100vh;
-  background-color: var(--color-sidebar-bg);
-  border-right: 1px solid var(--color-border);
-  overflow-y: auto;
-  padding: var(--sidebar-padding);
-  z-index: 100;
-}
-
-.nav-section {
-  margin-bottom: var(--spacing-md);
-}
-
-.nav-section-title {
-  padding: var(--spacing-sm) var(--spacing-md);
-  margin: 0 0 var(--spacing-xs);
-  font-size: var(--font-size-small);
-  font-weight: 600;
-  color: var(--color-text);
-  text-transform: uppercase;
-  letter-spacing: 0.05em;
-}
-
-.nav-items {
-  list-style: none;
-  margin: 0;
-  padding: 0;
-}
-
-.nav-item {
-  display: block;
-  padding: var(--spacing-sm) var(--spacing-md);
-  color: var(--color-text-muted);
-  text-decoration: none;
-  font-size: var(--font-size-small);
-  border-radius: 4px;
-  border-left: 3px solid transparent;
-  transition: all var(--transition-fast);
-}
-
-.nav-item:hover {
-  color: var(--color-text);
-  background-color: var(--color-hover-bg);
-  text-decoration: none;
-}
-
-.nav-item.active {
-  color: var(--color-primary);
-  background-color: var(--color-active-bg);
-  border-left-color: var(--color-active-border);
-  font-weight: 500;
-}
-
-.docs-nav {
-  list-style: none;
-  margin: 0;
-  padding: 0;
-}
-
-.docs-nav-section {
-  margin-bottom: var(--spacing-md);
-}
-
-.docs-nav-section-title {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  padding: var(--spacing-sm) var(--spacing-md);
-  font-size: var(--font-size-small);
-  font-weight: 600;
-  color: var(--color-text);
-  text-transform: uppercase;
-  letter-spacing: 0.05em;
-  cursor: pointer;
-  background: none;
-  border: none;
-  width: 100%;
-  text-align: left;
-  border-radius: 4px;
-  transition: background-color var(--transition-fast);
-}
-
-.docs-nav-section-title:hover {
-  background-color: var(--color-hover-bg);
-}
-
-.docs-nav-section-title::after {
-  content: "";
-  display: inline-block;
-  width: 6px;
-  height: 6px;
-  border-right: 2px solid currentColor;
-  border-bottom: 2px solid currentColor;
-  transform: rotate(-45deg);
-  transition: transform var(--transition-fast);
-}
-
-.docs-nav-section.collapsed .docs-nav-section-title::after {
-  transform: rotate(45deg);
-}
-
-.docs-nav-section.collapsed .docs-nav-items {
-  display: none;
-}
-
-.docs-nav-items {
-  list-style: none;
-  margin: 0;
-  padding: 0;
-}
-
-.docs-nav-item {
-  margin: 0;
-}
-
-.docs-nav-link {
-  display: block;
-  padding: var(--spacing-sm) var(--spacing-md);
-  color: var(--color-text-muted);
-  text-decoration: none;
-  font-size: var(--font-size-small);
-  border-radius: 4px;
-  border-left: 3px solid transparent;
-  transition: all var(--transition-fast);
-}
-
-.docs-nav-link:hover {
-  color: var(--color-text);
-  background-color: var(--color-hover-bg);
-}
-
-.docs-nav-link.active {
-  color: var(--color-primary);
-  background-color: var(--color-active-bg);
-  border-left-color: var(--color-active-border);
-  font-weight: 500;
-}
-
-/* Nested navigation items */
-.docs-nav-items .docs-nav-items {
-  margin-left: var(--spacing-md);
-}
-
-.docs-nav-items .docs-nav-items .docs-nav-link {
-  padding-left: var(--spacing-lg);
-  font-size: calc(var(--font-size-small) - 0.0625rem);
-}
-
-/* ==========================================================================
-   Links
-   ========================================================================== */
-
-a {
-  color: var(--color-primary);
-  text-decoration: none;
-  transition: color var(--transition-fast);
-}
-
-a:hover {
-  color: var(--color-primary-hover);
-  text-decoration: underline;
-}
-
-a:focus {
-  outline: 2px solid var(--color-primary);
-  outline-offset: 2px;
-}
-
-/* ==========================================================================
-   Code Blocks
-   ========================================================================== */
-
-code {
-  font-family: var(--font-family-mono);
-  font-size: 0.9em;
-  padding: var(--spacing-xs) var(--spacing-sm);
-  background-color: var(--color-code-bg);
-  border-radius: 4px;
-  border: 1px solid var(--color-code-border);
-}
-
-/* Inline code */
-p > code,
-li > code,
-td > code {
-  font-size: 0.85em;
-}
-
-/* Block code */
-pre {
-  margin: var(--spacing-lg) 0;
-  padding: var(--spacing-md);
-  background-color: var(--color-code-bg);
-  border: 1px solid var(--color-code-border);
-  border-radius: 6px;
-  overflow-x: auto;
-  -webkit-overflow-scrolling: touch;
-}
-
-pre code {
-  display: block;
-  padding: 0;
-  background: none;
-  border: none;
-  font-size: var(--font-size-small);
-  line-height: 1.5;
-  white-space: pre;
-}
-
-/* Code block with language indicator */
-pre[data-lang] {
-  position: relative;
-}
-
-pre[data-lang]::before {
-  content: attr(data-lang);
-  position: absolute;
-  top: var(--spacing-sm);
-  right: var(--spacing-sm);
-  font-size: var(--font-size-smaller);
-  color: var(--color-text-muted);
-  text-transform: uppercase;
-  font-family: var(--font-family);
-}
-
-/* Syntax highlighting base colors (for use with highlighters like Prism.js) */
-.token.comment,
-.token.prolog,
-.token.doctype,
-.token.cdata {
-  color: var(--color-text-muted);
-}
-
-.token.punctuation {
-  color: var(--color-text);
-}
-
-.token.property,
-.token.tag,
-.token.boolean,
-.token.number,
-.token.constant,
-.token.symbol {
-  color: #0550ae;
-}
-
-.token.selector,
-.token.attr-name,
-.token.string,
-.token.char,
-.token.builtin {
-  color: #0a3069;
-}
-
-.token.operator,
-.token.entity,
-.token.url {
-  color: #cf222e;
-}
-
-.token.atrule,
-.token.attr-value,
-.token.keyword {
-  color: #cf222e;
-}
-
-.token.function,
-.token.class-name {
-  color: #8250df;
-}
-
-.token.regex,
-.token.important,
-.token.variable {
-  color: #953800;
-}
-
-/* ==========================================================================
-   Tables
-   ========================================================================== */
-
-table {
-  width: 100%;
-  margin: var(--spacing-lg) 0;
-  border-collapse: collapse;
-  border-spacing: 0;
-  font-size: var(--font-size-small);
-}
-
-th,
-td {
-  padding: var(--spacing-sm) var(--spacing-md);
-  text-align: left;
-  border: 1px solid var(--color-border);
-}
-
-th {
-  background-color: var(--color-table-header-bg);
-  font-weight: 600;
-}
-
-tr:nth-child(even) {
-  background-color: var(--color-code-bg);
-}
-
-table code {
-  font-size: 0.9em;
-}
-
-/* ==========================================================================
-   Lists
-   ========================================================================== */
-
-ul,
-ol {
-  margin: var(--spacing-md) 0;
-  padding-left: var(--spacing-xl);
-}
-
-li {
-  margin: var(--spacing-xs) 0;
-}
-
-li > ul,
-li > ol {
-  margin: var(--spacing-xs) 0;
-}
-
-/* Definition lists */
-dl {
-  margin: var(--spacing-lg) 0;
-}
-
-dt {
-  font-weight: 600;
-  margin-top: var(--spacing-md);
-}
-
-dd {
-  margin: 0;
-  padding-left: var(--spacing-xl);
-  color: var(--color-text-muted);
-}
-
-/* ==========================================================================
-   Blockquotes
-   ========================================================================== */
-
-blockquote {
-  margin: var(--spacing-lg) 0;
-  padding: var(--spacing-md) var(--spacing-lg);
-  background-color: var(--color-blockquote-bg);
-  border-left: 4px solid var(--color-blockquote-border);
-  border-radius: 0 4px 4px 0;
-}
-
-blockquote p {
-  margin: 0;
-}
-
-blockquote p + p {
-  margin-top: var(--spacing-md);
-}
-
-blockquote code {
-  background-color: rgba(0, 0, 0, 0.05);
-}
-
-/* ==========================================================================
-   Warning Boxes
-   ========================================================================== */
-
-.warning-box {
-  background: #fff3cd;
-  border: 1px solid #ffc107;
-  border-left: 4px solid #ffc107;
-  padding: 1rem;
-  margin: 1rem 0;
-  border-radius: 4px;
-}
-
-.warning-box h4 {
-  margin-top: 0;
-  margin-bottom: 0.5rem;
-  color: #856404;
-}
-
-.warning-box p {
-  margin: 0;
-  color: #856404;
-}
-
-.warning-box ul {
-  margin: 0.5rem 0 0;
-  padding-left: 1.5rem;
-  color: #856404;
-}
-
-.warning-box li {
-  margin: 0.25rem 0;
-}
-
-.warning-box code {
-  background-color: rgba(133, 100, 4, 0.1);
-  border-color: rgba(133, 100, 4, 0.2);
-}
-
-/* ==========================================================================
-   Horizontal Rules
-   ========================================================================== */
-
-hr {
-  margin: var(--spacing-xxl) 0;
-  padding: 0;
-  border: none;
-  border-top: 1px solid var(--color-border);
-}
-
-/* ==========================================================================
-   Page Layout (for full-page components)
-   ========================================================================== */
-
-.page-container {
-  display: flex;
-  min-height: 100vh;
-}
-
-.main-content {
-  margin-left: var(--sidebar-width);
-  flex: 1;
-  min-width: 0;
-}
-
-.doc-content {
-  max-width: var(--content-max-width);
-  margin: 0 auto;
-  padding: var(--content-padding);
-}
-
-.doc-section {
-  margin-bottom: var(--spacing-xxl);
-}
-
-/* ==========================================================================
-   Home Page Styles
-   ========================================================================== */
-
-.home-hero {
-  text-align: center;
-  padding: var(--spacing-xxl) 0;
-  margin-bottom: var(--spacing-xl);
-  border-bottom: 1px solid var(--color-border);
-}
-
-.hero-title {
-  font-size: 3rem;
-  font-weight: 700;
-  margin: 0 0 var(--spacing-sm);
-  color: var(--color-text);
-  border-bottom: none;
-  padding-bottom: 0;
-}
-
-.hero-tagline {
-  font-size: 1.25rem;
-  color: var(--color-text-muted);
-  margin: 0;
-}
-
-.intro {
-  font-size: 1.125rem;
-  line-height: 1.7;
-  color: var(--color-text);
-}
-
-/* Quick Links Grid */
-.quick-links {
-  display: grid;
-  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
-  gap: var(--spacing-lg);
-  margin: var(--spacing-lg) 0;
-}
-
-.quick-link-card {
-  display: block;
-  padding: var(--spacing-lg);
-  background-color: var(--color-sidebar-bg);
-  border: 1px solid var(--color-border);
-  border-radius: 8px;
-  text-decoration: none;
-  transition: all var(--transition-fast);
-}
-
-.quick-link-card:hover {
-  background-color: var(--color-hover-bg);
-  border-color: var(--color-primary);
-  text-decoration: none;
-}
-
-.quick-link-card h3 {
-  margin: 0 0 var(--spacing-sm);
-  font-size: 1.125rem;
-  color: var(--color-primary);
-  border-bottom: none;
-  padding-bottom: 0;
-}
-
-.quick-link-card p {
-  margin: 0;
-  font-size: var(--font-size-small);
-  color: var(--color-text-muted);
-  line-height: 1.5;
-}
-
-/* Features List */
-.features-list {
-  list-style: none;
-  padding: 0;
-  margin: var(--spacing-lg) 0;
-}
-
-.features-list li {
-  padding: var(--spacing-sm) 0;
-  padding-left: var(--spacing-lg);
-  position: relative;
-}
-
-.features-list li::before {
-  content: "✓";
-  position: absolute;
-  left: 0;
-  color: var(--color-primary);
-  font-weight: 600;
-}
-
-.features-list li strong {
-  color: var(--color-text);
-}
-
-/* ==========================================================================
-   Demo Host Component
-   ========================================================================== */
-
-.demo-host {
-  margin: var(--spacing-xl) 0;
-  border: 2px solid var(--color-border);
-  border-radius: 8px;
-  overflow: hidden;
-  background-color: var(--color-background);
-  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
-}
-
-.demo-header {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  padding: var(--spacing-sm) var(--spacing-md);
-  background-color: var(--color-sidebar-bg);
-  border-bottom: 1px solid var(--color-border);
-}
-
-.demo-title {
-  font-size: var(--font-size-small);
-  font-weight: 600;
-  color: var(--color-text);
-}
-
-.demo-content {
-  padding: var(--spacing-lg);
-  background-color: var(--color-background);
-  min-height: 100px;
-}
-
-/* Demo toggle buttons */
-.demo-toggle-group {
-  display: flex;
-  gap: 2px;
-  background-color: var(--color-code-bg);
-  border-radius: 4px;
-  padding: 2px;
-}
-
-.demo-toggle-btn {
-  padding: var(--spacing-xs) var(--spacing-md);
-  font-family: var(--font-family);
-  font-size: var(--font-size-smaller);
-  font-weight: 500;
-  color: var(--color-text-muted);
-  background-color: transparent;
-  border: none;
-  border-radius: 3px;
-  cursor: pointer;
-  transition: all var(--transition-fast);
-}
-
-.demo-toggle-btn:hover {
-  color: var(--color-text);
-}
-
-.demo-toggle-btn.active {
-  color: var(--color-text);
-  background-color: var(--color-background);
-  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-}
-
-.demo-toggle-btn:focus {
-  outline: 2px solid var(--color-primary);
-  outline-offset: 1px;
-}
-
-/* Source code view */
-.demo-source {
-  margin: 0;
-  padding: var(--spacing-md);
-  background-color: var(--color-code-bg);
-  border-top: 1px solid var(--color-border);
-  overflow-x: auto;
-  font-family: var(--font-family-mono);
-  font-size: var(--font-size-small);
-  line-height: 1.5;
-}
-
-.demo-source code {
-  display: block;
-  padding: 0;
-  background: none;
-  border: none;
-  font-size: inherit;
-  white-space: pre;
-}
-
-/* Legacy demo-frame styles (for backwards compatibility) */
-.demo-frame {
-  border: 1px solid var(--color-border);
-  border-radius: 6px;
-  overflow: hidden;
-  background-color: var(--color-background);
-}
-
-.demo-frame-header {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  padding: var(--spacing-sm) var(--spacing-md);
-  background-color: var(--color-sidebar-bg);
-  border-bottom: 1px solid var(--color-border);
-}
-
-.demo-frame-title {
-  font-size: var(--font-size-small);
-  font-weight: 600;
-  color: var(--color-text);
-  margin: 0;
-}
-
-.demo-frame-content {
-  padding: var(--spacing-lg);
-}
-
-/* ==========================================================================
-   Code Block Component
-   ========================================================================== */
-
-.code-block {
-  margin: var(--spacing-lg) 0;
-  background-color: var(--color-code-bg);
-  border: 1px solid var(--color-code-border);
-  border-radius: 8px;
-  overflow: hidden;
-  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
-}
-
-.code-header {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  padding: var(--spacing-sm) var(--spacing-md);
-  background-color: var(--color-sidebar-bg);
-  border-bottom: 1px solid var(--color-border);
-}
-
-.code-dots {
-  display: flex;
-  gap: 6px;
-}
-
-.code-dot {
-  width: 12px;
-  height: 12px;
-  border-radius: 50%;
-}
-
-.code-dot.red {
-  background-color: #ff5f56;
-}
-
-.code-dot.yellow {
-  background-color: #ffbd2e;
-}
-
-.code-dot.green {
-  background-color: #27c93f;
-}
-
-.code-lang {
-  font-size: var(--font-size-smaller);
-  font-weight: 500;
-  color: var(--color-text-muted);
-  text-transform: uppercase;
-  letter-spacing: 0.05em;
-}
-
-.code-block pre {
-  margin: 0;
-  padding: var(--spacing-md);
-  background: none;
-  border: none;
-  overflow-x: auto;
-}
-
-.code-block pre code {
-  display: block;
-  padding: 0;
-  background: none;
-  border: none;
-  font-size: var(--font-size-small);
-  line-height: 1.6;
-  white-space: pre;
-}
-
-/* ==========================================================================
-   Lifecycle Diagram
-   ========================================================================== */
-
-.lifecycle-diagram {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  margin: var(--spacing-xl) 0;
-  padding: var(--spacing-lg);
-  background-color: var(--color-sidebar-bg);
-  border-radius: 8px;
-  border: 1px solid var(--color-border);
-}
-
-.lifecycle-step {
-  display: flex;
-  align-items: flex-start;
-  gap: var(--spacing-md);
-  width: 100%;
-  max-width: 500px;
-  padding: var(--spacing-md);
-  background-color: var(--color-background);
-  border: 1px solid var(--color-border);
-  border-radius: 6px;
-  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
-}
-
-.step-number {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  min-width: 32px;
-  height: 32px;
-  background-color: var(--color-primary);
-  color: white;
-  font-weight: 600;
-  font-size: var(--font-size-small);
-  border-radius: 50%;
-  flex-shrink: 0;
-}
-
-.step-content {
-  flex: 1;
-}
-
-.step-content h4 {
-  margin: 0 0 var(--spacing-xs);
-  font-size: 1rem;
-  color: var(--color-text);
-}
-
-.step-content p {
-  margin: 0;
-  font-size: var(--font-size-small);
-  color: var(--color-text-muted);
-}
-
-.lifecycle-arrow {
-  font-size: 1.5rem;
-  color: var(--color-primary);
-  padding: var(--spacing-sm) 0;
-  line-height: 1;
-}
-
-/* ==========================================================================
-   Utility Classes
-   ========================================================================== */
-
-/* Text utilities */
-.text-muted {
-  color: var(--color-text-muted);
-}
-
-.text-small {
-  font-size: var(--font-size-small);
-}
-
-/* Spacing utilities */
-.mt-0 { margin-top: 0; }
-.mt-1 { margin-top: var(--spacing-sm); }
-.mt-2 { margin-top: var(--spacing-md); }
-.mt-3 { margin-top: var(--spacing-lg); }
-.mt-4 { margin-top: var(--spacing-xl); }
-
-.mb-0 { margin-bottom: 0; }
-.mb-1 { margin-bottom: var(--spacing-sm); }
-.mb-2 { margin-bottom: var(--spacing-md); }
-.mb-3 { margin-bottom: var(--spacing-lg); }
-.mb-4 { margin-bottom: var(--spacing-xl); }
-
-/* ==========================================================================
-   Responsive Design
-   ========================================================================== */
-
-/* Tablet and smaller */
-@media (max-width: 1024px) {
-  :root {
-    --sidebar-width: 240px;
-    --content-padding: 1.5rem;
-  }
-}
-
-/* Mobile */
-@media (max-width: 768px) {
-  :root {
-    --sidebar-width: 100%;
-    --content-padding: 1rem;
-  }
-
-  .docs-sidebar {
-    transform: translateX(-100%);
-    transition: transform var(--transition-normal);
-    width: 280px;
-    max-width: 85vw;
-  }
-
-  .docs-sidebar.open {
-    transform: translateX(0);
-  }
-
-  .nav-sidebar {
-    transform: translateX(-100%);
-    transition: transform var(--transition-normal);
-    width: 280px;
-    max-width: 85vw;
-  }
-
-  .nav-sidebar.open {
-    transform: translateX(0);
-  }
-
-  .docs-main {
-    margin-left: 0;
-  }
-
-  /* Mobile menu toggle */
-  .docs-menu-toggle {
-    position: fixed;
-    top: var(--spacing-md);
-    left: var(--spacing-md);
-    z-index: 101;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    width: 40px;
-    height: 40px;
-    padding: 0;
-    background-color: var(--color-background);
-    border: 1px solid var(--color-border);
-    border-radius: 6px;
-    cursor: pointer;
-    transition: background-color var(--transition-fast);
-  }
-
-  .docs-menu-toggle:hover {
-    background-color: var(--color-hover-bg);
-  }
-
-  .docs-menu-toggle::before {
-    content: "";
-    display: block;
-    width: 18px;
-    height: 2px;
-    background-color: var(--color-text);
-    box-shadow: 0 -5px 0 var(--color-text), 0 5px 0 var(--color-text);
-  }
-
-  /* Overlay when sidebar is open */
-  .docs-overlay {
-    position: fixed;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    background-color: rgba(0, 0, 0, 0.5);
-    z-index: 99;
-    opacity: 0;
-    visibility: hidden;
-    transition: opacity var(--transition-normal), visibility var(--transition-normal);
-  }
-
-  .docs-overlay.visible {
-    opacity: 1;
-    visibility: visible;
-  }
-
-  /* Adjust typography for mobile */
-  h1 {
-    font-size: 1.75rem;
-  }
-
-  h2 {
-    font-size: 1.35rem;
-  }
-
-  h3 {
-    font-size: 1.15rem;
-  }
-
-  /* Scrollable tables on mobile */
-  table {
-    display: block;
-    overflow-x: auto;
-    -webkit-overflow-scrolling: touch;
-  }
-
-  /* Home page mobile adjustments */
-  .main-content {
-    margin-left: 0;
-  }
-
-  .hero-title {
-    font-size: 2rem;
-  }
-
-  .hero-tagline {
-    font-size: 1rem;
-  }
-
-  .quick-links {
-    grid-template-columns: 1fr;
-  }
-}
-
-/* Hide mobile menu toggle on desktop */
-@media (min-width: 769px) {
-  .docs-menu-toggle,
-  .docs-overlay {
-    display: none;
-  }
-}
-
-/* ==========================================================================
-   Print Styles
-   ========================================================================== */
-
-@media print {
-  .docs-sidebar,
-  .nav-sidebar,
-  .docs-menu-toggle,
-  .docs-overlay {
-    display: none !important;
-  }
-
-  .docs-main {
-    margin-left: 0 !important;
-  }
-
-  .docs-content {
-    max-width: none !important;
-    padding: 0 !important;
-  }
-
-  a {
-    color: var(--color-text) !important;
-    text-decoration: underline;
-  }
-
-  pre,
-  code {
-    border: none !important;
-    background-color: transparent !important;
-  }
-}

+ 0 - 41
demo/meson.build

@@ -1,41 +0,0 @@
-# Spry Framework Website
-# A modern, techy website showcasing the Spry framework and its ecosystem
-
-website_sources = files(
-    'Main.vala',
-    'MainTemplate.vala',
-    'Pages/HomePage.vala',
-    'Pages/ComponentsOverviewPage.vala',
-    'Pages/ComponentsTemplateSyntaxPage.vala',
-    'Pages/ComponentsActionsPage.vala',
-    'Pages/ComponentsOutletsPage.vala',
-    'Pages/ComponentsContinuationsPage.vala',
-    'Pages/PageComponentsOverviewPage.vala',
-    'Pages/PageTemplatesPage.vala',
-    'Pages/StaticResourcesOverviewPage.vala',
-    'Pages/ComponentsMkconstPage.vala',
-    'Pages/StaticResourcesMkssrPage.vala',
-    'Components/CodeBlockComponent.vala',
-    'Components/DemoHostComponent.vala',
-    'Components/NavSidebarComponent.vala',
-    'DemoComponents/SimpleCounterDemo.vala',
-    'DemoComponents/TodoListDemo.vala',
-    'DemoComponents/ProgressDemo.vala',
-)
-
-# Generate Vala resource file from CSS
-docs_css_resource = custom_target('docs-css-resource',
-    input: 'Static/docs.css',
-    output: 'DocsCssResource.vala',
-    command: [spry_mkssr, '--vala', '--ns=Demo.Static', '-n', 'docs.css', '-c', 'text/css', '-o', '@OUTPUT@', '@INPUT@']
-)
-
-# Math library for particle physics (sin/cos in explode function)
-m_dep = meson.get_compiler('c').find_library('m', required: false)
-
-executable('spry-demo',
-    website_sources,
-    docs_css_resource,
-    dependencies: [spry_dep, astralis_dep, invercargill_dep, inversion_dep, m_dep,invercargill_sql_dep, sqlite_dep, invercargill_sql_inversion_dep],
-    install: true
-)

+ 0 - 138
examples/ContentInjectionExample.vala

@@ -1,138 +0,0 @@
-using Astralis;
-using Invercargill;
-using Invercargill.DataStructures;
-using Inversion;
-using Spry;
-
-/**
- * CardComponent: A wrapper component that accepts content via spry-content.
- *
- * The <spry-content/> tag acts as a placeholder where parent components
- * can inject their own content. When a parent uses:
- *
- *   <spry-component name="CardComponent" sid="my-card">
- *     ...content here...
- *   </spry-component>
- *
- * The nested content replaces the <spry-content/> tag in the rendered output.
- */
-class CardComponent : Component {
-    public override string markup { get {
-        return """
-        <div class="card" style="border: 2px solid #3b82f6; border-radius: 8px; padding: 20px; margin: 16px 0; background-color: #f8fafc;">
-            <spry-content/>
-        </div>
-        """;
-    }}
-}
-
-/**
- * AlertComponent: Another wrapper component styled for warnings/info.
- *
- * This demonstrates that spry-content can be used in multiple components
- * with different styling. The content injection works the same way -
- * whatever is nested inside the spry-component tag gets placed where
- * <spry-content/> appears.
- */
-class AlertComponent : Component {
-    public override string markup { get {
-        return """
-        <div class="alert" style="border-left: 4px solid #f59e0b; background-color: #fffbeb; padding: 16px; margin: 16px 0; border-radius: 4px;">
-            <spry-content/>
-        </div>
-        """;
-    }}
-}
-
-/**
- * PageComponent: The main page layout that uses CardComponent and AlertComponent.
- *
- * This component demonstrates content injection by nesting different content
- * inside each wrapper component. The nested HTML (headings, paragraphs, etc.)
- * will be injected where <spry-content/> appears in each child component.
- */
-class PageComponent : Component {
-    public override string markup { get {
-        return """
-        <!DOCTYPE html>
-        <html>
-        <head>
-            <title>Content Injection Example</title>
-            <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"></script>
-            <style>
-                body { font-family: system-ui, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
-                h1 { color: #1e293b; }
-            </style>
-        </head>
-        <body>
-            <h1>Spry Content Injection Example</h1>
-            <p>This page demonstrates the <code>spry-content</code> tag for injecting content into child components.</p>
-
-            <!-- Card with welcome content -->
-            <spry-component name="CardComponent" sid="welcome-card">
-                <h2 style="margin-top: 0; color: #1e40af;">Welcome!</h2>
-                <p>This content is injected into the CardComponent. The blue border and padding come from the component's styling.</p>
-                <p>Any HTML can be placed here - forms, images, other components, etc.</p>
-            </spry-component>
-
-            <!-- Alert with info message -->
-            <spry-component name="AlertComponent" sid="info-alert">
-                <span><strong>Notice:</strong> This is an informational alert. The yellow styling and left border come from AlertComponent.</span>
-            </spry-component>
-
-            <!-- Another card with different content -->
-            <spry-component name="CardComponent" sid="features-card">
-                <h2 style="margin-top: 0; color: #1e40af;">Features</h2>
-                <ul>
-                    <li>Components can be reused with different content</li>
-                    <li>Styling is encapsulated in the wrapper component</li>
-                    <li>Content is flexible and parent-controlled</li>
-                </ul>
-            </spry-component>
-
-            <!-- Alert with warning -->
-            <spry-component name="AlertComponent" sid="warning-alert">
-                <span><strong>Warning:</strong> This demonstrates another use of AlertComponent with completely different content.</span>
-            </spry-component>
-        </body>
-        </html>
-        """;
-    }}
-}
-
-/**
- * HomePageEndpoint: Serves the PageComponent.
- */
-class HomePageEndpoint : Object, Endpoint {
-
-    private PageComponent page_component = inject<PageComponent>();
-
-    public async Astralis.HttpResult handle_request(Astralis.HttpContext http_context, Astralis.RouteContext route_context) throws Error {
-        return yield page_component.to_result();
-    }
-}
-
-
-void main(string[] args) {
-    int port = args.length > 1 ? int.parse(args[1]) : 8080;
-
-    try {
-        var application = new WebApplication(port);
-
-        application.use_compression();
-
-        application.add_module<SpryModule>();
-
-        application.add_transient<CardComponent>();
-        application.add_transient<AlertComponent>();
-        application.add_transient<PageComponent>();
-
-        application.add_endpoint<HomePageEndpoint>(new EndpointRoute("/"));
-
-        application.run();
-
-    } catch (Error e) {
-        printerr("Error: %s\n", e.message);
-        Process.exit(1);
-    }
-}

+ 0 - 577
examples/CounterComponent.vala

@@ -1,577 +0,0 @@
-using Astralis;
-using Invercargill;
-using Invercargill.DataStructures;
-using Inversion;
-using Spry;
-
-/**
- * CounterComponent Example
- * 
- * Demonstrates using the Spry.Component class with IoC composition and HTMX.
- * Shows how to:
- *   - Define Component subclasses with embedded HTML markup
- *   - Use spry-outlet elements for dynamic content injection
- *   - Use inject<T>() for dependency injection
- *   - Use ComponentFactory to create component instances
- *   - Use spry-action and spry-target for declarative HTMX interactions
- *   - Use handle_action() for action handling
- * 
- * Usage: counter-component [port]
- */
-
-/**
- * AppState - Application state registered as singleton.
- */
-class AppState : Object {
-    public int counter { get; set; }
-    public int total_changes { get; set; }
-    public string last_action { get; set; }
-    public DateTime last_update { get; set; }
-    
-    public AppState() {
-        counter = 0;
-        total_changes = 0;
-        last_action = "Initialized";
-        last_update = new DateTime.now_local();
-    }
-    
-    public void increment() {
-        counter++;
-        total_changes++;
-        last_action = "Incremented";
-        last_update = new DateTime.now_local();
-    }
-    
-    public void decrement() {
-        counter--;
-        total_changes++;
-        last_action = "Decremented";
-        last_update = new DateTime.now_local();
-    }
-    
-    public void reset() {
-        counter = 0;
-        total_changes++;
-        last_action = "Reset";
-        last_update = new DateTime.now_local();
-    }
-}
-
-/**
- * CSS content for the counter page.
- * Served as a FastResource for optimal performance with pre-compression.
- */
-private const string COUNTER_CSS = """
-body {
-    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
-    max-width: 700px;
-    margin: 0 auto;
-    padding: 20px;
-    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-    min-height: 100vh;
-}
-.card {
-    background: white;
-    border-radius: 12px;
-    padding: 25px;
-    margin: 15px 0;
-    box-shadow: 0 10px 40px rgba(0,0,0,0.2);
-}
-h1 {
-    color: #333;
-    margin-top: 0;
-}
-.counter-display {
-    text-align: center;
-    padding: 30px;
-    background: #f8f9fa;
-    border-radius: 8px;
-    margin: 20px 0;
-}
-.counter-value {
-    font-size: 72px;
-    font-weight: bold;
-    color: #667eea;
-    line-height: 1;
-}
-.counter-label {
-    color: #666;
-    font-size: 14px;
-    text-transform: uppercase;
-    letter-spacing: 2px;
-}
-.button-group {
-    display: flex;
-    gap: 10px;
-    justify-content: center;
-    margin: 20px 0;
-}
-button {
-    padding: 12px 24px;
-    border: none;
-    border-radius: 6px;
-    cursor: pointer;
-    font-size: 16px;
-    font-weight: 600;
-    transition: all 0.2s;
-}
-button:hover {
-    transform: translateY(-2px);
-    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
-}
-.btn-primary {
-    background: #667eea;
-    color: white;
-}
-.btn-primary:hover {
-    background: #5a6fd6;
-}
-.btn-danger {
-    background: #e74c3c;
-    color: white;
-}
-.btn-danger:hover {
-    background: #c0392b;
-}
-.btn-success {
-    background: #2ecc71;
-    color: white;
-}
-.btn-success:hover {
-    background: #27ae60;
-}
-.info-grid {
-    display: grid;
-    grid-template-columns: repeat(2, 1fr);
-    gap: 15px;
-    margin: 20px 0;
-}
-.info-item {
-    background: #f8f9fa;
-    padding: 15px;
-    border-radius: 6px;
-    text-align: center;
-}
-.info-label {
-    font-size: 12px;
-    color: #666;
-    text-transform: uppercase;
-    letter-spacing: 1px;
-}
-.info-value {
-    font-size: 18px;
-    font-weight: 600;
-    color: #333;
-    margin-top: 5px;
-}
-.status-positive {
-    color: #2ecc71 !important;
-}
-.status-negative {
-    color: #e74c3c !important;
-}
-.status-zero {
-    color: #666 !important;
-}
-code {
-    background: #e8e8e8;
-    padding: 2px 6px;
-    border-radius: 4px;
-    font-size: 14px;
-}
-pre {
-    background: #263238;
-    color: #aed581;
-    padding: 15px;
-    border-radius: 6px;
-    overflow-x: auto;
-    font-size: 13px;
-}
-.feature-list {
-    margin: 0;
-    padding-left: 20px;
-}
-.feature-list li {
-    margin: 8px 0;
-    color: #555;
-}
-a {
-    color: #667eea;
-    text-decoration: none;
-}
-a:hover {
-    text-decoration: underline;
-}
-""";
-
-/**
- * InfoItemComponent - A single info grid item.
- */
-class InfoItemComponent : Component {
-    public override string markup { get {
-        return """
-        <div class="info-item">
-            <div class="info-label" sid="label"></div>
-            <div class="info-value" sid="value"></div>
-        </div>
-        """;
-    }}
-
-    public string label { set {
-        this["label"].text_content = value;
-    }}
-
-    public string info_value { set {
-        this["value"].text_content = value;
-    }}
-
-    public string? status_class { set {
-        var el = this["value"];
-        if (value != null) {
-            el.add_class(value);
-        }
-    }}
-}
-
-/**
- * InfoGridComponent - Container for info items.
- */
-class InfoGridComponent : Component {
-    
-    public void set_items(Enumerable<Renderable> items) {
-        set_outlet_children("items", items);
-    }
-    
-    public override string markup { get {
-        return """
-        <div class="info-grid">
-            <spry-outlet sid="items"/>
-        </div>
-        """;
-    }}
-}
-
-/**
- * CounterDisplayComponent - Shows the counter value with HTMX buttons.
- * Uses declarative spry-action and spry-target attributes.
- */
-class CounterDisplayComponent : Component {
-    private ComponentFactory factory = inject<ComponentFactory>();
-    private AppState app_state = inject<AppState>();
-    
-    public void set_info_items(Enumerable<Renderable> items) throws Error {
-        var info_grid = factory.create<InfoGridComponent>();
-        info_grid.set_items(items);
-        set_outlet_child("info-grid", info_grid);
-    }
-    
-    public override string markup { get {
-        return """
-        <div class="card" sid="counter-card">
-            <div class="counter-display">
-                <div class="counter-label">Current Value</div>
-                <div class="counter-value" sid="counter-value">0</div>
-            </div>
-            <div class="button-group">
-                <button type="button" class="btn-danger" sid="decrement-btn" spry-action=":Decrement" spry-target="counter-card" hx-swap="outerHTML">- Decrease</button>
-                <button type="button" class="btn-primary" sid="reset-btn" spry-action=":Reset" spry-target="counter-card" hx-swap="outerHTML">Reset</button>
-                <button type="button" class="btn-success" sid="increment-btn" spry-action=":Increment" spry-target="counter-card" hx-swap="outerHTML">+ Increase</button>
-            </div>
-            <spry-outlet sid="info-grid"/>
-        </div>
-        """;
-    }}
-    
-    public async override void handle_action(string action) throws Error {
-        // Update state based on action
-        switch (action) {
-            case "Increment":
-                app_state.increment();
-                break;
-            case "Decrement":
-                app_state.decrement();
-                break;
-            case "Reset":
-                app_state.reset();
-                break;
-        }
-        
-        // Update counter value
-        var counter_el = this["counter-value"];
-        counter_el.text_content = app_state.counter.to_string();
-        
-        // Update status class
-        counter_el.remove_class("status-positive");
-        counter_el.remove_class("status-negative");
-        counter_el.remove_class("status-zero");
-        
-        if (app_state.counter > 0) {
-            counter_el.add_class("status-positive");
-        } else if (app_state.counter < 0) {
-            counter_el.add_class("status-negative");
-        } else {
-            counter_el.add_class("status-zero");
-        }
-        
-        // Build info grid
-        var info_grid = factory.create<InfoGridComponent>();
-        var items = new Series<Renderable>();
-        
-        // Determine status
-        string status_text;
-        string status_class;
-        if (app_state.counter > 0) {
-            status_text = "Positive";
-            status_class = "status-positive";
-        } else if (app_state.counter < 0) {
-            status_text = "Negative";
-            status_class = "status-negative";
-        } else {
-            status_text = "Zero";
-            status_class = "status-zero";
-        }
-        
-        var status_item = factory.create<InfoItemComponent>();
-        status_item.label = "Status";
-        status_item.info_value = status_text;
-        status_item.status_class = status_class;
-        items.add(status_item);
-        
-        var action_item = factory.create<InfoItemComponent>();
-        action_item.label = "Last Action";
-        action_item.info_value = app_state.last_action;
-        items.add(action_item);
-        
-        var time_item = factory.create<InfoItemComponent>();
-        time_item.label = "Last Update";
-        time_item.info_value = app_state.last_update.format("%H:%M:%S");
-        items.add(time_item);
-        
-        var changes_item = factory.create<InfoItemComponent>();
-        changes_item.label = "Total Changes";
-        changes_item.info_value = app_state.total_changes.to_string();
-        items.add(changes_item);
-        
-        info_grid.set_items(items);
-        set_outlet_child("info-grid", info_grid);
-    }
-    
-    public int counter { set {
-        var counter_el = this["counter-value"];
-        counter_el.text_content = value.to_string();
-        
-        // Update status class
-        counter_el.remove_class("status-positive");
-        counter_el.remove_class("status-negative");
-        counter_el.remove_class("status-zero");
-        
-        if (value > 0) {
-            counter_el.add_class("status-positive");
-        } else if (value < 0) {
-            counter_el.add_class("status-negative");
-        } else {
-            counter_el.add_class("status-zero");
-        }
-    }}
-}
-
-/**
- * CounterPageComponent - The main page structure.
- */
-class CounterPageComponent : Component {
-    
-    public void set_counter_section(Renderable component) {
-        set_outlet_child("counter-section", component);
-    }
-    
-    public override string markup { get {
-        return """
-        <!DOCTYPE html>
-        <html lang="en">
-        <head>
-            <meta charset="UTF-8"/>
-            <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-            <title>Component Counter Example</title>
-            <link rel="stylesheet" href="/styles.css"/>
-            <script spry-res="htmx.js"></script>
-        </head>
-        <body>
-            <div class="card">
-                <h1>Component Counter Example</h1>
-                <p>This page demonstrates using Spry.Component with IoC composition and HTMX.</p>
-            </div>
-            <spry-outlet sid="counter-section"/>
-            <div class="card">
-                <h2>How It Works</h2>
-                <p>The counter uses declarative HTMX attributes for dynamic updates:</p>
-                <pre>&lt;button spry-action=":Increment" spry-target="counter-card" hx-swap="outerHTML"&gt;+ Increase&lt;/button&gt;</pre>
-                <h3>Component Features Used:</h3>
-                <ul class="feature-list">
-                    <li><code>spry-outlet</code> - Placeholder for child components</li>
-                    <li><code>spry-action=":Action"</code> - Declarative HTMX action</li>
-                    <li><code>spry-target="sid"</code> - Target element by sid</li>
-                    <li><code>handle_action(action)</code> - Handle HTMX requests</li>
-                    <li><code>inject<ComponentFactory>()</code> - Factory for creating components</li>
-                </ul>
-            </div>
-            <div class="card">
-                <p style="text-align: center; color: #666; margin: 0;">
-                    Built with <code>Spry.Component</code> + HTMX |
-                    <a href="/raw">View Raw HTML</a>
-                </p>
-            </div>
-        </body>
-        </html>
-        """;
-    }}
-}
-
-/**
- * NoticeComponent - A simple notice for the raw view.
- */
-class NoticeComponent : Component {
-    public override string markup { get {
-        return """
-        <div class="card" style="background: #fff3cd; color: #856404; border: 1px solid #ffc107;">
-            <p>This is the raw template without dynamic modifications.</p>
-            <p><a href="/">Back to dynamic version</a></p>
-        </div>
-        """;
-    }}
-}
-
-// Home page endpoint - builds the component tree
-class HomePageEndpoint : Object, Endpoint {
-    private AppState app_state = inject<AppState>();
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public async HttpResult handle_request(HttpContext context, RouteContext route) throws Error {
-        // Determine status
-        string status_text;
-        string status_class;
-        if (app_state.counter > 0) {
-            status_text = "Positive";
-            status_class = "status-positive";
-        } else if (app_state.counter < 0) {
-            status_text = "Negative";
-            status_class = "status-negative";
-        } else {
-            status_text = "Zero";
-            status_class = "status-zero";
-        }
-        
-        // Create info items
-        var items = new Series<Renderable>();
-        
-        var status_item = factory.create<InfoItemComponent>();
-        status_item.label = "Status";
-        status_item.info_value = status_text;
-        status_item.status_class = status_class;
-        items.add(status_item);
-        
-        var action_item = factory.create<InfoItemComponent>();
-        action_item.label = "Last Action";
-        action_item.info_value = app_state.last_action;
-        items.add(action_item);
-        
-        var time_item = factory.create<InfoItemComponent>();
-        time_item.label = "Last Update";
-        time_item.info_value = app_state.last_update.format("%H:%M:%S");
-        items.add(time_item);
-        
-        var changes_item = factory.create<InfoItemComponent>();
-        changes_item.label = "Total Changes";
-        changes_item.info_value = app_state.total_changes.to_string();
-        items.add(changes_item);
-        
-        // Create counter display
-        var counter_display = factory.create<CounterDisplayComponent>();
-        counter_display.counter = app_state.counter;
-        counter_display.set_info_items(items);
-        
-        // Create page and set counter section
-        var page = factory.create<CounterPageComponent>();
-        page.set_counter_section(counter_display);
-        
-        // to_result() handles all outlet replacement
-        return yield page.to_result();
-    }
-}
-
-// Raw HTML endpoint - shows the unmodified template
-class RawHtmlEndpoint : Object, Endpoint {
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public async HttpResult handle_request(HttpContext context, RouteContext route) throws Error {
-        var page = factory.create<CounterPageComponent>();
-        var notice = factory.create<NoticeComponent>();
-        
-        // Add a notice component
-        page.set_counter_section(notice);
-        
-        return yield page.to_result();
-    }
-}
-
-void main(string[] args) {
-    int port = args.length > 1 ? int.parse(args[1]) : 8080;
-    
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("            Spry CounterComponent Example (IoC + HTMX)\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  Port: %d\n", port);
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  Endpoints:\n");
-    print("    /           - Counter page (Component-based with HTMX)\n");
-    print("    /styles.css - CSS stylesheet (FastResource)\n");
-    print("    /raw        - Raw template (no modifications)\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  HTMX Actions (via SpryModule):\n");
-    print("    Increment, Decrement, Reset - Dynamic updates\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("\nPress Ctrl+C to stop the server\n\n");
-    
-    try {
-        var application = new WebApplication(port);
-        
-        // Register compression components
-        application.use_compression();
-        
-        // Add Spry module for automatic HTMX endpoint registration
-        application.add_module<SpryModule>();
-        
-        // Register application state as singleton
-        application.add_singleton<AppState>();
-        
-        // Register ComponentFactory as scoped
-        application.add_scoped<ComponentFactory>();
-        
-        // Register components as transient (created via factory)
-        application.add_transient<InfoItemComponent>();
-        application.add_transient<InfoGridComponent>();
-        application.add_transient<CounterDisplayComponent>();
-        application.add_transient<CounterPageComponent>();
-        application.add_transient<NoticeComponent>();
-        
-        // Register CSS as a FastResource
-        application.add_startup_endpoint<FastResource>(new EndpointRoute("/styles.css"), () => {
-            try {
-                return new FastResource.from_string(COUNTER_CSS)
-                    .with_content_type("text/css; charset=utf-8")
-                    .with_default_compressors();
-            } catch (Error e) {
-                error("Failed to create CSS resource: %s", e.message);
-            }
-        });
-        
-        // Register endpoints
-        application.add_endpoint<HomePageEndpoint>(new EndpointRoute("/"));
-        application.add_endpoint<RawHtmlEndpoint>(new EndpointRoute("/raw"));
-        
-        application.run();
-        
-    } catch (Error e) {
-        printerr("Error: %s\n", e.message);
-        Process.exit(1);
-    }
-}

+ 0 - 193
examples/ProgressExample.vala

@@ -1,193 +0,0 @@
-using Astralis;
-using Invercargill;
-using Invercargill.DataStructures;
-using Inversion;
-using Spry;
-
-/**
- * ProgressExample demonstrates the continuation feature for server-sent events (SSE).
- * 
- * The continuation feature allows a Component to send real-time progress updates
- * to the client via SSE. This is useful for:
- * - Long-running task progress reporting
- * - Real-time status updates
- * - Live data streaming
- * 
- * How it works:
- * 1. Add `spry-continuation` attribute to an element in your markup
- *    (This is shorthand for: hx-ext="sse" sse-connect="(endpoint)" sse-close="_spry-close")
- * 2. Use `sse-swap="eventname"` on child elements to swap content when events arrive
- * 3. Override the `continuation(SseStream stream)` method in your Component
- * 4. Use `stream.send_event()` to send SSE events with HTML content to swap
- */
-class ProgressComponent : Component {
-    
-    public int percent { get; set; }
-    public string status { get; set; default = "Initializing..."; }
-    public Series<string> completed_tasks { get; set; default = new Series<string>(); }
-    
-    public override string markup { get {
-        return """
-        <!DOCTYPE html>
-        <html>
-        <head>
-        <script spry-res="htmx.js"></script>
-        <script spry-res="htmx-sse.js"></script>
-        <style>
-            body { font-family: system-ui, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
-            .progress-container { 
-                background: #e0e0e0; 
-                border-radius: 8px; 
-                overflow: hidden; 
-                margin: 20px 0;
-            }
-            .progress-bar { 
-                height: 30px; 
-                background: linear-gradient(90deg, #4CAF50, #8BC34A); 
-                transition: width 0.3s ease;
-                display: flex;
-                align-items: center;
-                justify-content: center;
-                color: white;
-                font-weight: bold;
-                min-width: 40px;
-            }
-            .status { 
-                padding: 15px; 
-                background: #f5f5f5; 
-                border-radius: 4px; 
-                margin: 10px 0;
-                border-left: 4px solid #2196F3;
-            }
-            .log { 
-                max-height: 200px; 
-                overflow-y: auto; 
-                background: #263238; 
-                color: #4CAF50; 
-                padding: 15px; 
-                border-radius: 4px;
-                font-family: monospace;
-                font-size: 14px;
-            }
-            .log-entry { margin: 5px 0; }
-            h1 { color: #333; }
-            .info { color: #666; font-size: 14px; }
-        </style>
-        </head>
-        <body>
-        <h1>Task Progress Demo</h1>
-        <p class="info">This example demonstrates Spry's continuation feature for real-time progress updates via Server-Sent Events (SSE).</p>
-        
-        <div spry-continuation>
-            <div class="progress-container" spry-dynamic="progress-bar">
-                <div class="progress-bar" spry-unique
-                content-expr='format("{{this.percent}}%")' style-width-expr='format("{{this.percent}}%")'>
-                    0%
-                </div>
-            </div>
-            
-            <div class="status" spry-dynamic="status">
-                <strong>Status:</strong> <span spry-unique content-expr="this.status">Initializing...</span>
-            </div>
-            
-            <div class="log" sid="log" spry-dynamic="log">
-                <div spry-per-task="this.completed_tasks" content-expr="task"></div>
-            </div>
-        </div>
-        </body>
-        </html>
-        """;
-    }}
-    
-    /**
-     * The continuation method is called when a client connects to the SSE endpoint.
-     * This is where you can send real-time updates to the client.
-     * 
-     * The event data should be HTML content that will be swapped into elements
-     * with matching sse-swap="eventname" attributes.
-     */
-    public async override void continuation(ContinuationContext continuation_context) throws Error {
-        // Simulate a long-running task with progress updates
-        var steps = new string[] {
-            "Initializing task...",
-            "Loading configuration...",
-            "Connecting to database...",
-            "Fetching records...",
-            "Processing batch 1/5...",
-            "Processing batch 2/5...",
-            "Processing batch 3/5...",
-            "Processing batch 4/5...",
-            "Processing batch 5/5...",
-            "Validating results...",
-            "Generating report...",
-            "Finalizing..."
-        };
-        
-        for (int i = 0; i < steps.length; i++) {
-            // Update the template
-            percent = (int)(((i + 1) / (double)steps.length) * 100);
-            status = steps[i];
-            completed_tasks.add_start(steps[i]);
-            
-            // Send progress bar update - HTML that will be swapped into the progress bar
-            yield continuation_context.send_dynamic("progress-bar");
-            
-            // Send status update - HTML that will be swapped into the status div
-            yield continuation_context.send_dynamic("status");
-            
-            // Send log message - HTML that will be appended to the log
-            yield continuation_context.send_dynamic("log");
-            
-            // Simulate work being done (500ms per step)
-            Timeout.add(500, () => {
-                continuation.callback();
-                return false;
-            });
-            yield;
-        }
-        
-        // Send final completion messages
-        percent = 100;
-        status = "Task completed successfully!";
-        yield continuation_context.send_dynamic("progress-bar");
-        yield continuation_context.send_dynamic("status");
-    }
-}
-
-class HomePageEndpoint : Object, Endpoint {
-
-    private ProgressComponent progress_component = inject<ProgressComponent>();
-
-    public async Astralis.HttpResult handle_request(Astralis.HttpContext http_context, Astralis.RouteContext route_context) throws Error {
-        return yield progress_component.to_result();
-    }
-}
-
-void main(string[] args) {
-    int port = args.length > 1 ? int.parse(args[1]) : 8080;
-    
-    try {
-        var application = new WebApplication(port);
-        
-        // Register compression components
-        application.use_compression();
-        
-        // Add Spry module (includes ContinuationProvider for SSE)
-        application.add_module<SpryModule>();
-
-        // Register the progress component
-        application.add_transient<ProgressComponent>();
-
-        // Register the home page endpoint
-        application.add_endpoint<HomePageEndpoint>(new EndpointRoute("/"));
-
-        print("Progress Example running on http://localhost:%d/\n", port);
-        print("Open the URL in your browser to see real-time progress updates via SSE.\n");
-        
-        application.run();
-        
-    } catch (Error e) {
-        printerr("Error: %s\n", e.message);
-        Process.exit(1);
-    }
-}

+ 0 - 120
examples/SimpleExample.vala

@@ -1,120 +0,0 @@
-using Astralis;
-using Invercargill;
-using Invercargill.DataStructures;
-using Inversion;
-using Spry;
-
-
-class TestComponent : Component {
-    public override string markup { get {
-        return """
-        <!DOCTYPE html>
-        <html>
-        <head>
-        <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"></script>
-        </head>
-        <body>
-        <h1>Hello, World!</h1>
-        <spry-outlet sid="content" />
-        </body>
-        </html>
-        """;
-    }}
-
-    public void add_content(Renderable content) {
-        add_outlet_child("content", content);
-    }
-
-}
-
-class ContentComponent : Component {
-    public override string markup { get {
-        return """
-        <p>Quia assumenda sunt qui. Voluptatibus magni exercitationem tenetur sit itaque laborum aut. Sint voluptates fugit consectetur.</p>
-        <p>Optio totam doloremque minus impedit est eum. Nisi a rerum natus. Impedit est autem culpa ullam reprehenderit sunt. Et harum odio cumque iure.</p>
-        <p>Architecto non ipsum quibusdam aut. Deleniti enim magnam aperiam voluptatibus similique dolor. Porro et aliquam et eum magnam neque praesentium.</p>
-        <p>Quod at nemo rem fugit quia nemo facere et. Fugit sed labore voluptates recusandae dolores sed. Consequatur autem sit minima sunt excepturi et fugiat voluptates. Repellat aut vero doloribus quis laborum repellat dolorem et.</p>
-        <p>Porro at id optio sit voluptatibus nulla quam. Dignissimos praesentium est dolore architecto voluptatem adipisci nostrum. In dolorum et qui distinctio. Aperiam et eligendi quod eaque.</p>
-        """;
-    }}
-
-}
-
-class MessageFormComponent : Component {
-
-    private PathProvider component_uri_provider = inject<PathProvider>();
-
-    public override string markup { get {
-        return """
-        <form sid="form" spry-action="UserContentComponent:SendMessage" spry-target="result">
-            <input type="text" name="message" placeholder="Your message here"/>
-            <input type="submit"/>
-        </form>
-        <div sid="result">
-        <em>Message will show here</em>
-        </div>
-        """;
-    }}
-
-
-}
-
-class UserContentComponent : Component {
-    public override string markup { get {
-        return """
-        <p>You said: <strong sid="message"></strong> <em>(via <span sid="action"></span>)</em></p>
-        """;
-    }}
-
-    private HttpContext http_context = inject<HttpContext>();
-
-    public async override void handle_action(string action) throws Error {
-        this["message"].text_content = http_context.request.query_params.get_any_or_default("message") ?? "No message provided!";
-        this["action"].text_content = action;
-    }
-
-}
-
-class HomePageEndpoint : Object, Endpoint {
-
-    private TestComponent test_component = inject<TestComponent>();
-    private ContentComponent content_component = inject<ContentComponent>();
-    private MessageFormComponent message_form = inject<MessageFormComponent>();
-
-    public async Astralis.HttpResult handle_request(Astralis.HttpContext http_context, Astralis.RouteContext route_context) throws Error {
-        test_component.add_content(content_component);
-        test_component.add_content(message_form);
-        return yield test_component.to_result();
-    }
-}
-
-
-void main(string[] args) {
-    int port = args.length > 1 ? int.parse(args[1]) : 8080;
-
-    
-    try {
-        var application = new WebApplication(port);
-        
-        // Register compression components
-        application.use_compression();
-        
-        // Add Spry
-        application.add_module<SpryModule>();
-
-        // Register components
-        application.add_transient<TestComponent>();
-        application.add_transient<ContentComponent>();
-        application.add_transient<MessageFormComponent>();
-        application.add_transient<UserContentComponent>();
-
-        // Register endpoints
-        application.add_endpoint<HomePageEndpoint>(new EndpointRoute("/"));
-
-        application.run();
-        
-    } catch (Error e) {
-        printerr("Error: %s\n", e.message);
-        Process.exit(1);
-    }
-}

+ 0 - 692
examples/TemplateExample.vala

@@ -1,692 +0,0 @@
-using Astralis;
-using Invercargill;
-using Invercargill.DataStructures;
-using Inversion;
-using Spry;
-
-/**
- * TemplateExample.vala - Demonstrates PageComponent and PageTemplate usage
- * 
- * This example shows how to create template-based pages where:
- * - MainLayoutTemplate provides the base HTML structure with header and footer
- * - AdminSectionTemplate adds an admin navigation sidebar (nested template)
- * - PageComponents render their content into template outlets
- * 
- * Route structure:
- *   /              -> HomePage (uses MainLayoutTemplate)
- *   /about         -> AboutPage (uses MainLayoutTemplate)
- *   /admin         -> AdminDashboardPage (uses AdminSectionTemplate -> MainLayoutTemplate)
- *   /admin/users   -> AdminUsersPage (uses AdminSectionTemplate -> MainLayoutTemplate)
- */
-
-// =============================================================================
-// STYLESHEETS - CSS content served as FastResources
-// =============================================================================
-
-/**
- * Main CSS - Base styles for all pages
- */
-private const string MAIN_CSS = """
-/* Base Reset & Layout */
-* { box-sizing: border-box; margin: 0; padding: 0; }
-html, body {
-    height: 100%;
-}
-body {
-    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
-    line-height: 1.6;
-    background: #f5f7fa;
-    display: flex;
-    flex-direction: column;
-    min-height: 100vh;
-}
-
-/* Header */
-header {
-    background: #2c3e50;
-    color: white;
-    padding: 1rem 2rem;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    flex-shrink: 0;
-}
-header nav a {
-    color: white;
-    margin-right: 1.5rem;
-    text-decoration: none;
-    font-weight: 500;
-    transition: opacity 0.2s;
-}
-header nav a:hover { opacity: 0.8; }
-header nav a:last-child { margin-right: 0; }
-header .visit-info {
-    font-size: 0.85rem;
-    opacity: 0.8;
-}
-
-/* Main Content - grows to fill space */
-main.container {
-    flex: 1;
-    max-width: 1200px;
-    width: 100%;
-    margin: 0 auto;
-    padding: 2rem 1rem;
-}
-
-/* Cards */
-.card {
-    background: white;
-    border-radius: 12px;
-    padding: 2rem;
-    margin-bottom: 1.5rem;
-    box-shadow: 0 2px 8px rgba(0,0,0,0.08);
-}
-
-/* Typography */
-h1 { color: #2c3e50; margin-bottom: 1rem; }
-h2 { color: #34495e; margin-bottom: 0.75rem; margin-top: 1.5rem; }
-h3 { color: #34495e; margin-bottom: 0.5rem; margin-top: 1rem; }
-p { color: #555; margin-bottom: 1rem; }
-ul, ol { margin-left: 1.5rem; margin-bottom: 1rem; }
-li { margin-bottom: 0.5rem; color: #555; }
-
-/* Links */
-a { color: #3498db; text-decoration: none; transition: color 0.2s; }
-a:hover { color: #2980b9; text-decoration: underline; }
-
-/* Code */
-code {
-    background: #f0f0f0;
-    padding: 0.2rem 0.5rem;
-    border-radius: 4px;
-    font-size: 0.9em;
-    color: #e74c3c;
-}
-pre {
-    background: #263238;
-    color: #aed581;
-    padding: 1rem;
-    border-radius: 8px;
-    overflow-x: auto;
-    font-size: 0.9rem;
-    margin: 1rem 0;
-}
-
-/* Footer - at bottom */
-footer {
-    background: #2c3e50;
-    color: rgba(255,255,255,0.7);
-    padding: 1.5rem;
-    text-align: center;
-    flex-shrink: 0;
-}
-
-/* Buttons & Forms */
-button {
-    background: #3498db;
-    color: white;
-    border: none;
-    padding: 0.75rem 1.5rem;
-    border-radius: 6px;
-    cursor: pointer;
-    font-size: 1rem;
-    font-weight: 500;
-    transition: all 0.2s;
-}
-button:hover {
-    background: #2980b9;
-}
-input[type="text"] {
-    padding: 0.75rem;
-    border: 2px solid #e0e0e0;
-    border-radius: 6px;
-    font-size: 1rem;
-    transition: border-color 0.2s;
-}
-input[type="text"]:focus {
-    outline: none;
-    border-color: #3498db;
-}
-""";
-
-/**
- * Admin CSS - Additional styles for admin section
- */
-private const string ADMIN_CSS = """
-/* Admin Section Layout */
-.admin-section {
-    display: flex;
-    gap: 2rem;
-}
-
-/* Admin Sidebar */
-.admin-sidebar {
-    width: 220px;
-    background: #34495e;
-    padding: 1.5rem;
-    border-radius: 12px;
-    flex-shrink: 0;
-}
-.admin-sidebar h3 {
-    color: white;
-    margin-bottom: 1rem;
-    font-size: 1.1rem;
-    border-bottom: 1px solid rgba(255,255,255,0.2);
-    padding-bottom: 0.75rem;
-}
-.admin-sidebar ul {
-    list-style: none;
-    margin: 0;
-    padding: 0;
-}
-.admin-sidebar li { margin-bottom: 0.5rem; margin-left: 0; }
-.admin-sidebar a {
-    color: rgba(255,255,255,0.7);
-    display: block;
-    padding: 0.5rem 0.75rem;
-    border-radius: 6px;
-    transition: all 0.2s;
-}
-.admin-sidebar a:hover {
-    color: white;
-    background: rgba(255,255,255,0.1);
-    text-decoration: none;
-}
-
-/* Admin Content Area */
-.admin-content {
-    flex: 1;
-    min-width: 0;
-}
-
-/* Dashboard Stats */
-.dashboard-stats {
-    display: flex;
-    gap: 1.5rem;
-    flex-wrap: wrap;
-}
-.stat-card {
-    background: #3498db;
-    color: white;
-    padding: 1.5rem;
-    border-radius: 12px;
-    min-width: 180px;
-}
-.stat-card h3 {
-    color: rgba(255,255,255,0.9);
-    font-size: 0.85rem;
-    text-transform: uppercase;
-    letter-spacing: 1px;
-    margin: 0 0 0.5rem 0;
-}
-.stat-card .stat-value {
-    font-size: 2.5rem;
-    font-weight: bold;
-}
-
-/* User List */
-.user-list {
-    margin: 1.5rem 0;
-}
-.user-item {
-    display: flex;
-    align-items: center;
-    gap: 1rem;
-    padding: 1rem 1.25rem;
-    background: #f8f9fa;
-    margin-bottom: 0.75rem;
-    border-radius: 8px;
-    transition: background 0.2s;
-}
-.user-item:hover {
-    background: #e9ecef;
-}
-.user-item .user-name {
-    flex: 1;
-    font-weight: 500;
-    color: #2c3e50;
-}
-.user-item .user-status {
-    color: #27ae60;
-    font-size: 0.9rem;
-    font-weight: 500;
-}
-
-/* Add Form */
-.add-form {
-    display: flex;
-    gap: 0.75rem;
-    margin-top: 1.5rem;
-}
-.add-form input[type="text"] {
-    flex: 1;
-    max-width: 300px;
-}
-
-/* Navigation Links */
-.nav-link {
-    display: inline-block;
-    margin-top: 1.5rem;
-    color: #3498db;
-    font-weight: 500;
-}
-.nav-link:hover { color: #2980b9; }
-""";
-
-// =============================================================================
-// STORES - Simple data stores for demonstration
-// =============================================================================
-
-class AppState : Object {
-    public int visit_count { get; set; }
-    public string last_visit { get; set; }
-}
-
-class UserStore : Object {
-    private Series<string> users = new Series<string>();
-
-    construct {
-        users.add("Alice");
-        users.add("Bob");
-        users.add("Charlie");
-    }
-
-    public Enumerable<string> get_all() {
-        return users;
-    }
-
-    public void add_user(string name) {
-        users.add(name);
-    }
-
-    public int count() {
-        return (int)users.length;
-    }
-}
-
-// =============================================================================
-// TEMPLATES - Provide reusable page layouts
-// =============================================================================
-
-/**
- * MainLayoutTemplate - The base template for all pages
- * 
- * Provides:
- * - HTML document structure
- * - Common <head> elements (scripts, styles)
- * - Site-wide header with navigation
- * - Site-wide footer
- * 
- * Uses <spry-content> where child content/templates will be inserted
- */
-class MainLayoutTemplate : PageTemplate {
-    
-    private AppState app_state = inject<AppState>();
-    
-    public override string markup { get {
-        return """
-        <!DOCTYPE html>
-        <html lang="en">
-        <head>
-            <meta charset="UTF-8">
-            <meta name="viewport" content="width=device-width, initial-scale=1.0">
-            <title>Spry Template Example</title>
-            <link rel="stylesheet" href="/styles/main.css">
-            <script spry-res="htmx.js"></script>
-        </head>
-        <body>
-            <header>
-                <nav>
-                    <a href="/">Home</a>
-                    <a href="/about">About</a>
-                    <a href="/admin">Admin</a>
-                </nav>
-                <small class="visit-info" sid="visit-info"></small>
-            </header>
-            <main class="container">
-                <spry-content />
-            </main>
-            <footer>
-                <p>Built with Spry Framework - Template Example</p>
-            </footer>
-        </body>
-        </html>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        this["visit-info"].text_content = @"Visits: $(app_state.visit_count) | Last: $(app_state.last_visit)";
-    }
-}
-
-/**
- * AdminSectionTemplate - A nested template for admin pages
- * 
- * This template is applied to routes starting with /admin
- * It adds an admin sidebar navigation around the page content
- * 
- * Templates are applied in order of rank (based on prefix length):
- * 1. MainLayoutTemplate (rank 0, prefix "") - outermost
- * 2. AdminSectionTemplate (rank 1, prefix "/admin") - nested inside main
- * 3. PageComponent - innermost content
- */
-class AdminSectionTemplate : PageTemplate {
-    
-    public override string markup { get {
-        return """
-        <head>
-            <link rel="stylesheet" href="/styles/admin.css">
-        </head>
-        <div class="admin-section">
-            <aside class="admin-sidebar">
-                <h3>Admin Menu</h3>
-                <ul>
-                    <li><a href="/admin">Dashboard</a></li>
-                    <li><a href="/admin/users">Users</a></li>
-                </ul>
-            </aside>
-            <div class="admin-content">
-                <spry-content />
-            </div>
-        </div>
-        """;
-    }}
-}
-
-// =============================================================================
-// PAGE COMPONENTS - Render content into templates
-// =============================================================================
-
-/**
- * HomePage - The main landing page
- * 
- * Extends PageComponent (not Component) to automatically use template rendering
- * The handle_request method in PageComponent:
- * 1. Finds all matching templates (MainLayoutTemplate matches "")
- * 2. Renders each template in order
- * 3. Inserts each rendered content into the previous template's outlet
- */
-class HomePage : PageComponent {
-    
-    public override string title { get { return "Home"; } }
-    
-    private AppState app_state = inject<AppState>();
-    
-    public const string ROUTE = "/";
-    
-    public override string markup { get {
-        return """
-        <div class="card" sid="home">
-            <h1>Welcome to Spry!</h1>
-            <p>This example demonstrates template-based pages using <code>PageComponent</code> and <code>PageTemplate</code>.</p>
-            
-            <h2>Features</h2>
-            <ul>
-                <li><strong>MainLayoutTemplate</strong> - Provides base HTML, header, footer</li>
-                <li><modulestrong>AdminSectionTemplate</strong> - Adds sidebar for /admin/* routes</li>
-                <li><strong>PageComponent</strong> - Pages automatically inherit templates</li>
-            </ul>
-            
-            <h2>Try These Pages</h2>
-            <ul>
-                <li><a href="/about">About Page</a> - Uses main layout only</li>
-                <li><a href="/admin">Admin Dashboard</a> - Uses admin template + main layout</li>
-                <li><a href="/admin/users">Admin Users</a> - Interactive user list</li>
-            </ul>
-            
-            <p sid="visit-count"></p>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        app_state.visit_count++;
-        app_state.last_visit = new DateTime.now_local().format("%H:%M:%S");
-        this["visit-count"].text_content = @"You have visited $(app_state.visit_count) times.";
-    }
-}
-
-/**
- * AboutPage - A simple about page
- */
-class AboutPage : PageComponent {
-    
-    public override string title { get { return "About"; } }
-    
-    public const string ROUTE = "/about";
-    
-    public override string markup { get {
-        return """
-        <div class="card">
-            <h1>About Spry Templates</h1>
-            
-            <h2>How Templates Work</h2>
-            <p>Templates use <code><spry-content /></code> to define where child content will be inserted.</p>
-            
-            <h3>Template Resolution</h3>
-            <p>When a <code>PageComponent</code> handles a request:</p>
-            <ol>
-                <li>It finds all registered <code>PageTemplate</code>s matching the route</li>
-                <li>Templates are ordered by their prefix length (rank)</li>
-                <li>Each template is rendered, with content nested into outlets</li>
-            </ol>
-            
-            <h3>Route Matching</h3>
-            <pre>
-Prefix "" matches all routes
-Prefix "/admin" matches /admin and /admin/*
-Prefix "/admin/users" matches /admin/users only
-            </pre>
-            
-            <a href="/" class="nav-link">Back to Home</a>
-        </div>
-        """;
-    }}
-}
-
-/**
- * AdminDashboardPage - Admin dashboard with statistics
- */
-class AdminDashboardPage : PageComponent {
-    
-    public override string title { get { return "Admin Dashboard"; } }
-    
-    private UserStore user_store = inject<UserStore>();
-    
-    public const string ROUTE = "/admin";
-    
-    public override string markup { get {
-        return """
-        <div class="card">
-            <h1>Admin Dashboard</h1>
-            
-            <div class="dashboard-stats">
-                <div class="stat-card">
-                    <h3>Total Users</h3>
-                    <div class="stat-value" sid="user-count"></div>
-                </div>
-            </div>
-            
-            <a href="/" class="nav-link">Back to Home</a>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        this["user-count"].text_content = user_store.count().to_string();
-    }
-}
-
-/**
- * AdminUsersPage - Admin page with interactive user list
- * 
- * Demonstrates HTMX interactions within a templated page.
- * The form targets the card with outerHTML swap so the entire card
- * is replaced with the updated content.
- */
-class AdminUsersPage : PageComponent {
-    
-    public override string title { get { return "User Management"; } }
-    
-    private UserStore user_store = inject<UserStore>();
-    private ComponentFactory factory = inject<ComponentFactory>();
-    private HttpContext http_context = inject<HttpContext>();
-    
-    public const string ROUTE = "/admin/users";
-    
-    public override string markup { get {
-        return """
-        <div class="card" sid="users-card">
-            <h1>User Management</h1>
-            
-            <div class="user-list">
-                <spry-outlet sid="user-list"/>
-            </div>
-            
-            <form class="add-form" sid="add-form" spry-action=":AddUser" spry-target="users-card" hx-swap="outerHTML">
-                <input type="text" name="username" placeholder="Enter username" required>
-                <button type="submit">Add User</button>
-            </form>
-            
-            <a href="/admin" class="nav-link">Back to Dashboard</a>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        refresh_user_list();
-    }
-    
-    private void refresh_user_list() throws Error {
-        var users = user_store.get_all();
-        var items = new Series<Renderable>();
-        
-        users.iterate((name) => {
-            var item = factory.create<UserItemComponent>();
-            item.username = name;
-            items.add(item);
-        });
-        
-        set_outlet_children("user-list", items);
-    }
-    
-    public async override void handle_action(string action) throws Error {
-        if (action == "AddUser") {
-            var username = http_context.request.query_params.get_any_or_default("username");
-            if (username != null && username.length > 0) {
-                user_store.add_user(username);
-            }
-            refresh_user_list();
-        }
-    }
-}
-
-/**
- * UserItemComponent - Individual user item in the list
- */
-class UserItemComponent : Component {
-    
-    public string username { set; get; }
-    
-    public override string markup { get {
-        return """
-        <div class="user-item" sid="user-item">
-            <span class="user-name" sid="name"></span>
-            <span class="user-status">Active</span>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        this["name"].text_content = username;
-    }
-}
-
-// =============================================================================
-// APPLICATION SETUP
-// =============================================================================
-
-void main(string[] args) {
-    int port = args.length > 1 ? int.parse(args[1]) : 8080;
-    
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("            Spry Template Example (PageComponent + PageTemplate)\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  Port: %d\n", port);
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  Endpoints:\n");
-    print("    /              - Home page (MainLayoutTemplate)\n");
-    print("    /about         - About page (MainLayoutTemplate)\n");
-    print("    /admin         - Admin dashboard (AdminSectionTemplate)\n");
-    print("    /admin/users   - User management (AdminSectionTemplate)\n");
-    print("    /styles/main.css  - Main stylesheet (FastResource)\n");
-    print("    /styles/admin.css - Admin stylesheet (FastResource)\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("\nPress Ctrl+C to stop the server\n\n");
-    
-    try {
-        var application = new WebApplication(port);
-        
-        // Enable compression
-        application.use_compression();
-        
-        // Add Spry module for component actions
-        application.add_module<SpryModule>();
-        
-        // Register stores as singletons
-        application.add_singleton<AppState>();
-        application.add_singleton<UserStore>();
-        
-        // Register templates with route prefixes
-        // MainLayoutTemplate applies to ALL routes (empty prefix)
-        var spry_cfg = application.configure_with<SpryConfigurator>();
-        spry_cfg.add_template<MainLayoutTemplate>("");
-
-        // AdminSectionTemplate applies to /admin/* routes
-        spry_cfg.add_template<AdminSectionTemplate>("/admin");
-        
-        // Register page components as endpoints
-        application.add_transient<HomePage>();
-        application.add_endpoint<HomePage>(new EndpointRoute(HomePage.ROUTE));
-        
-        application.add_transient<AboutPage>();
-        application.add_endpoint<AboutPage>(new EndpointRoute(AboutPage.ROUTE));
-        
-        application.add_transient<AdminDashboardPage>();
-        application.add_endpoint<AdminDashboardPage>(new EndpointRoute(AdminDashboardPage.ROUTE));
-        
-        application.add_transient<AdminUsersPage>();
-        application.add_endpoint<AdminUsersPage>(new EndpointRoute(AdminUsersPage.ROUTE));
-        
-        // Register child components
-        application.add_transient<UserItemComponent>();
-        
-        // Register CSS as FastResources
-        application.add_startup_endpoint<FastResource>(new EndpointRoute("/styles/main.css"), () => {
-            try {
-                return new FastResource.from_string(MAIN_CSS)
-                    .with_content_type("text/css; charset=utf-8")
-                    .with_default_compressors();
-            } catch (Error e) {
-                error("Failed to create main CSS resource: %s", e.message);
-            }
-        });
-        
-        application.add_startup_endpoint<FastResource>(new EndpointRoute("/styles/admin.css"), () => {
-            try {
-                return new FastResource.from_string(ADMIN_CSS)
-                    .with_content_type("text/css; charset=utf-8")
-                    .with_default_compressors();
-            } catch (Error e) {
-                error("Failed to create admin CSS resource: %s", e.message);
-            }
-        });
-        
-        application.run();
-        
-    } catch (Error e) {
-        printerr("Error: %s\n", e.message);
-        Process.exit(1);
-    }
-}

+ 0 - 488
examples/TodoComponent.vala

@@ -1,488 +0,0 @@
-using Astralis;
-using Invercargill;
-using Invercargill.DataStructures;
-using Inversion;
-using Spry;
-
-/**
- * TodoComponent Example
- * 
- * Demonstrates using the Spry.Component class with IoC composition.
- * Shows how to:
- *   - Build a complete CRUD interface with Components
- *   - Use <spry-component name="MyComponent"> for declarative child components
- *   - Use get_component_child<T>(sid) to access child components
- *   - Use <spry-outlet> for dynamic lists (multiple items from data)
- *   - Use inject<T>() for dependency injection
- *   - Use spry-action and spry-target for declarative HTMX interactions
- *   - Use handle_action() for action handling
- * 
- * Usage: todo-component [port]
- */
-
-/**
- * TodoItem - Simple task model for our todo list.
- */
-class TodoItem : Object {
-    public int id { get; set; }
-    public string title { get; set; }
-    public bool completed { get; set; }
-    
-    public TodoItem(int id, string title, bool completed = false) {
-        this.id = id;
-        this.title = title;
-        this.completed = completed;
-    }
-}
-
-/**
- * TodoStore - In-memory todo store registered as singleton.
- */
-class TodoStore : Object {
-    private Series<TodoItem> items = new Series<TodoItem>();
-    private int next_id = 1;
-    
-    public TodoStore() {
-        // Add some initial items
-        add("Learn Spry.Component");
-        add("Build dynamic HTML pages");
-        add("Handle form submissions");
-    }
-    
-    public void add(string title) {
-        items.add(new TodoItem(next_id++, title));
-    }
-    
-    public void toggle(int id) {
-        items.to_immutable_buffer().iterate((item) => {
-            if (item.id == id) {
-                item.completed = !item.completed;
-            }
-        });
-    }
-    
-    public void remove(int id) {
-        var new_items = items.to_immutable_buffer()
-            .where(item => item.id != id)
-            .to_series();
-        items = new_items;
-    }
-    
-    public ImmutableBuffer<TodoItem> all() {
-        return items.to_immutable_buffer();
-    }
-    
-    public int count() {
-        return (int)items.to_immutable_buffer().count();
-    }
-    
-    public int completed_count() {
-        return (int)items.to_immutable_buffer()
-            .count(item => item.completed);
-    }
-}
-
-/**
- * EmptyListComponent - Shown when no items exist.
- */
-class EmptyListComponent : Component {
-    public override string markup { get {
-        return """
-        <div class="empty">
-            No tasks yet! Add one below.
-        </div>
-        """;
-    }}
-}
-
-/**
- * TodoItemComponent - A single todo item with HTMX actions.
- */
-class TodoItemComponent : Component {
-    private TodoStore todo_store = inject<TodoStore>();
-    private ComponentFactory factory = inject<ComponentFactory>();
-    private HttpContext http_context = inject<HttpContext>();
-    private HeaderComponent header = inject<HeaderComponent>();
-    
-    private int _item_id;
-    public int item_id {
-        set {
-            _item_id = value;
-        }
-        get {
-            return _item_id;
-        }
-    }
-    
-    public override string markup { get {
-        return """
-        <div class="todo-item" sid="item">
-            <button type="button" class="btn-toggle" sid="toggle-btn" spry-action=":Toggle" spry-target="item" hx-swap="outerHTML"></button>
-            <span class="title" sid="title"></span>
-            <button type="button" class="btn-delete" sid="delete-btn" spry-action=":Delete" spry-target="item" hx-swap="delete">Delete</button>
-        </div>
-        """;
-    }}
-    
-    // Called before serialization to prepare template with data from store
-    public override async void prepare() throws Error {
-        var item = todo_store.all().first_or_default(i => i.id == _item_id);
-        if (item == null) return;
-        
-        this["title"].text_content = item.title;
-        this["toggle-btn"].text_content = item.completed ? "Undo" : "Done";
-        if (item.completed) {
-            this["item"].add_class("completed");
-        }
-        
-        // Set hx-vals on parent div - inherited by child buttons
-        this["item"].set_attribute("hx-vals", @"{\"id\":$_item_id}");
-    }
-    
-    public async override void handle_action(string action) throws Error {
-        // Get the item id from query parameters (passed via hx-vals)
-        var id_str = http_context.request.query_params.get_any_or_default("id");
-        if (id_str == null) return;
-        
-        var id = int.parse(id_str);
-        _item_id = id; // Set for prepare()
-        
-        switch (action) {
-            case "Toggle":
-                todo_store.toggle(id);
-                // prepare() will be called automatically before serialization
-                // Add header globals for OOB swap (header's prepare() fetches stats)
-                add_globals_from(header);
-                break;
-            case "Delete":
-                todo_store.remove(id);
-                // With hx-swap="delete", we still need to return the header update
-                add_globals_from(header);
-                return;
-        }
-    }
-}
-
-/**
- * TodoListComponent - Container for todo items.
- */
-class TodoListComponent : Component {
-    private TodoStore todo_store = inject<TodoStore>();
-    private ComponentFactory factory = inject<ComponentFactory>();
-    private HttpContext http_context = inject<HttpContext>();
-    private HeaderComponent header = inject<HeaderComponent>();
-    
-    public void set_items(Enumerable<Renderable> items) {
-        set_outlet_children("items", items);
-    }
-    
-    public override string markup { get {
-        return """
-        <div class="card" id="todo-list" sid="todo-list">
-            <h2>Todo List</h2>
-            <spry-outlet sid="items"/>
-        </div>
-        """;
-    }}
-    
-    public async override void handle_action(string action) throws Error {
-        if (action == "Add") {
-            var title = http_context.request.query_params.get_any_or_default("title");
-            
-            if (title != null && title.strip() != "") {
-                todo_store.add(title.strip());
-            }
-        }
-        
-        // Rebuild the list - only need to set item_id, prepare() handles the rest
-        var count = todo_store.count();
-        if (count == 0) {
-            set_outlet_children("items", Iterate.single<Renderable>(factory.create<EmptyListComponent>()));
-        } else {
-            var items = new Series<Renderable>();
-            todo_store.all().iterate((item) => {
-                var component = factory.create<TodoItemComponent>();
-                component.item_id = item.id;
-                items.add(component);
-            });
-            set_outlet_children("items", items);
-        }
-        
-        // Add header globals for OOB swap (header's prepare() fetches stats)
-        add_globals_from(header);
-    }
-}
-
-/**
- * HeaderComponent - Page header with stats.
- * Uses prepare() to fetch data from store automatically.
- */
-class HeaderComponent : Component {
-    private TodoStore todo_store = inject<TodoStore>();
-    
-    public override string markup { get {
-        return """
-        <div class="card" id="header" spry-global="header">
-            <h1>Todo Component Example</h1>
-            <p>This page demonstrates <code>Spry.Component</code> with IoC composition.</p>
-            <div class="stats">
-                <div class="stat">
-                    <div class="stat-value" sid="total"></div>
-                    <div class="stat-label">Total Tasks</div>
-                </div>
-                <div class="stat">
-                    <div class="stat-value" sid="completed"></div>
-                    <div class="stat-label">Completed</div>
-                </div>
-            </div>
-        </div>
-        """;
-    }}
-    
-    // Called before serialization to populate stats from store
-    public override async void prepare() throws Error {
-        this["total"].text_content = todo_store.count().to_string();
-        this["completed"].text_content = todo_store.completed_count().to_string();
-    }
-}
-
-/**
- * AddFormComponent - Form to add new todos with HTMX.
- */
-class AddFormComponent : Component {
-    private TodoStore todo_store = inject<TodoStore>();
-    private ComponentFactory factory = inject<ComponentFactory>();
-    private HttpContext http_context = inject<HttpContext>();
-    
-    public override string markup { get {
-        return """
-        <div class="card">
-            <h2>Add New Task</h2>
-            <form sid="form" spry-action="TodoListComponent:Add" hx-target="#todo-list" hx-swap="outerHTML" style="display: flex; gap: 10px;">
-                <input type="text" name="title" placeholder="Enter a new task..." required="required" sid="title-input"/>
-                <button type="submit" class="btn-primary">Add Task</button>
-            </form>
-        </div>
-        """;
-    }}
-}
-
-/**
- * FeaturesComponent - Shows Component features used.
- */
-class FeaturesComponent : Component {
-    public override string markup { get {
-        return """
-        <div class="card">
-            <h2>Component Features Used</h2>
-            <div class="feature">
-                <strong>Defining Components:</strong>
-                <code>class MyComponent : Component { public override string markup { get { return "..."; } } }</code>
-            </div>
-            <div class="feature">
-                <strong>Declarative Child Components:</strong>
-                <code>&lt;spry-component name="HeaderComponent" sid="header"/&gt;</code>
-            </div>
-            <div class="feature">
-                <strong>Accessing Child Components:</strong>
-                <code>var header = get_component_child&lt;HeaderComponent&gt;("header");</code>
-            </div>
-            <div class="feature">
-                <strong>Using Outlets (for lists):</strong>
-                <code>&lt;spry-outlet sid="items"/&gt;</code>
-            </div>
-            <div class="feature">
-                <strong>Preparing Templates:</strong>
-                <code>public override void prepare() { this["title"].text_content = "..."; }</code>
-            </div>
-            <div class="feature">
-                <strong>Declarative HTMX Actions:</strong>
-                <code>&lt;button spry-action=":Toggle" hx-vals='{"id":1}'&gt;Toggle&lt;/button&gt;</code>
-            </div>
-            <div class="feature">
-                <strong>IoC Injection:</strong>
-                <code>private ComponentFactory factory = inject&lt;ComponentFactory&gt;();</code>
-            </div>
-        </div>
-        """;
-    }}
-}
-
-/**
- * FooterComponent - Page footer.
- */
-class FooterComponent : Component {
-    public override string markup { get {
-        return """
-        <div class="card" style="text-align: center; color: #666;">
-            <p>Built with <code>Spry.Component</code> |
-                <a href="/api/todos">View JSON API</a>
-            </p>
-        </div>
-        """;
-    }}
-}
-
-/**
- * TodoPage - The main page structure.
- *
- * Inherits from PageComponent to act as both a Component and Endpoint.
- * Uses <spry-component name="..."> syntax for declarative child components.
- * Child components are accessed via get_component_child<T>(sid) in prepare().
- */
-class TodoPage : PageComponent {
-    
-    public override string title { get { return "Todo"; } }
-    
-    private TodoStore todo_store = inject<TodoStore>();
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <!DOCTYPE html>
-        <html>
-        <head>
-            <meta charset="UTF-8"/>
-            <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-            <title>Todo Component Example</title>
-            <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"></script>
-            <style>
-                body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; background: #f5f5f5; }
-                .card { background: white; border-radius: 8px; padding: 20px; margin: 10px 0; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
-                h1 { color: #333; margin-top: 0; }
-                h2 { color: #555; border-bottom: 2px solid #4CAF50; padding-bottom: 10px; }
-                .todo-item { display: flex; align-items: center; padding: 10px; margin: 5px 0; background: #fafafa; border-radius: 4px; border-left: 4px solid #4CAF50; }
-                .todo-item.completed { border-left-color: #ccc; opacity: 0.7; }
-                .todo-item.completed .title { text-decoration: line-through; color: #888; }
-                .todo-item .title { flex: 1; margin: 0 10px; }
-                .stats { display: flex; gap: 20px; margin: 10px 0; }
-                .stat { background: #e8f5e9; padding: 10px 20px; border-radius: 4px; }
-                .stat-value { font-size: 24px; font-weight: bold; color: #4CAF50; }
-                .stat-label { font-size: 12px; color: #666; }
-                input[type="text"] { padding: 10px; border: 1px solid #ddd; border-radius: 4px; flex: 1; }
-                button { padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; }
-                .btn-primary { background: #4CAF50; color: white; }
-                .btn-primary:hover { background: #45a049; }
-                .btn-toggle { background: #2196F3; color: white; padding: 5px 10px; font-size: 12px; }
-                .btn-delete { background: #f44336; color: white; padding: 5px 10px; font-size: 12px; }
-                code { background: #e8e8e8; padding: 2px 6px; border-radius: 4px; font-size: 14px; }
-                pre { background: #263238; color: #aed581; padding: 15px; border-radius: 4px; overflow-x: auto; }
-                .feature { margin: 15px 0; }
-                .feature code { display: block; background: #f5f5f5; padding: 10px; margin: 5px 0; }
-                a { color: #2196F3; text-decoration: none; }
-                a:hover { text-decoration: underline; }
-                .empty { color: #999; font-style: italic; padding: 20px; text-align: center; }
-            </style>
-        </head>
-        <body>
-            <spry-component name="HeaderComponent" sid="header"/>
-            <spry-component name="TodoListComponent" sid="todo-list"/>
-            <spry-component name="AddFormComponent" sid="add-form"/>
-            <spry-component name="FeaturesComponent" sid="features"/>
-            <spry-component name="FooterComponent" sid="footer"/>
-        </body>
-        </html>
-        """;
-    }}
-    
-    // Called before serialization to populate the todo list
-    public override async void prepare() throws Error {
-        // Get the TodoListComponent child and populate it
-        var todo_list = get_component_child<TodoListComponent>("todo-list");
-        
-        var count = todo_store.count();
-        if (count == 0) {
-            todo_list.set_items(Iterate.single<Renderable>(factory.create<EmptyListComponent>()));
-        } else {
-            var items = new Series<Renderable>();
-            todo_store.all().iterate((item) => {
-                var component = factory.create<TodoItemComponent>();
-                component.item_id = item.id;
-                items.add(component);
-            });
-            todo_list.set_items(items);
-        }
-    }
-}
-
-// API endpoint that returns JSON representation of todos
-class TodoJsonEndpoint : Object, Endpoint {
-    private TodoStore todo_store = inject<TodoStore>();
-    
-    public async HttpResult handle_request(HttpContext context, RouteContext route) throws Error {
-        var json_parts = new Series<string>();
-        json_parts.add("{\"todos\": [");
-        
-        bool first = true;
-        todo_store.all().iterate((item) => {
-            if (!first) json_parts.add(",");
-            var completed_str = item.completed ? "true" : "false";
-            var escaped_title = item.title.replace("\"", "\\\"");
-            json_parts.add(@"{\"id\":$(item.id),\"title\":\"$escaped_title\",\"completed\":$completed_str}");
-            first = false;
-        });
-        
-        json_parts.add("]}");
-        
-        var json = json_parts.to_immutable_buffer()
-            .aggregate<string>("", (acc, s) => acc + s);
-        
-        return new HttpStringResult(json)
-            .set_header("Content-Type", "application/json");
-    }
-}
-
-void main(string[] args) {
-    int port = args.length > 1 ? int.parse(args[1]) : 8080;
-    
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("             Spry TodoComponent Example (IoC)\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  Port: %d\n", port);
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  Endpoints:\n");
-    print("    /           - Todo list (Component-based)\n");
-    print("    /api/todos  - JSON API for todos\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  HTMX Actions (via SpryModule):\n");
-    print("    Add, Toggle, Delete - Dynamic updates\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("\nPress Ctrl+C to stop the server\n\n");
-    
-    try {
-        var application = new WebApplication(port);
-        
-        // Register compression components (optional, for better performance)
-        application.use_compression();
-        
-        // Add Spry module for automatic HTMX endpoint registration
-        application.add_module<SpryModule>();
-        
-        // Register the todo store as singleton
-        application.add_singleton<TodoStore>();
-        
-        // Configure Spry components and pages
-        var spry_cfg = application.configure_with<SpryConfigurator>();
-        
-        // Register child components
-        spry_cfg.add_component<EmptyListComponent>();
-        spry_cfg.add_component<TodoItemComponent>();
-        spry_cfg.add_component<TodoListComponent>();
-        spry_cfg.add_component<HeaderComponent>();
-        spry_cfg.add_component<AddFormComponent>();
-        spry_cfg.add_component<FeaturesComponent>();
-        spry_cfg.add_component<FooterComponent>();
-        
-        // Register the page (acts as both Component and Endpoint)
-        spry_cfg.add_page<TodoPage>(new EndpointRoute("/"));
-        
-        // Register JSON API endpoint
-        application.add_endpoint<TodoJsonEndpoint>(new EndpointRoute("/api/todos"));
-        
-        application.run();
-        
-    } catch (Error e) {
-        printerr("Error: %s\n", e.message);
-        Process.exit(1);
-    }
-}

+ 0 - 20
examples/UserContentComponent.vala

@@ -1,20 +0,0 @@
-// This file demonstrates the spry-mkconst workflow:
-// 1. The HTML template (UserContentComponent.vala.html) is converted to a const using spry-mkconst
-// 2. The generated const (USER_CONTENT_COMPONENT_VALA_HTML) is referenced in the markup property
-// 3. This allows the Vala language server to still recognize this file as valid Vala code
-
-class UserContentComponent : Component {
-    public override string markup { get { return USER_CONTENT_COMPONENT_VALA_HTML; } }
-
-    private HttpContext http_context = inject<HttpContext>();
-
-    public async override void handle_action(string action) throws Error {
-        this["message"].text_content = http_context.request.query_params.get_any_or_default("message") ?? "No message provided!";
-        this["action"].text_content = action;
-    }
-}
-
-// Generated by spry-mkconst (would be in a separate file or included via build system):
-// const string USER_CONTENT_COMPONENT_VALA_HTML = """
-// <p>You said: <strong sid="message"></strong> <em>(via <span sid="action"></span>)</em></p>
-// """;

+ 0 - 1
examples/UserContentComponent.vala.html

@@ -1 +0,0 @@
-<p>You said: <strong sid="message"></strong> <em>(via <span sid="action"></span>)</em></p>

+ 0 - 1071
examples/UsersExample.vala

@@ -1,1071 +0,0 @@
-using Astralis;
-using Invercargill;
-using Invercargill.DataStructures;
-using InvercargillSql;
-using InvercargillSql.Migrations;
-using InvercargillSqlInversion;
-using Inversion;
-using Spry;
-using Spry.Authentication;
-using Spry.Authorisation;
-
-/**
- * UsersExample.vala - Complete example demonstrating the Spry Authentication system
- * 
- * This example demonstrates:
- * 1. Application Migration - Extends UserTableMigration with a specific version
- * 2. Service Setup - Using Inversion's inject<T>() pattern
- * 3. User Registration - Creating a new user with username/email/password
- * 4. User Authentication - Login flow with AuthorisationToken
- * 5. Permission Management - Setting and checking permissions
- * 6. Protected Content - Pages that require authentication
- * 7. Login Form - Using the built-in LoginFormComponent
- * 8. User Management - Using UserManagementComponent (for users with permission)
- * 9. Authorisation Context - Using AuthorisationContext for permission checking
- * 
- * Route structure:
- *   /              -> HomePage (public landing page)
- *   /register      -> RegisterPage (create new account)
- *   /login         -> LoginPage (uses LoginFormComponent)
- *   /logout        -> LogoutEndpoint (clears cookie and redirects)
- *   /dashboard     -> DashboardPage (protected - requires authentication)
- *   /admin/users   -> UserAdminPage (protected - requires "user-management" permission, uses UserManagementComponent)
- */
-
-// =============================================================================
-// APPLICATION PERMISSIONS - Define permissions available in this application
-// =============================================================================
-
-/**
- * Creates a Vector of permissions for the UsersExample application.
- *
- * These permissions are passed to the authentication components so they can
- * display appropriate checkboxes. The components themselves do NOT hardcode
- * any permissions - they must be provided by the application.
- *
- * Returns a Vector<string> which is required for proper property binding
- * in the authentication components.
- */
-public Vector<string> get_application_permissions() {
-    var permissions = new Vector<string>();
-    permissions.add("user-management");
-    permissions.add("user.create");
-    permissions.add("user.read");
-    permissions.add("user.update");
-    permissions.add("user.delete");
-    permissions.add("admin");
-    return permissions;
-}
-
-// =============================================================================
-// STYLESHEETS - CSS content served as FastResources
-// =============================================================================
-
-private const string MAIN_CSS = """
-/* Base Reset & Layout */
-* { box-sizing: border-box; margin: 0; padding: 0; }
-html, body {
-    height: 100%;
-}
-body {
-    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
-    line-height: 1.6;
-    background: #f5f7fa;
-    display: flex;
-    flex-direction: column;
-    min-height: 100vh;
-}
-
-/* Header */
-header {
-    background: #2c3e50;
-    color: white;
-    padding: 1rem 2rem;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    flex-shrink: 0;
-}
-header nav a {
-    color: white;
-    margin-right: 1.5rem;
-    text-decoration: none;
-    font-weight: 500;
-    transition: opacity 0.2s;
-}
-header nav a:hover { opacity: 0.8; }
-header nav a:last-child { margin-right: 0; }
-header .user-info {
-    font-size: 0.9rem;
-}
-header .user-info a {
-    margin-left: 1rem;
-    color: #3498db;
-}
-
-/* Main Content */
-main.container {
-    flex: 1;
-    max-width: 800px;
-    width: 100%;
-    margin: 0 auto;
-    padding: 2rem 1rem;
-}
-
-/* Cards */
-.card {
-    background: white;
-    border-radius: 12px;
-    padding: 2rem;
-    margin-bottom: 1.5rem;
-    box-shadow: 0 2px 8px rgba(0,0,0,0.08);
-}
-
-/* Typography */
-h1 { color: #2c3e50; margin-bottom: 1rem; }
-h2 { color: #34495e; margin-bottom: 0.75rem; margin-top: 1.5rem; }
-p { color: #555; margin-bottom: 1rem; }
-ul { margin-left: 1.5rem; margin-bottom: 1rem; }
-li { margin-bottom: 0.5rem; color: #555; }
-
-/* Links */
-a { color: #3498db; text-decoration: none; transition: color 0.2s; }
-a:hover { color: #2980b9; text-decoration: underline; }
-
-/* Forms */
-.form-group {
-    margin-bottom: 1.25rem;
-}
-.form-group label {
-    display: block;
-    margin-bottom: 0.5rem;
-    font-weight: 500;
-    color: #34495e;
-}
-.form-group input {
-    width: 100%;
-    padding: 0.75rem;
-    border: 2px solid #e0e0e0;
-    border-radius: 6px;
-    font-size: 1rem;
-    transition: border-color 0.2s;
-}
-.form-group input:focus {
-    outline: none;
-    border-color: #3498db;
-}
-.form-group-checkbox {
-    display: flex;
-    align-items: center;
-    gap: 0.5rem;
-}
-.form-group-checkbox input {
-    width: auto;
-}
-.form-group-checkbox label {
-    margin: 0;
-    font-weight: normal;
-}
-
-/* Buttons */
-button, .btn {
-    background: #3498db;
-    color: white;
-    border: none;
-    padding: 0.75rem 1.5rem;
-    border-radius: 6px;
-    cursor: pointer;
-    font-size: 1rem;
-    font-weight: 500;
-    transition: all 0.2s;
-    text-decoration: none;
-    display: inline-block;
-}
-button:hover, .btn:hover {
-    background: #2980b9;
-    text-decoration: none;
-}
-.btn-secondary {
-    background: #6c757d;
-}
-.btn-secondary:hover {
-    background: #545b62;
-}
-
-/* Alerts */
-.alert {
-    padding: 1rem;
-    border-radius: 6px;
-    margin-bottom: 1rem;
-}
-.alert-success {
-    background: #d4edda;
-    color: #155724;
-    border: 1px solid #c3e6cb;
-}
-.alert-error {
-    background: #f8d7da;
-    color: #721c24;
-    border: 1px solid #f5c6cb;
-}
-.error-message {
-    color: #dc3545;
-    font-size: 0.9rem;
-    margin-top: 0.5rem;
-}
-
-/* Login Form */
-.spry-login-form {
-    max-width: 400px;
-}
-.login-btn {
-    width: 100%;
-    margin-top: 1rem;
-}
-
-/* Footer */
-footer {
-    background: #2c3e50;
-    color: rgba(255,255,255,0.7);
-    padding: 1.5rem;
-    text-align: center;
-    flex-shrink: 0;
-}
-
-/* Dashboard */
-.welcome-section {
-    margin-bottom: 2rem;
-}
-.permission-list {
-    display: flex;
-    flex-wrap: wrap;
-    gap: 0.5rem;
-    margin-top: 0.5rem;
-}
-.permission-badge {
-    background: #e9ecef;
-    color: #495057;
-    padding: 0.25rem 0.75rem;
-    border-radius: 20px;
-    font-size: 0.85rem;
-}
-.permission-badge.admin {
-    background: #ffc107;
-    color: #856404;
-}
-""";
-
-// =============================================================================
-// PAGE TEMPLATE - Provides consistent layout for all pages
-// =============================================================================
-
-/**
- * MainLayoutTemplate - Base template for all pages
- * 
- * Provides:
- * - HTML document structure
- * - Common <head> elements (scripts, styles)
- * - Site-wide header with navigation (changes based on auth state)
- * - Site-wide footer
- * 
- * Uses AuthorisationContext to check authentication status.
- */
-public class MainLayoutTemplate : PageTemplate {
-    
-    private AuthorisationContext _auth_context = inject<AuthorisationContext>();
-    
-    public override string markup { get {
-        return """
-        <!DOCTYPE html>
-        <html lang="en">
-        <head>
-            <meta charset="UTF-8">
-            <meta name="viewport" content="width=device-width, initial-scale=1.0">
-            <title>Spry Authentication Example</title>
-            <link rel="stylesheet" href="/styles/main.css">
-            <script spry-res="htmx.js"></script>
-        </head>
-        <body>
-            <header>
-                <nav>
-                    <a href="/">Home</a>
-                    <a href="/dashboard">Dashboard</a>
-                    <a href="/admin/users">User Admin</a>
-                </nav>
-                <div class="user-info" sid="user-info">
-                    <!-- Will be populated based on auth state -->
-                </div>
-            </header>
-            <main class="container">
-                <spry-content />
-            </main>
-            <footer>
-                <p>Built with Spry Framework - Authentication Example</p>
-            </footer>
-        </body>
-        </html>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Check authentication using AuthorisationContext
-        if (!_auth_context.is_anonymous() && _auth_context.token != null) {
-            var token = _auth_context.token;
-            this["user-info"].inner_html = @"Logged in as $(token.username) | <a href=\"/logout\">Logout</a>";
-        } else {
-            this["user-info"].inner_html = "<a href=\"/login\">Login</a> | <a href=\"/register\">Register</a>";
-        }
-    }
-}
-
-// =============================================================================
-// PAGE COMPONENTS - Public pages
-// =============================================================================
-
-/**
- * HomePage - Public landing page
- * 
- * This page is accessible to everyone, authenticated or not.
- * It provides an overview of the Authentication system features.
- */
-public class HomePage : PageComponent {
-    
-    public override string title { get { return "Authentication Example"; } }
-    
-    private AuthorisationContext _auth_context = inject<AuthorisationContext>();
-    
-    public const string ROUTE = "/";
-    
-    public override string markup { get {
-        return """
-        <div class="card">
-            <h1>Welcome to the Spry Authentication Example</h1>
-            <p>This example demonstrates the complete Spry Authentication system including:</p>
-            
-            <h2>Features</h2>
-            <ul>
-                <li><strong>User Registration</strong> - Create new accounts with username/email/password</li>
-                <li><strong>Authentication</strong> - Login with AuthorisationToken management</li>
-                <li><strong>Permissions</strong> - Granular permission system with wildcard support</li>
-                <li><strong>Protected Pages</strong> - Pages that require authentication</li>
-                <li><strong>User Management</strong> - Admin interface for managing users</li>
-                <li><strong>Authorisation Context</strong> - Request-scoped permission checking</li>
-            </ul>
-            
-            <h2>Try It Out</h2>
-            <p sid="status-message"></p>
-            
-            <ul>
-                <li><a href="/register">Register</a> - Create a new account</li>
-                <li><a href="/login">Login</a> - Sign in to your account</li>
-                <li><a href="/dashboard">Dashboard</a> - Protected page (requires login)</li>
-                <li><a href="/admin/users">User Admin</a> - Admin page (requires permission)</li>
-            </ul>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Check if user is authenticated using AuthorisationContext
-        if (!_auth_context.is_anonymous() && _auth_context.token != null) {
-            var token = _auth_context.token;
-            this["status-message"].text_content = @"You are logged in as <strong>$(token.username)</strong>.";
-        } else {
-            this["status-message"].text_content = "You are not logged in. Register or login to access protected pages.";
-        }
-    }
-}
-
-/**
- * RegisterPage - User registration page
- * 
- * Allows new users to create an account with username, email, and password.
- * Demonstrates direct use of UserService.register_user().
- */
-public class RegisterPage : PageComponent {
-    
-    public override string title { get { return "Register"; } }
-    
-    private UserService _user_service = inject<UserService>();
-    private HttpContext _http_context = inject<HttpContext>();
-    
-    public string? error_message { get; private set; default = null; }
-    public string? success_message { get; private set; default = null; }
-    public string preserved_username { get; private set; default = ""; }
-    public string preserved_email { get; private set; default = ""; }
-    
-    public const string ROUTE = "/register";
-    
-    public override string markup { get {
-        return """
-        <div class="card" sid="register-card" hx-swap="outerHTML">
-            <h1>Create Account</h1>
-            
-            <div spry-if="this.success_message != null" class="alert alert-success" sid="success-alert">
-                <span content-expr="this.success_message"></span>
-            </div>
-            
-            <form sid="register-form" spry-action=":Register" spry-target="register-card">
-                <div class="form-group">
-                    <label for="username">Username</label>
-                    <input type="text" name="username" sid="username-input" required 
-                           autocomplete="username" placeholder="Choose a username"/>
-                </div>
-                
-                <div class="form-group">
-                    <label for="email">Email</label>
-                    <input type="email" name="email" sid="email-input" required 
-                           autocomplete="email" placeholder="Enter your email"/>
-                </div>
-                
-                <div class="form-group">
-                    <label for="forename">First Name</label>
-                    <input type="text" name="forename" sid="forename-input" required 
-                           autocomplete="given-name" placeholder="Enter your first name"/>
-                </div>
-                
-                <div class="form-group">
-                    <label for="surname">Last Name</label>
-                    <input type="text" name="surname" sid="surname-input" required 
-                           autocomplete="family-name" placeholder="Enter your last name"/>
-                </div>
-                
-                <div class="form-group">
-                    <label for="date-of-birth">Date of Birth</label>
-                    <input type="date" name="date_of_birth" sid="dob-input" required 
-                           autocomplete="bday" placeholder="YYYY-MM-DD"/>
-                </div>
-                
-                <div class="form-group">
-                    <label for="password">Password</label>
-                    <input type="password" name="password" sid="password-input" required 
-                           autocomplete="new-password" placeholder="Choose a password"/>
-                </div>
-                
-                <div class="form-group">
-                    <label for="confirm-password">Confirm Password</label>
-                    <input type="password" name="confirm_password" sid="confirm-password-input" required 
-                           autocomplete="new-password" placeholder="Confirm your password"/>
-                </div>
-                
-                <div spry-if="this.error_message != null" class="error-message" sid="error-container">
-                    <span content-expr="this.error_message"></span>
-                </div>
-                
-                <button type="submit">Create Account</button>
-            </form>
-            
-            <p style="margin-top: 1.5rem;">
-                Already have an account? <a href="/login">Login here</a>
-            </p>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Preserve form values after failed submission
-        if (preserved_username.length > 0) {
-            this["username-input"].set_attribute("value", preserved_username);
-        }
-        if (preserved_email.length > 0) {
-            this["email-input"].set_attribute("value", preserved_email);
-        }
-    }
-    
-    public async override void handle_action(string action) throws Error {
-        if (action == "Register") {
-            yield handle_register_async();
-        }
-    }
-    
-    private async void handle_register_async() throws Error {
-        var query = _http_context.request.query_params;
-        
-        // Get form values
-        var username = (query.get_any_or_default("username") ?? "").strip();
-        var email = (query.get_any_or_default("email") ?? "").strip();
-        var forename = (query.get_any_or_default("forename") ?? "").strip();
-        var surname = (query.get_any_or_default("surname") ?? "").strip();
-        var dob_string = query.get_any_or_default("date_of_birth") ?? "";
-        var password = query.get_any_or_default("password") ?? "";
-        var confirm_password = query.get_any_or_default("confirm_password") ?? "";
-        
-        // Preserve values for re-display
-        preserved_username = username;
-        preserved_email = email;
-        
-        // Validate inputs
-        if (username.length < 3) {
-            error_message = "Username must be at least 3 characters";
-            return;
-        }
-        
-        if (!email.contains("@") || !email.contains(".")) {
-            error_message = "Please enter a valid email address";
-            return;
-        }
-        
-        if (forename.length == 0) {
-            error_message = "Please enter your first name";
-            return;
-        }
-        
-        if (surname.length == 0) {
-            error_message = "Please enter your last name";
-            return;
-        }
-        
-        // Parse date of birth
-        DateTime? date_of_birth = null;
-        if (dob_string.length > 0) {
-            try {
-                date_of_birth = new DateTime.from_iso8601(dob_string, new TimeZone.utc());
-            } catch (Error e) {
-                error_message = "Please enter a valid date of birth (YYYY-MM-DD)";
-                return;
-            }
-        } else {
-            error_message = "Please enter your date of birth";
-            return;
-        }
-        
-        if (password.length < 6) {
-            error_message = "Password must be at least 6 characters";
-            return;
-        }
-        
-        if (password != confirm_password) {
-            error_message = "Passwords do not match";
-            return;
-        }
-        
-        // Attempt to create user using the new register_user method
-        try {
-            var user = yield _user_service.register_user(
-                username, 
-                email, 
-                forename, 
-                surname, 
-                date_of_birth, 
-                password,
-                true  // enabled
-            );
-            
-            // Grant basic permissions to new users
-            yield _user_service.set_user_permission(user.id, "user.read");
-            
-            success_message = @"Account created successfully! You can now <a href=\"/login\">login</a>.";
-            error_message = null;
-            
-            // Clear preserved values on success
-            preserved_username = "";
-            preserved_email = "";
-            
-        } catch (Error e) {
-            // Handle duplicate username/email errors
-            if (e.message.contains("UNIQUE constraint failed") || e.message.contains("duplicate")) {
-                if (e.message.contains("username")) {
-                    error_message = "Username already exists. Please choose another.";
-                } else if (e.message.contains("email")) {
-                    error_message = "Email already registered. Please use another or login.";
-                } else {
-                    error_message = "A user with this information already exists.";
-                }
-            } else {
-                error_message = "Registration failed: %s".printf(e.message);
-            }
-        }
-    }
-}
-
-// =============================================================================
-// PAGE COMPONENTS - Authentication pages
-// =============================================================================
-
-/**
- * LoginPage - Login page using the built-in LoginFormComponent
- * 
- * This page demonstrates how to use the LoginFormComponent for authentication.
- * The component handles:
- * - Form display and validation
- * - Authentication via UserService.authenticate_user()
- * - Cookie management via AuthorisationService
- * - Redirect after successful login
- */
-public class LoginPage : PageComponent {
-    
-    public override string title { get { return "Login"; } }
-    
-    private ComponentFactory _factory = inject<ComponentFactory>();
-    
-    public const string ROUTE = "/login";
-    
-    public override string markup { get {
-        return """
-        <div class="card">
-            <h1>Login</h1>
-            <spry-component name="SpryAuthenticationLoginComponent" />
-            <p style="margin-top: 1.5rem;">
-                Don't have an account? <a href="/register">Register here</a>
-            </p>
-        </div>
-        """;
-    }}
-    
-}
-
-/**
- * LogoutEndpoint - Handles logout by clearing the authorisation cookie
- *
- * This demonstrates:
- * - Simply clearing the authorisation cookie
- * - Returning a redirect response
- * 
- * Note: In the refined authentication system, there's no server-side session
- * to delete - authentication is stateless using signed tokens.
- */
-public class LogoutEndpoint : Object, Endpoint {
-    
-    public async HttpResult handle_request(HttpContext http_context, RouteContext route_context) throws Error {
-        // Create redirect result with Location header
-        var result = new HttpStringResult("Redirecting to home page...", 302);
-        result.set_header("Location", "/");
-        
-        // Clear the authorisation cookie by setting it to empty with an expired date
-        result.headers.add("Set-Cookie", "_spry-authorisation=; Secure; Max-Age=0");
-        
-        return result;
-    }
-}
-
-// =============================================================================
-// PAGE COMPONENTS - Protected pages
-// =============================================================================
-
-/**
- * DashboardPage - Protected dashboard page
- * 
- * This page demonstrates:
- * - Checking authentication using AuthorisationContext
- * - Redirecting unauthenticated users to login
- * - Accessing the current user's information from AuthorisationToken
- * - Checking permissions using AuthorisationContext
- * - Displaying user-specific content
- */
-public class DashboardPage : PageComponent {
-    
-    public override string title { get { return "Dashboard"; } }
-    
-    private AuthorisationContext _auth_context = inject<AuthorisationContext>();
-    
-    public const string ROUTE = "/dashboard";
-    
-    public override string markup { get {
-        return """
-        <div class="card">
-            <!-- Not authenticated message -->
-            <div spry-if="this.is_anonymous" class="alert alert-error">
-                <h2>Authentication Required</h2>
-                <p>You must be logged in to view this page.</p>
-                <p style="margin-top: 1rem;">
-                    <a href="/login" class="btn">Login</a>
-                    <a href="/register" class="btn btn-secondary" style="margin-left: 0.5rem;">Register</a>
-                </p>
-            </div>
-            
-            <!-- Authenticated content -->
-            <div spry-if="!this.is_anonymous">
-                <div class="welcome-section">
-                    <h1 sid="welcome-heading">Dashboard</h1>
-                    <p>Welcome to your dashboard! This page demonstrates protected content.</p>
-                </div>
-                
-                <h2>Your Profile</h2>
-                <ul>
-                    <li><strong>Username:</strong> <span sid="username"></span></li>
-                    <li><strong>Email:</strong> <span sid="email"></span></li>
-                    <li><strong>User ID:</strong> <span sid="user-id"></span></li>
-                    <li><strong>Account Created:</strong> <span sid="created-at"></span></li>
-                </ul>
-                
-                <h2>Your Permissions</h2>
-                <div class="permission-list" sid="permission-list">
-                    <!-- Permissions will be listed here -->
-                </div>
-                
-                <div spry-if="this.is_admin" class="alert alert-success" style="margin-top: 1.5rem;">
-                    <strong>Admin Access:</strong> You have admin privileges.
-                    <a href="/admin/users" style="color: #155724;">Go to User Management</a>
-                </div>
-                
-                <p style="margin-top: 1.5rem;">
-                    <a href="/" class="btn btn-secondary">Back to Home</a>
-                </p>
-            </div>
-        </div>
-        """;
-    }}
-    
-    // Track if user is authenticated (for template binding)
-    public bool is_anonymous { get; private set; default = true; }
-    
-    // Track if user has admin permission
-    public bool is_admin { get; private set; default = false; }
-    
-    public override async void prepare() throws Error {
-        // Check authentication using AuthorisationContext
-        if (_auth_context.is_anonymous()) {
-            // Not authenticated - show message and link to login
-            is_anonymous = true;
-            return;
-        }
-        
-        is_anonymous = false;
-        
-        var token = _auth_context.token;
-        if (token == null) {
-            is_anonymous = true;
-            return;
-        }
-        
-        // Check permissions using AuthorisationContext
-        is_admin = _auth_context.has_permission("admin");
-        
-        // Populate user info from the token
-        this["welcome-heading"].text_content = @"Welcome, $(token.username)!";
-        this["username"].text_content = token.username;
-        this["user-id"].text_content = token.user_identifier.to_string();
-        
-        // Get additional user data from the token's data properties
-        var user_data = token.data;
-        string? email_val = null;
-        DateTime? created_val = null;
-        
-        // Try to get email and created from properties
-        try {
-            var email_element = user_data.get("email");
-            email_val = email_element.as_string_or_null();
-        } catch (Error e) {
-            // Email not available
-        }
-        
-        try {
-            var created_element = user_data.get("created");
-            created_val = created_element.as<DateTime>();
-        } catch (Error e) {
-            // Created not available
-        }
-        
-        this["email"].text_content = email_val ?? "N/A";
-        this["created-at"].text_content = created_val != null ? 
-            ((DateTime)created_val).format("%Y-%m-%d %H:%M:%S UTC") : "N/A";
-        
-        // Populate permissions from the token
-        var perm_text = "";
-        var user_permissions = token.permissions;
-        int perm_count = 0;
-        foreach (var perm in user_permissions) {
-            var badge_class = perm == "admin" ? "permission-badge admin" : "permission-badge";
-            perm_text += @"<span class=\"$badge_class\">$perm</span> ";
-            perm_count++;
-        }
-        if (perm_count == 0) {
-            perm_text = "<span class=\"permission-badge\">No permissions assigned</span>";
-        }
-        this["permission-list"].inner_html = perm_text;
-    }
-}
-
-// =============================================================================
-// PAGE COMPONENTS - Admin pages
-// =============================================================================
-
-/**
- * UserAdminPage - Admin page for user management
- * 
- * This page demonstrates how to use UserManagementComponent within your own
- * page layout. Unlike the old UserManagementPage (which was a PageComponent
- * that generated a full HTML document), UserManagementComponent is a regular
- * Component that can be placed anywhere.
- * 
- * Applications now have full control over:
- * - The page layout and navigation
- * - CSS styling via their own stylesheets
- * - Where the user management component appears
- */
-public class UserAdminPage : PageComponent {
-    
-    public override string title { get { return "User Administration"; } }
-    
-    private ComponentFactory _factory = inject<ComponentFactory>();
-    private UserManagementComponent _user_management;
-    
-    public const string ROUTE = "/admin/users";
-    
-    public override string markup { get {
-        return """
-        <div class="card">
-            <h1>User Administration</h1>
-            <p>Manage user accounts, permissions, and access control.</p>
-            <spry-outlet sid="user-management-outlet"/>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        // Create the user management component
-        _user_management = _factory.create<UserManagementComponent>();
-        
-        // Pass the application-defined permissions to the component
-        // This allows the component to display appropriate checkboxes
-        //  _user_management.available_permissions = get_application_permissions();
-        
-        // Add it to our outlet
-        _user_management.authorisation_permission = "admin";
-        add_outlet_child("user-management-outlet", _user_management);
-        
-        // Share globals with the component (required for action handling)
-        add_globals_from(_user_management);
-    }
-}
-
-// =============================================================================
-// SEED DATA - Creates initial admin user
-// =============================================================================
-
-/**
- * SeedData - Creates initial users for testing
- * 
- * This demonstrates how to:
- * - Check if users exist before creating
- * - Create users programmatically using register_user()
- * - Grant permissions to users using set_user_permission()
- */
-public class SeedData : Object {
-    
-    public static async void ensure_admin_exists(UserService user_service) throws Error {
-        // Try to get list of users and check if admin exists
-        var users = yield user_service.list_users(0, 100);
-        
-        bool admin_exists = false;
-        bool testuser_exists = false;
-        int64? admin_id = null;
-        int64? testuser_id = null;
-        
-        foreach (var user in users) {
-            if (user.username == "admin") {
-                admin_exists = true;
-                admin_id = user.id;
-            }
-            if (user.username == "testuser") {
-                testuser_exists = true;
-                testuser_id = user.id;
-            }
-        }
-        
-        if (admin_exists) {
-            print("Admin user already exists\n");
-        } else {
-            print("Creating admin user...\n");
-            
-            // Create admin user using register_user
-            var admin_user = yield user_service.register_user(
-                "admin", 
-                "admin@example.com", 
-                "Admin", 
-                "User", 
-                new DateTime.utc(1990, 1, 1, 0, 0, 0.0),
-                "admin123",
-                true
-            );
-            admin_id = admin_user.id;
-            
-            // Grant admin permissions
-            yield user_service.set_user_permission(admin_id, "admin");
-            yield user_service.set_user_permission(admin_id, "user-management");
-            yield user_service.set_user_permission(admin_id, "user.create");
-            yield user_service.set_user_permission(admin_id, "user.read");
-            yield user_service.set_user_permission(admin_id, "user.update");
-            yield user_service.set_user_permission(admin_id, "user.delete");
-            
-            print("Admin user created with username 'admin' and password 'admin123'\n");
-        }
-        
-        if (!testuser_exists) {
-            print("Creating test user...\n");
-            
-            var test_user = yield user_service.register_user(
-                "testuser", 
-                "test@example.com", 
-                "Test", 
-                "User", 
-                new DateTime.utc(1995, 6, 15, 0, 0, 0.0),
-                "test123",
-                true
-            );
-            testuser_id = test_user.id;
-            
-            yield user_service.set_user_permission(testuser_id, "user.read");
-            print("Test user created with username 'testuser' and password 'test123'\n");
-        } else {
-            print("Test user already exists\n");
-        }
-    }
-}
-
-// =============================================================================
-// APPLICATION SETUP
-// =============================================================================
-
-// =============================================================================
-// ASYNC MAIN LOOP - Required for async initialization
-// =============================================================================
-
-private MainLoop main_loop;
-
-public static int main(string[] args) {
-    int port = args.length > 1 ? int.parse(args[1]) : 8080;
-    
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("              Spry Authentication Example - Complete Demo\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  Port: %d\n", port);
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  Public Endpoints:\n");
-    print("    /              - Home page (public)\n");
-    print("    /register      - Create new account\n");
-    print("    /login         - Login page\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  Protected Endpoints (requires login):\n");
-    print("    /dashboard     - User dashboard\n");
-    print("    /logout        - Logout and clear cookie\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  Admin Endpoints (requires 'user-management' permission):\n");
-    print("    /admin/users   - User management page\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("  Default Users:\n");
-    print("    admin / admin123    - Has all permissions\n");
-    print("    testuser / test123  - Regular user\n");
-    print("═══════════════════════════════════════════════════════════════\n");
-    print("\nPress Ctrl+C to stop the server\n\n");
-    
-    main_loop = new MainLoop();
-    
-    try {
-        start_application.begin(port, (obj, res) => {
-            try {
-                start_application.end(res);
-            } catch (Error e) {
-                printerr("Application error: %s\n", e.message);
-                main_loop.quit();
-            }
-        });
-        
-        main_loop.run();
-        return 0;
-        
-    } catch (Error e) {
-        printerr("Error: %s\n", e.message);
-        return 1;
-    }
-}
-
-/**
- * Start the web application.
- */
-private async void start_application(int port) throws Error {
-    var application = new WebApplication(port);
-    
-    // Enable compression
-    application.use_compression();
-    
-    // Add Spry module for component actions
-    application.add_module<SpryModule>();
-    
-    // Configure the database using InvercargillSqlInversion
-    var db_config = application.container.configure_with<DatabaseConfigurator>();
-    db_config.register_connection(@"sqlite://./db.sqlite");
-    db_config.migrate_on_startup();
-    
-    // Add authentication module to register entity mappings
-    application.add_module<AuthenticationModule>();
-    
-    // Register Authentication system services
-    application.add_scoped<UserService>();
-    
-    // Register Authorisation system services
-    application.add_scoped<AuthorisationService>();
-    
-    // Add the authorisation pipeline component to read tokens from requests
-    // This component creates a scoped AuthorisationContext per request
-    application.add_scoped<AuthorisationPipelineComponent>()
-        .as<Astralis.PipelineComponent>();
-    
-    // Register template with route prefix
-    // MainLayoutTemplate applies to ALL routes (empty prefix)
-    var spry_cfg = application.configure_with<SpryConfigurator>();
-    spry_cfg.add_template<MainLayoutTemplate>("");
-    
-    // Register page components as endpoints
-    application.add_transient<HomePage>();
-    application.add_endpoint<HomePage>(new EndpointRoute(HomePage.ROUTE));
-    
-    application.add_transient<RegisterPage>();
-    application.add_endpoint<RegisterPage>(new EndpointRoute(RegisterPage.ROUTE));
-    
-    application.add_transient<LoginPage>();
-    application.add_endpoint<LoginPage>(new EndpointRoute(LoginPage.ROUTE));
-    
-    application.add_transient<DashboardPage>();
-    application.add_endpoint<DashboardPage>(new EndpointRoute(DashboardPage.ROUTE));
-    
-    // Register logout endpoint
-    application.add_endpoint<LogoutEndpoint>(new EndpointRoute("/logout"));
-    
-    // Register UserAdminPage (admin page wrapping UserManagementComponent)
-    application.add_transient<UserAdminPage>();
-    application.add_endpoint<UserAdminPage>(new EndpointRoute(UserAdminPage.ROUTE));
-    
-    // Register LoginFormComponent (used by LoginPage)
-    application.add_transient<LoginComponent>();
-    
-    // Register new user management components
-    application.add_transient<UserManagementComponent>();
-    application.add_transient<UserComponent>();
-    application.add_transient<UserEditComponent>();
-    
-    // Register CSS as FastResource
-    application.add_startup_endpoint<FastResource>(new EndpointRoute("/styles/main.css"), () => {
-        try {
-            return new FastResource.from_string(MAIN_CSS)
-                .with_content_type("text/css; charset=utf-8")
-                .with_default_compressors();
-        } catch (Error e) {
-            error("Failed to create main CSS resource: %s", e.message);
-        }
-    });
-    
-    print("Starting web server on port %d...\n\n", port);
-    
-    // Seed initial data after migrations have run (migrations execute during application.run())
-    // Use Idle.add() to ensure this runs after the main loop starts
-    GLib.Idle.add(() => {
-        seed_initial_data.begin(application.container);
-        return false; // Don't repeat
-    });
-    
-    application.run();
-}
-
-/**
- * Seed initial data (admin and test users).
- */
-private async void seed_initial_data(Container container) {
-    try {
-        var scope = container.create_scope();
-        var user_service = scope.resolve<UserService>();
-        yield SeedData.ensure_admin_exists(user_service);
-    } catch (Error e) {
-        printerr("Warning: Failed to seed initial data: %s\n", e.message);
-    }
-}

+ 0 - 50
examples/meson.build

@@ -1,50 +0,0 @@
-# CounterComponent Example - demonstrates Spry.Component with outlets for counter page
-executable('counter-component',
-    'CounterComponent.vala',
-    dependencies: [spry_dep, astralis_dep, invercargill_dep, inversion_dep, invercargill_sql_dep, sqlite_dep, invercargill_sql_inversion_dep],
-    install: false
-)
-
-# TodoComponent Example - demonstrates Spry.Component for a complete todo list CRUD
-executable('todo-component',
-    'TodoComponent.vala',
-    dependencies: [spry_dep, astralis_dep, invercargill_dep, inversion_dep, invercargill_sql_dep, sqlite_dep, invercargill_sql_inversion_dep],
-    install: false
-)
-
-# SimpleExample - demonstrates basic Spry.Component usage with outlets
-executable('simple-example',
-    'SimpleExample.vala',
-    dependencies: [spry_dep, astralis_dep, invercargill_dep, inversion_dep, invercargill_sql_dep, sqlite_dep, invercargill_sql_inversion_dep],
-    install: false
-)
-
-# TemplateExample - demonstrates PageComponent and PageTemplate for template-based pages
-executable('template-example',
-    'TemplateExample.vala',
-    dependencies: [spry_dep, astralis_dep, invercargill_dep, inversion_dep, invercargill_sql_dep, sqlite_dep, invercargill_sql_inversion_dep],
-    install: false
-)
-
-# ProgressExample - demonstrates continuation feature for real-time progress updates via SSE
-executable('progress-example',
-    'ProgressExample.vala',
-    dependencies: [spry_dep, astralis_dep, invercargill_dep, inversion_dep, invercargill_sql_dep, sqlite_dep, invercargill_sql_inversion_dep],
-    install: false
-)
-
-# UsersExample - demonstrates the complete Spry Authentication/Authorisation system
-# Includes: user registration, authentication, permissions, protected pages
-executable('users-example',
-    'UsersExample.vala',
-    dependencies: [spry_dep, astralis_dep, invercargill_dep, inversion_dep, invercargill_sql_dep, sqlite_dep, invercargill_sql_inversion_dep],
-    install: false
-)
-
-# ContentInjectionExample - demonstrates content injection with spry-content tag
-executable('content-injection-example',
-    'ContentInjectionExample.vala',
-    dependencies: [spry_dep, astralis_dep, invercargill_dep, inversion_dep, invercargill_sql_dep, sqlite_dep, invercargill_sql_inversion_dep],
-    install: false
-)
-

+ 0 - 5
generate-static-resources.sh

@@ -1,5 +0,0 @@
-#!/bin/bash
-
-cd src/Static
-spry-mkssr Sources/htmx.min.js -n htmx.js --vala --ns Spry.Static
-spry-mkssr Sources/htmx-sse.min.js -n htmx-sse.js --vala --ns Spry.Static

+ 0 - 592
important-details.md

@@ -1,592 +0,0 @@
-# Spry Framework - Important Details
-
-## Component Basics
-
-### Template DOM is NOT Persisted
-- The template is fresh on every request
-- Any state set via setters (like `title`, `completed`) is NOT available in `handle_action()`
-- Always use `prepare()` to fetch data from store and set up the template
-
-### The `prepare()` Method
-- Called automatically before serialization
-- Use this to fetch data from stores and populate the template
-- Centralizes data fetching logic in one place
-
-```vala
-public override async void prepare() throws Error {
-    var item = store.get_by_id(_item_id);
-    if (item == null) return;
-    
-    this["title"].text_content = item.title;
-    this["button"].text_content = item.completed ? "Undo" : "Done";
-}
-```
-
-### The `prepare_once()` Method
-- Called only once before the first `prepare()` call
-- Useful for one-time initialization that should not repeat on every render
-- Runs before `prepare()` in the same request lifecycle
-
-```vala
-public override async void prepare_once() throws Error {
-    // One-time setup, e.g., loading initial data
-    initial_data = yield fetch_initial_data();
-}
-```
-
-### The `handle_action()` Method
-- Called when HTMX requests trigger an action
-- Modify state in stores, then let `prepare()` handle template updates
-- For delete with `hx-swap="delete"`, just return (no content needed)
-
-```vala
-public async override void handle_action(string action) throws Error {
-    var id = get_id_from_query_params();
-    _item_id = id; // Set for prepare()
-    
-    switch (action) {
-        case "Toggle":
-            store.toggle(id);
-            break; // prepare() will be called automatically
-        case "Delete":
-            store.remove(id);
-            return; // HTMX removes element via hx-swap="delete"
-    }
-}
-```
-
-## Real-Time Updates with Continuations (SSE)
-
-### Overview
-
-The continuation feature allows a Component to send real-time updates to the client via Server-Sent Events (SSE). This is useful for:
-- Long-running task progress reporting
-- Real-time status updates
-- Live data streaming
-
-### The `continuation()` Method
-
-Override `continuation(ContinuationContext context)` to send SSE events:
-
-```vala
-public async override void continuation(ContinuationContext continuation_context) throws Error {
-    for (int i = 0; i <= 100; i += 10) {
-        percent = i;
-        status = @"Processing... $(i)%";
-        
-        // Send dynamic section updates to the client
-        yield continuation_context.send_dynamic("progress-bar");
-        yield continuation_context.send_dynamic("status");
-        
-        Timeout.add(500, () => {
-            continuation.callback();
-            return false;
-        });
-        yield;
-    }
-    
-    status = "Complete!";
-    yield continuation_context.send_dynamic("status");
-}
-```
-
-### The `continuation_canceled()` Method
-
-Called when the client disconnects from the SSE stream:
-
-```vala
-public async override void continuation_canceled() throws Error {
-    // Clean up resources when client disconnects
-    cleanup_task();
-}
-```
-
-### ContinuationContext API
-
-| Method | Description |
-|--------|-------------|
-| `send_dynamic(name)` | Send a dynamic section (by `spry-dynamic` name) as an SSE event |
-| `send_json(event_type, node)` | Send JSON data as an SSE event |
-| `send_string(event_type, data)` | Send raw string data as an SSE event |
-| `send_full_update(event_type)` | Send the entire component document |
-| `send_event(event)` | Send a custom `SseEvent` |
-
-### The `spry-continuation` Attribute
-
-Add `spry-continuation` to an element to enable SSE for its children:
-
-```vala
-public override string markup { get {
-    return """
-    <div spry-continuation>
-        <div class="progress-container" spry-dynamic="progress-bar">
-            <div class="progress-bar" spry-unique
-                 content-expr='format("{{this.percent}}%")' 
-                 style-width-expr='format("{{this.percent}}%")'>
-                0%
-            </div>
-        </div>
-        <div class="status" spry-dynamic="status">
-            <strong>Status:</strong> <span spry-unique content-expr="this.status">Initializing...</span>
-        </div>
-    </div>
-    """;
-}}
-```
-
-The `spry-continuation` attribute is shorthand for:
-- `hx-ext="sse"` - Enable HTMX SSE extension
-- `sse-connect="(auto-generated-endpoint)"` - Connect to the SSE endpoint
-- `sse-close="_spry-close"` - Close event name
-
-### The `spry-dynamic` Attribute
-
-Use `spry-dynamic="name"` on child elements to mark them as updatable sections:
-
-```html
-<div class="progress-container" spry-dynamic="progress-bar">...</div>
-<div class="status" spry-dynamic="status">...</div>
-```
-
-**Requirements:**
-- Must be a child of an element with `spry-continuation`
-- Automatically gets `sse-swap="_spry-dynamic-{name}"` and `hx-swap="outerHTML"`
-
-When `continuation_context.send_dynamic("progress-bar")` is called:
-1. The element with `spry-dynamic="progress-bar"` is located
-2. Its HTML content is rendered and sent as an SSE event
-3. HTMX swaps it into the matching element on the client
-
-### The `spry-unique` Attribute
-
-Use `spry-unique` to generate unique IDs for elements that need stable targeting:
-
-```html
-<div class="progress-bar" spry-unique>...</div>
-```
-
-**Restrictions:**
-- Cannot specify an `id` attribute on the same element
-- Cannot be used inside `spry-per-*` loops (or children of loops)
-
-The generated ID format is `_spry-unique-{counter}-{context_key}`.
-
-### Required Scripts for SSE
-
-Include the HTMX SSE extension in your markup:
-
-```html
-<script spry-res="htmx.js"></script>
-<script spry-res="htmx-sse.js"></script>
-```
-
-## HTMX Integration
-
-### Declarative Attributes
-
-#### `spry-action` - Declare HTMX Actions
-- `spry-action=":ActionName"` - Action on same component (e.g., `:Toggle`)
-- `spry-action="ComponentName:ActionName"` - Action on different component (cross-component)
-
-#### `spry-target` - Scoped Targeting (within same component)
-- `spry-target="sid"` - Targets element by its `sid` attribute
-- Only works within the SAME component
-- Automatically generates proper `hx-target` with unique IDs
-
-#### `hx-target` - Global Targeting (cross-component)
-- Use `hx-target="#id"` to target elements anywhere on the page
-- Requires the target element to have an `id` attribute (not just `sid`)
-
-#### `hx-swap` - Swap Strategies
-- `hx-swap="outerHTML"` - Replace entire target element (prevents nesting)
-- `hx-swap="delete"` - Remove target element (no response content needed)
-
-### Out-of-Band Swaps with `spry-global` and `add_globals_from()`
-
-Update multiple elements on the page with a single response using `spry-global`:
-
-```vala
-// 1. Add spry-global to elements that may need OOB updates
-// 2. Use prepare() to fetch data from store - no manual property setting needed!
-
-class HeaderComponent : Component {
-    private TodoStore todo_store = inject<TodoStore>();
-    
-    public override string markup { get {
-        return """
-        <div class="card" id="header" spry-global="header">
-            <h1>Todo App</h1>
-            <div sid="total"></div>
-        </div>
-        """;
-    }}
-    
-    // prepare() fetches data from store automatically
-    public override async void prepare() throws Error {
-        this["total"].text_content = todo_store.count().to_string();
-    }
-}
-
-// 3. Inject the component and pass it to add_globals_from()
-
-class ItemComponent : Component {
-    private HeaderComponent header = inject<HeaderComponent>();
-    
-    public override string markup { get {
-        return """
-        <div sid="item">...</div>
-        """;
-    }}
-    
-    public async override void handle_action(string action) throws Error {
-        store.toggle(id);
-        // Add header globals for OOB swap (header's prepare() fetches stats)
-        add_globals_from(header);
-    }
-}
-```
-
-The `spry-global="key"` attribute:
-- Automatically adds `hx-swap-oob="true"` when the element appears in a response
-- HTMX finds the existing element on the page and swaps it in place
-- Use `add_globals_from(component)` to append spry-global elements from another component
-- The component's `prepare()` method is called automatically to populate data
-
-### Passing Data with `hx-vals`
-
-Since template DOM is not persisted, use `hx-vals` to pass data:
-
-```vala
-// In prepare() - set on parent element, inherited by children
-this["item"].set_attribute("hx-vals", @"{\"id\":$_item_id}");
-
-// In handle_action()
-var id_str = http_context.request.query_params.get_any_or_default("id");
-var id = int.parse(id_str);
-```
-
-**Note**: `hx-vals` is inherited by child elements, so set it on the parent div rather than individual buttons.
-
-## Declarative Expression Attributes
-
-### Expression Attributes (`*-expr`)
-
-Use `*-expr` attributes to dynamically set any attribute based on component properties:
-
-```vala
-class ProgressComponent : Component {
-    public int percent { get; set; }
-    
-    public override string markup { get {
-        return """
-        <div class="progress-bar" 
-             content-expr='format("{{this.percent}}%")' 
-             style-width-expr='format("{{this.percent}}%")'>
-            0%
-        </div>
-        """;
-    }}
-}
-```
-
-Expression attribute patterns:
-- `content-expr="expression"` - Set text/HTML content
-- `class-expr="expression"` - Set CSS classes
-- `style-expr="expression"` - Set inline styles (e.g., `style-width-expr`)
-- `any-attr-expr="expression"` - Set any attribute dynamically
-
-### Conditional Class Expressions
-
-For `class-*` attributes, boolean expressions add/remove the class:
-
-```html
-<div class-completed-expr="this.is_completed">Item</div>
-```
-
-If `this.is_completed` is `true`, the `completed` class is added.
-
-### Conditional Rendering with `spry-if`
-
-Use `spry-if`, `spry-else-if`, and `spry-else` for conditional rendering:
-
-```html
-<div spry-if="this.is_admin">Admin Panel</div>
-<div spry-else-if="this.is_moderator">Moderator Panel</div>
-<div spry-else>User Panel</div>
-```
-
-### Loop Rendering with `spry-per-*`
-
-Use `spry-per-{varname}="expression"` to iterate over collections:
-
-```html
-<div spry-per-task="this.tasks">
-    <span content-expr="task.name"></span>
-</div>
-```
-
-The variable name after `spry-per-` (e.g., `task`) becomes available in nested expressions.
-
-### Static Resources with `spry-res`
-
-Use `spry-res` to reference Spry's built-in static resources:
-
-```html
-<script spry-res="htmx.js"></script>
-<script spry-res="htmx-sse.js"></script>
-```
-
-This resolves to `/_spry/res/{resource-name}` automatically.
-
-## IoC Composition
-
-### Registration Patterns
-
-```vala
-// State as singleton
-application.add_singleton<AppState>();
-
-// Factory as scoped
-application.add_scoped<ComponentFactory>();
-
-// Components as transient
-application.add_transient<MyComponent>();
-```
-
-### Dependency Injection
-
-Use `inject<T>()` in field initializers:
-
-```vala
-class MyComponent : Component {
-    private TodoStore store = inject<TodoStore>();
-    private ComponentFactory factory = inject<ComponentFactory>();
-    private HttpContext http_context = inject<HttpContext>();
-}
-```
-
-### Creating Components
-
-Use `ComponentFactory.create<T>()` (not `inject<T>()` which only works in field initializers):
-
-```vala
-var child = factory.create<ChildComponent>();
-child.item_id = item.id;
-items.add(child);
-```
-
-## Common Patterns
-
-### List with Items Pattern
-
-```vala
-// Parent component
-class ListComponent : Component {
-    public void set_items(Enumerable<Renderable> items) {
-        set_outlet_children("items", items);
-    }
-    
-    public override string markup { get {
-        return """
-        <div id="my-list" sid="my-list">
-            <spry-outlet sid="items"/>
-        </div>
-        """;
-    }}
-}
-
-// Item component with prepare()
-class ItemComponent : Component {
-    private TodoStore store = inject<TodoStore>();
-    private HttpContext http_context = inject<HttpContext>();
-    private HeaderComponent header = inject<HeaderComponent>();
-    
-    private int _item_id;
-    public int item_id { set { _item_id = value; } }
-    
-    public override string markup { get {
-        return """
-        <div class="item" sid="item">
-            <span sid="title"></span>
-            <button sid="toggle-btn" spry-action=":Toggle" spry-target="item" hx-swap="outerHTML"></button>
-        </div>
-        """;
-    }}
-    
-    public override void prepare() throws Error {
-        var item = store.get_by_id(_item_id);
-        this["title"].text_content = item.title;
-        // hx-vals on parent is inherited by children
-        this["item"].set_attribute("hx-vals", @"{\"id\":$_item_id}");
-    }
-    
-    public async override void handle_action(string action) throws Error {
-        var id = int.parse(http_context.request.query_params.get_any_or_default("id"));
-        _item_id = id;
-        
-        if (action == "Toggle") {
-            store.toggle(id);
-            // Add header globals for OOB swap (header's prepare() fetches stats)
-            add_globals_from(header);
-        }
-    }
-}
-
-// Creating the list
-var items = new Series<Renderable>();
-store.all().iterate((item) => {
-    var component = factory.create<ItemComponent>();
-    component.item_id = item.id; // Only set ID, prepare() handles rest
-    items.add(component);
-});
-list.set_items(items);
-```
-
-### Cross-Component Action Pattern
-
-```vala
-// Form in one component triggers action on another
-<form spry-action="ListComponent:Add" hx-target="#my-list" hx-swap="outerHTML">
-    <input name="title"/>
-    <button type="submit">Add</button>
-</form>
-
-// ListComponent handles the Add action
-class ListComponent : Component {
-    public async override void handle_action(string action) throws Error {
-        if (action == "Add") {
-            var title = http_context.request.query_params.get_any_or_default("title");
-            store.add(title);
-        }
-        // Rebuild list...
-    }
-}
-```
-
-## HTML Escaping
-
-`<pre>` and `<code>` tags do NOT escape their contents. Manually escape:
-
-```vala
-// Wrong
-<pre><button spry-action=":Toggle">Click</button></pre>
-
-// Correct
-<pre>&lt;button spry-action=":Toggle"&gt;Click&lt;/button&gt;</pre>
-```
-
-## SpryModule
-
-Automatically registers `ComponentEndpoint` at `/_spry/{component-id}/{action}`:
-
-```vala
-application.add_module<SpryModule>();
-```
-
-This enables the declarative `spry-action` attributes to work without manual endpoint registration.
-
-## Declarative Child Components with `<spry-component>`
-
-### When to Use `<spry-component>` vs `<spry-outlet>`
-
-- **`<spry-component name="ComponentName" sid="..."/>`** - For single, known child components
-- **`<spry-outlet sid="..."/>`** - For dynamic lists (multiple items from data)
-
-### Declaring Child Components
-
-Use `<spry-component>` in markup for declarative composition:
-
-```vala
-class TodoPage : PageComponent {
-    public override string markup { get {
-        return """
-        <!DOCTYPE html>
-        <html>
-        <body>
-            <spry-component name="HeaderComponent" sid="header"/>
-            <spry-component name="TodoListComponent" sid="todo-list"/>
-            <spry-component name="AddFormComponent" sid="add-form"/>
-            <spry-component name="FooterComponent" sid="footer"/>
-        </body>
-        </html>
-        """;
-    }}
-}
-```
-
-### Accessing Child Components with `get_component_child<T>()`
-
-Use `get_component_child<T>(sid)` in `prepare()` to access and configure child components:
-
-```vala
-class TodoPage : PageComponent {
-    private TodoStore todo_store = inject<TodoStore>();
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override async void prepare() throws Error {
-        // Get child component and configure it
-        var todo_list = get_component_child<TodoListComponent>("todo-list");
-        
-        // Populate the list (which still uses spry-outlet for dynamic items)
-        var items = new Series<Renderable>();
-        todo_store.all().iterate((item) => {
-            var component = factory.create<TodoItemComponent>();
-            component.item_id = item.id;
-            items.add(component);
-        });
-        todo_list.set_items(items);
-    }
-}
-```
-
-## PageComponent - Combining Component and Endpoint
-
-`PageComponent` is a base class that acts as both a `Component` AND an `Endpoint`. This eliminates the need for separate endpoint classes:
-
-```vala
-// Before: Separate endpoint class
-class HomePageEndpoint : Object, Endpoint {
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public async HttpResult handle_request(HttpContext context, RouteContext route) throws Error {
-        var page = factory.create<PageLayoutComponent>();
-        return yield page.to_result();
-    }
-}
-
-// After: PageComponent handles both roles
-class TodoPage : PageComponent {
-    public override string markup { get { return "..."; } }
-    public override async void prepare() throws Error { /* ... */ }
-}
-```
-
-## SpryConfigurator - Component and Page Registration
-
-Use `SpryConfigurator` to register components and pages in a structured way:
-
-```vala
-// Get the configurator
-var spry_cfg = application.configure_with<SpryConfigurator>();
-
-// Register child components (transient lifecycle)
-spry_cfg.add_component<HeaderComponent>();
-spry_cfg.add_component<TodoListComponent>();
-spry_cfg.add_component<TodoItemComponent>();
-spry_cfg.add_component<AddFormComponent>();
-spry_cfg.add_component<FooterComponent>();
-
-// Register pages (scoped lifecycle, acts as Endpoint)
-spry_cfg.add_page<TodoPage>(new EndpointRoute("/"));
-
-// Other endpoints still use add_endpoint
-application.add_endpoint<TodoJsonEndpoint>(new EndpointRoute("/api/todos"));
-```
-
-### Registration Methods
-
-| Method | Lifecycle | Use Case |
-|--------|-----------|----------|
-| `add_component<T>()` | Transient | Child components created via factory |
-| `add_page<T>(route)` | Scoped | Page components that act as endpoints |
-| `add_template<T>(prefix)` | Transient | Page templates for layout wrapping |

+ 0 - 399
important-notes-on-writing-documentation-pages.md

@@ -1,399 +0,0 @@
-# Important Notes on Writing Documentation Pages for Spry
-
-This document captures key learnings and patterns for creating documentation pages in the Spry demo site.
-
-## Page Structure
-
-### PageComponent Pattern
-
-Documentation pages extend `PageComponent` (not `Component`). PageComponent is special because it acts as both a Component AND an Endpoint, meaning it handles its own route.
-
-```vala
-public class Demo.Pages.ComponentsOverviewPage : PageComponent {
-    public override string markup { get {
-        return """...""";
-    }}
-    
-    public override async void prepare() throws Error {
-        // Setup code
-    }
-}
-```
-
-### Template Wrapping
-
-**IMPORTANT**: Page markup should NOT include the full HTML structure (`<!DOCTYPE html>`, `<html>`, `<head>`, `<body>`). The `MainTemplate` class automatically wraps page content with the proper HTML structure, including:
-
-- DOCTYPE and html tags
-- `<head>` with stylesheets and scripts
-- `<body>` with the page container
-
-Your page markup should start with the content container:
-
-```vala
-public override string markup { get {
-    return """
-    <div class="page-container">
-        <spry-component name="NavSidebarComponent" sid="nav"/>
-        <main class="main-content">
-            <!-- Your content here -->
-        </main>
-    </div>
-    """;
-}}
-```
-
-### Navigation Sidebar
-
-Every documentation page should include the NavSidebarComponent and set its `current_path` property in `prepare()`:
-
-```vala
-public override async void prepare() throws Error {
-    var nav = get_component_child<NavSidebarComponent>("nav");
-    nav.current_path = "/components/overview";
-}
-```
-
-## Required Imports
-
-```vala
-using Spry;
-using Astralis;      // Required for HttpContext
-using Inversion;     // Required for inject<T>()
-using Invercargill.DataStructures;  // Required for Series<T>
-```
-
-## String Handling and Code Examples
-
-### Triple-Quote String Escaping
-
-**CRITICAL**: Vala's triple-quoted strings (`"""`) CANNOT contain another triple-quoted string sequence. This means you cannot embed code examples that show triple-quoted strings directly.
-
-**Wrong** (will fail to compile):
-```vala
-// This breaks because """ appears inside """
-return """
-    <pre><code>
-public override string markup { get {
-    return """<div>content</div>""";  // SYNTAX ERROR!
-}}
-    </code></pre>
-""";
-```
-
-**Solution**: Use regular strings with `\n` for line breaks and string concatenation:
-
-```vala
-private const string COMPONENT_CODE = 
-    "public class MyComponent : Component {\n" +
-    "    public override string markup { get {\n" +
-    "        return \"\"\"<div>content</div>\"\"\";\n" +
-    "    }}\n" +
-    "}";
-```
-
-### Escaping Quotes in Code Examples
-
-When code contains double quotes, you need to escape them:
-- In triple-quoted strings: Use `\"` for literal quotes
-- In regular strings: Use `\\\"` (escaped backslash + escaped quote)
-
-```vala
-// Inside a triple-quoted string:
-"this[\"element\"].text_content = \"Hello\";"
-
-// Inside a regular string (more escaping needed):
-"this[\\\"element\\\"].text_content = \\\"Hello\\\";"
-```
-
-### JSON in Code Examples
-
-JSON strings in code examples need heavy escaping:
-
-```vala
-// Showing hx-vals in code:
-"this[\"button\"].set_attribute(\"hx-vals\", \"{\\\"id\\\": 123}\");"
-```
-
-## CodeBlockComponent Usage
-
-Use `CodeBlockComponent` for displaying code examples with syntax highlighting:
-
-```vala
-// In markup:
-"<spry-component name=\"CodeBlockComponent\" sid=\"example-code\"/>"
-
-// In prepare():
-var code_block = get_component_child<CodeBlockComponent>("example-code");
-code_block.language = "vala";
-code_block.code = YOUR_CODE_STRING;
-```
-
-Supported languages: `vala`, `xml`, `css`, `javascript`
-
-## DemoHostComponent Usage
-
-Use `DemoHostComponent` for interactive demos that show source code alongside a working demo:
-
-```vala
-// In markup:
-"<spry-component name=\"DemoHostComponent\" sid=\"demo\"/>"
-
-// In prepare():
-var demo = get_component_child<DemoHostComponent>("demo");
-demo.source_file = "DemoComponents/SimpleCounterDemo.vala";
-
-// Create and set the actual demo component
-var counter = factory.create<SimpleCounterDemo>();
-demo.set_outlet_child("demo-outlet", counter);
-```
-
-The DemoHostComponent provides:
-- Tabbed interface (Source / Demo)
-- Syntax-highlighted source code display
-- Live demo outlet
-
-## Component Lifecycle and State
-
-### New Instance Per Request
-
-**IMPORTANT**: Components are instantiated fresh on each request. You cannot store state directly in component instance fields between requests.
-
-**Wrong** (state won't persist):
-```vala
-public class MyComponent : Component {
-    private int counter = 0;  // Reset to 0 on every request!
-}
-```
-
-**Correct** (use a singleton store):
-```vala
-public class MyComponent : Component {
-    private MyStore store = inject<MyStore>();  // Singleton, persists
-}
-
-public class MyStore : Object {
-    public int counter { get; set; default = 0; }  // Persists between requests
-}
-```
-
-### prepare() Must Be Async
-
-The `prepare()` method must be marked `async`:
-
-```vala
-public override async void prepare() throws Error {
-    // ...
-}
-```
-
-## Dependency Injection
-
-Use the `inject<T>()` pattern for dependency injection:
-
-```vala
-private ComponentFactory factory = inject<ComponentFactory>();
-private HttpContext http_context = inject<HttpContext>();
-private MyStore store = inject<MyStore>();  // Must be registered in Main.vala
-```
-
-Register singleton stores in `demo/Main.vala`:
-
-```vala
-// In Main.vala configure() method:
-container.register<MyStore>(new MyStore());
-```
-
-## Series<T> Collection
-
-The `Series<T>` type from Invercargill is used for collections:
-
-```vala
-public Series<TodoItem> items { get; set; default = new Series<TodoItem>(); }
-
-// Add items:
-items.add(new TodoItem(1, "Task"));
-
-// Iterate:
-foreach (var item in items) {
-    // ...
-}
-
-// Get count:
-int count = items.length;  // NOT .size!
-
-// Create new series:
-var new_items = new Series<TodoItem>();
-```
-
-## Common Patterns
-
-### Element Selection and Modification
-
-```vala
-// Select by sid:
-this["my-element"].text_content = "Hello";
-this["my-element"].add_class("active");
-this["my-element"].set_attribute("data-id", "123");
-
-// Set inner HTML:
-this["container"].inner_html = "<span>Dynamic content</span>";
-```
-
-### Handling Actions
-
-```vala
-public async override void handle_action(string action) throws Error {
-    switch (action) {
-        case "Save":
-            // Get form data
-            var value = http_context.request.query_params.get_any_or_default("field_name");
-            // Process...
-            break;
-        case "Delete":
-            // ...
-            break;
-    }
-}
-```
-
-### Using Outlets for Child Components
-
-```vala
-// In markup:
-"<ul><spry-outlet sid=\"items-outlet\"/></ul>"
-
-// In prepare():
-var children = new Series<Renderable>();
-foreach (var item in store.items) {
-    var component = factory.create<ChildComponent>();
-    component.item_id = item.id;
-    children.add(component);
-}
-set_outlet_children("items-outlet", children);
-```
-
-## Routes and Registration
-
-### Route Convention
-
-Routes follow the pattern `/section/page-name`:
-- `/components/overview`
-- `/components/actions`
-- `/components/outlets`
-
-### Registration in Main.vala
-
-Pages are registered with the router:
-
-```vala
-// In Main.vala:
-router.add_route("/components/overview", typeof(ComponentsOverviewPage));
-```
-
-Components used in demos must be registered with the factory:
-
-```vala
-factory.register<SimpleCounterDemo>();
-factory.register<TodoListDemo>();
-```
-
-## File Organization
-
-```
-demo/
-├── Pages/                      # PageComponent classes
-│   ├── ComponentsOverviewPage.vala
-│   ├── ComponentsActionsPage.vala
-│   └── ...
-├── Components/                 # Shared UI components
-│   ├── NavSidebarComponent.vala
-│   ├── CodeBlockComponent.vala
-│   └── DemoHostComponent.vala
-├── DemoComponents/             # Demo-specific components
-│   ├── SimpleCounterDemo.vala
-│   ├── TodoListDemo.vala
-│   └── ProgressDemo.vala
-├── Static/
-│   └── docs.css               # Documentation styles
-├── Main.vala                   # App configuration and routing
-├── MainTemplate.vala           # HTML wrapper template
-└── meson.build                 # Build configuration
-```
-
-## Build Configuration
-
-Add new source files to `demo/meson.build`:
-
-```vala
-demo_sources = files(
-    'Main.vala',
-    'MainTemplate.vala',
-    'Pages/ComponentsOverviewPage.vala',
-    'Pages/ComponentsActionsPage.vala',
-    'DemoComponents/SimpleCounterDemo.vala',
-    # ... etc
-)
-```
-
-## Styling Conventions
-
-Documentation pages use CSS classes from `docs.css`:
-
-- `.doc-hero` - Hero section with title
-- `.doc-section` - Content sections
-- `.doc-card` - Card containers
-- `.doc-table` - Tables for reference
-- `.doc-example` - Code example containers
-- `.demo-container` - Interactive demo containers
-
-## Debugging Tips
-
-1. **Build errors with strings**: Check for unescaped quotes or triple-quote conflicts
-2. **inject<T>() not found**: Add `using Inversion;`
-3. **HttpContext not found**: Add `using Astralis;`
-4. **Property read-only**: Add `set;` to property definition
-5. **Method signature mismatch**: Ensure `prepare()` is `async`
-
-## Quick Reference: Page Template
-
-```vala
-using Spry;
-using Astralis;
-using Inversion;
-
-public class Demo.Pages.YourPage : PageComponent {
-    
-    private ComponentFactory factory = inject<ComponentFactory>();
-    
-    public override string markup { get {
-        return """
-        <div class="page-container">
-            <spry-component name="NavSidebarComponent" sid="nav"/>
-            <main class="main-content">
-                <div class="doc-hero">
-                    <h1>Your Page Title</h1>
-                    <p class="doc-subtitle">Brief description</p>
-                </div>
-                
-                <div class="doc-section">
-                    <h2>Section Title</h2>
-                    <p>Content...</p>
-                    
-                    <spry-component name="CodeBlockComponent" sid="example"/>
-                </div>
-            </main>
-        </div>
-        """;
-    }}
-    
-    public override async void prepare() throws Error {
-        var nav = get_component_child<NavSidebarComponent>("nav");
-        nav.current_path = "/your/path";
-        
-        var code = get_component_child<CodeBlockComponent>("example");
-        code.language = "vala";
-        code.code = "your code here";
-    }
-}
-```

+ 0 - 453
invercargill-format-migration-details.md

@@ -1,453 +0,0 @@
-# Format Function v2 Migration Guide
-
-## Overview
-
-The `format()` global function in the Invercargill expression system has been redesigned from printf-style formatting to handlebars-style interpolation. This is a **breaking change** that affects all code using the `format()` function.
-
-### What Changed
-
-| Aspect | Before (v1) | After (v2) |
-|--------|-------------|------------|
-| Syntax | `%s`, `%d`, `%f`, etc. | `{{expression}}` |
-| Arguments | Template + variadic args | Template only |
-| Value source | Positional arguments | EvaluationContext |
-| Precision | `%.2f`, `%5d` supported | No format specifiers |
-
-### Why This Change
-
-1. **Consistency**: Handlebars-style interpolation is more widely recognized in modern templating
-2. **Expressiveness**: Full expressions can now be evaluated inside interpolation blocks
-3. **Context integration**: Values come from the EvaluationContext, enabling more dynamic templates
-4. **Readability**: `{{name}}` is more self-documenting than `%s` with positional arguments
-
----
-
-## Breaking Changes
-
-### Removed Features
-
-1. **Format specifiers** - All printf-style specifiers removed:
-   - `%s` (string)
-   - `%d`, `%i` (integer)
-   - `%f` (float)
-   - `%.Nf` (float with precision)
-   - `%x`, `%X` (hexadecimal)
-   - `%o` (octal)
-   - `%%` (literal percent)
-
-2. **Precision/width control** - No more `%.2f` or `%10s` formatting
-
-3. **Positional arguments** - No additional arguments after the template
-
-4. **Length modifiers** - No more `ll`, `h`, `l`, etc.
-
-### Error Handling Changes
-
-| Scenario | Old Behavior | New Behavior |
-|----------|--------------|--------------|
-| Missing argument | Error at runtime | N/A - no positional args |
-| Unclosed `{{` | N/A | `INVALID_SYNTAX` error |
-| Invalid expression in `{{}}` | N/A | `INVALID_SYNTAX` with details |
-| Missing variable | N/A | `NON_EXISTANT_PROPERTY` error |
-
----
-
-## Migration Examples
-
-### Basic String Substitution
-
-**Before:**
-```javascript
-format("Hello, %s!", name)
-```
-
-**After:**
-```javascript
-format("Hello, {{name}}!")
-```
-
-### Integer Formatting
-
-**Before:**
-```javascript
-format("You have %d items", count)
-format("ID: %i", id)
-```
-
-**After:**
-```javascript
-format("You have {{count}} items")
-format("ID: {{id}}")
-```
-
-### Multiple Arguments
-
-**Before:**
-```javascript
-format("%s #%i: %s", category, id, title)
-```
-
-**After:**
-```javascript
-format("{{category}} #{{id}}: {{title}}")
-```
-
-### Float/Double Values
-
-**Before:**
-```javascript
-format("Price: %.2f", price)  // With precision
-format("Value: %f", amount)   // Without precision
-```
-
-**After:**
-```javascript
-format("Price: {{price}}")    // No precision control
-format("Value: {{amount}}")
-```
-
-> **Note:** Precision formatting is not currently supported. If you need formatted numbers, consider pre-formatting values before passing to the expression context.
-
-### Hexadecimal Output
-
-**Before:**
-```javascript
-format("Hex: 0x%x", value)
-format("HEX: 0x%X", value)
-```
-
-**After:**
-```javascript
-// No direct equivalent - use stringify with pre-formatted value
-// Or add a hex() helper function to your context
-```
-
-### Literal Percent Sign
-
-**Before:**
-```javascript
-format("100%% complete")
-```
-
-**After:**
-```javascript
-format("100% complete")  // % is now a literal character
-```
-
----
-
-## New Features
-
-### Expression Evaluation
-
-The new `format()` supports full expressions inside interpolation blocks:
-
-```javascript
-// Arithmetic
-format("Sum: {{a + b}}")
-format("Product: {{x * y}}")
-format("Total: {{price * quantity}}")
-
-// Comparisons (outputs "true" or "false")
-format("Is equal: {{a == b}}")
-format("Is valid: {{age >= 18}}")
-
-// Ternary expressions
-format("Status: {{active ? 'active' : 'inactive'}}")
-format("Role: {{isAdmin ? 'Administrator' : 'User'}}")
-
-// Complex expressions
-format("Result: {{(a + b) * c}}")
-```
-
-### Property Access
-
-Access nested properties directly in templates:
-
-```javascript
-// Object property access
-format("User: {{user.name}}")
-format("Email: {{user.email}}")
-
-// Deep nesting
-format("City: {{user.address.city}}")
-format("ZIP: {{user.address.zipCode}}")
-
-// Chained method calls
-format("First: {{items.first().name}}")
-format("Count: {{items.count()}}")
-```
-
-### Whitespace Handling
-
-Whitespace inside `{{}}` is automatically trimmed:
-
-```javascript
-format("Value: {{name}}")      // Standard
-format("Value: {{ name }}")    // With spaces - equivalent
-format("Value: {{  name  }}")  // Multiple spaces - equivalent
-```
-
-### Empty Expressions
-
-Empty expressions produce empty strings:
-
-```javascript
-format("Hello{{}}World")       // → "HelloWorld"
-format("Hello{{ }}World")      // → "HelloWorld"
-```
-
----
-
-## Escape Sequences
-
-To include literal braces in your output, use backslash escaping:
-
-### Literal `{{`
-
-```javascript
-format("Template syntax: \\{{name}}")
-// Output: "Template syntax: {{name}}"
-```
-
-### Literal `}}`
-
-```javascript
-format("End of block: \\}}")
-// Output: "End of block: }}"
-```
-
-### Literal Backslash
-
-```javascript
-format("Path: C:\\\\Users")
-// Output: "Path: C:\Users"
-```
-
-### Escape Sequence Summary
-
-| Sequence | Output |
-|----------|--------|
-| `\{{` | `{{` |
-| `\}}` | `}}` |
-| `\\` | `\` |
-
----
-
-## The `stringify()` Function
-
-A new `stringify()` global function is available as an alternative for simple concatenation:
-
-### Basic Usage
-
-```javascript
-stringify(42)                          // → "42"
-stringify("Hello", " ", "World")       // → "Hello World"
-stringify(1, " + ", 2, " = ", 3)       // → "1 + 2 = 3"
-```
-
-### With Variables
-
-```javascript
-stringify("The answer is: ", answer)
-stringify(name, " is ", age, " years old")
-```
-
-### With Expressions
-
-```javascript
-stringify("Sum: ", 2 + 3)              // → "Sum: 5"
-stringify("Is active: ", active)       // → "Is active: true"
-```
-
-### Null Handling
-
-```javascript
-stringify(null)                        // → "" (empty string)
-stringify("Value: ", null)             // → "Value: "
-```
-
-### Boolean Output
-
-```javascript
-stringify(true, " or ", false)         // → "true or false"
-```
-
-### When to Use `stringify()` vs `format()`
-
-| Use `format()` when... | Use `stringify()` when... |
-|------------------------|---------------------------|
-| You have a template string | You need simple concatenation |
-| You want inline expressions | Values are pre-computed |
-| The structure is complex | The output is straightforward |
-| You need escape sequences | You don't need templating |
-
----
-
-## Error Handling
-
-### Common Errors
-
-#### Unclosed Expression
-
-```javascript
-format("Hello {{name")
-// Error: INVALID_SYNTAX - "Unclosed expression at position 6: missing }}"
-```
-
-**Fix:** Ensure all `{{` have matching `}}`
-
-```javascript
-format("Hello {{name}}")
-```
-
-#### Invalid Expression Syntax
-
-```javascript
-format("Value: {{1 +}}")
-// Error: INVALID_SYNTAX - "Error in expression '1 +': ..."
-```
-
-**Fix:** Ensure expressions are syntactically valid
-
-```javascript
-format("Value: {{1 + 2}}")
-```
-
-#### Missing Variable
-
-```javascript
-format("Hello {{name}}")
-// Error: NON_EXISTANT_PROPERTY if 'name' not in context
-```
-
-**Fix:** Ensure all referenced variables exist in the EvaluationContext
-
-```javascript
-// Before evaluating, ensure context has the variable:
-props.set("name", new NativeElement<string?>("World"));
-```
-
----
-
-## Migration Checklist
-
-- [ ] Identify all `format()` calls in your codebase
-- [ ] Replace `%s` with `{{variableName}}`
-- [ ] Replace `%d`, `%i` with `{{variableName}}`
-- [ ] Replace `%f` with `{{variableName}}`
-- [ ] Remove variadic arguments from `format()` calls
-- [ ] Ensure variables are available in EvaluationContext
-- [ ] Update any `%%` to single `%`
-- [ ] Remove precision specifiers (`%.2f`) - pre-format if needed
-- [ ] Consider using `stringify()` for simple concatenation
-- [ ] Test all format strings with edge cases
-
----
-
-## FAQ
-
-### Q: How do I format numbers with precision?
-
-**A:** Precision formatting is not currently supported in `format()`. Options:
-
-1. Pre-format values before adding to context:
-   ```vala
-   var formatted_price = "%.2f".printf(price);
-   props.set("price", new NativeElement<string?>(formatted_price));
-   ```
-   
-2. Use `stringify()` with pre-formatted values:
-   ```javascript
-   stringify("$", formatted_price)
-   ```
-
-### Q: How do I output a literal `{{` in my template?
-
-**A:** Use the escape sequence `\{{`:
-```javascript
-format("Use \\{{variable}} for interpolation")
-// Output: "Use {{variable}} for interpolation"
-```
-
-### Q: What happens if a variable is missing from the context?
-
-**A:** A `NON_EXISTANT_PROPERTY` error is thrown. Ensure all variables referenced in templates exist in the EvaluationContext before evaluation.
-
-### Q: Can I use nested expressions like `{{a {{b}} c}}`?
-
-**A:** No, nested expressions are not supported. The first `}}` will close the expression block. Consider restructuring your template or pre-computing values.
-
-### Q: How do I convert from hexadecimal formatting?
-
-**A:** There is no direct equivalent. Pre-format the hexadecimal string before adding to context:
-```vala
-var hex_value = "0x%x".printf(value);
-props.set("hex", new NativeElement<string?>(hex_value));
-```
-
-### Q: Can I still use `format()` with no placeholders?
-
-**A:** Yes, templates without `{{}}` are returned as-is:
-```javascript
-format("Just a plain string")  // → "Just a plain string"
-```
-
-### Q: What is the difference between `to_string()` and `stringify()`?
-
-**A:** 
-- `Element.to_string()` returns a debug representation like `Element[string]`
-- `Element.stringify()` returns the actual value as a string (e.g., `"hello"` or `"42"`)
-- `stringify()` global function concatenates multiple stringified values
-
-### Q: How do null values behave?
-
-**A:** Null values produce empty strings:
-```javascript
-format("Value: '{{value}}'")  // With null value → "Value: ''"
-stringify(null)                // → ""
-```
-
----
-
-## Complete Migration Example
-
-### Before (v1)
-
-```vala
-// Setting up context
-var props = new PropertyDictionary();
-props.set("category", new NativeElement<string?>("Product"));
-props.set("id", new NativeElement<int?>(123));
-props.set("title", new NativeElement<string?>("Widget"));
-props.set("price", new NativeElement<double?>(19.99));
-props.set("discount", new NativeElement<double?>(0.15));
-var context = new EvaluationContext(props);
-
-// Format call with multiple arguments
-var expr = ExpressionParser.parse(
-    "format(\"%s #%d: %s - $%.2f (%.0f%% off)\", category, id, title, price, discount * 100)"
-);
-var result = expr.evaluate(context);
-// Output: "Product #123: Widget - $19.99 (15% off)"
-```
-
-### After (v2)
-
-```vala
-// Setting up context - same as before
-var props = new PropertyDictionary();
-props.set("category", new NativeElement<string?>("Product"));
-props.set("id", new NativeElement<int?>(123));
-props.set("title", new NativeElement<string?>("Widget"));
-props.set("price", new NativeElement<double?>(19.99));
-props.set("discount", new NativeElement<double?>(0.15));
-var context = new EvaluationContext(props);
-
-// Format call - template only, expressions inline
-var expr = ExpressionParser.parse(
-    "format(\"{{category}} #{{id}}: {{title}} - ${{price}} ({{discount * 100}}% off)\")"
-);
-var result = expr.evaluate(context);
-// Output: "Product #123: Widget - $19.99 (15% off)"
-```

+ 4 - 4
meson.build

@@ -1,5 +1,5 @@
 project('spry', ['c', 'vala'],
-  version: '0.1',
+  version: '0.2',
 )
 
 vapi_dir = join_paths(meson.current_source_dir(), 'vapi')
@@ -17,6 +17,9 @@ invercargill_sql_dep = dependency('invercargill-sql', required: true)
 invercargill_sql_inversion_dep = dependency('invercargill-sql-inversion', required: true)
 sqlite_dep = dependency('sqlite3')
 libxml_dep = dependency('libxml-2.0')
+statum_dep = dependency('statum-0.1')
+
+# libsodium is consumed via a bundled VAPI (libsodium does not ship one).
 sodium_vapi = files('vapi/libsodium.vapi')
 sodium_c_lib = meson.get_compiler('c').find_library('sodium', required: true)
 sodium_deps = declare_dependency(sources: sodium_vapi, dependencies: sodium_c_lib)
@@ -25,7 +28,4 @@ sodium_deps = declare_dependency(sources: sodium_vapi, dependencies: sodium_c_li
 add_project_arguments(['--vapidir', vapi_dir], language: 'vala')
 
 subdir('src')
-subdir('examples')
 subdir('tools')
-# subdir('website')
-subdir('demo')

+ 0 - 1324
plans/auth-refactor-architecture.md

@@ -1,1324 +0,0 @@
-# Spry Authentication & Authorisation Refactor Architecture
-
-## 1. Overview
-
-This document describes the architecture for refactoring Spry's `src/Users` system into two separate concerns:
-
-- **`src/Authentication`** (renamed from `src/Users`): ONE method of authentication provided by Spry
-- **`src/Authorisation`**: Token generation, validation, and permission checking
-
-### Key Design Principles
-
-1. **Separation of Concerns**: Authentication (who you are) is separate from Authorisation (what you can do)
-2. **Identity Abstraction**: Authorisation works with a generic `Identity` interface, not a concrete User model
-3. **Stateless Tokens**: Tokens are self-contained and validated cryptographically
-4. **Multiple Token Delivery**: Same token via cookie or Bearer header
-5. **Extensibility**: Applications can implement custom authentication while using Spry's Authorisation
-
----
-
-## 2. High-Level Architecture
-
-```mermaid
-flowchart TB
-    subgraph Request Flow
-        Request[HTTP Request] --> TokenExtractor
-        TokenExtractor --> TokenValidator
-        TokenValidator --> AuthorisationContext
-    end
-    
-    subgraph Authorisation System
-        TokenExtractor[TokenExtractor]
-        TokenValidator[TokenValidator]
-        AuthorisationContext[AuthorisationContext]
-        AuthorisationService[AuthorisationService]
-    end
-    
-    subgraph Authentication System
-        IdentityProvider[IdentityProvider Interface]
-        UserIdentityProvider[UserIdentityProvider]
-        UserService[UserService]
-        SessionService[SessionService]
-        LoginFormComponent[LoginFormComponent]
-    end
-    
-    subgraph Storage
-        Implexus[(Implexus Storage)]
-    end
-    
-    TokenExtractor --> |Cookie or Bearer| TokenValidator
-    TokenValidator --> |Valid Token| AuthorisationContext
-    AuthorisationContext --> |get_current_identity| IdentityProvider
-    IdentityProvider --> |implemented by| UserIdentityProvider
-    UserIdentityProvider --> UserService
-    UserIdentityProvider --> SessionService
-    UserService --> Implexus
-    SessionService --> Implexus
-    LoginFormComponent --> UserService
-    LoginFormComponent --> SessionService
-    LoginFormComponent --> AuthorisationService
-```
-
----
-
-## 3. File Structure
-
-### 3.1 New `src/Authorisation` Structure
-
-```
-src/Authorisation/
-├── ARCHITECTURE.md              # This document
-├── meson.build                  # Build configuration
-├── Identity.vala                # Identity interface
-├── AuthorisationContext.vala    # Request-scoped authorisation state
-├── AuthorisationService.vala    # Token generation and validation
-├── TokenPayload.vala            # Token data structure
-├── AuthorisationError.vala      # Error domain
-└── AuthorisationModule.vala     # IoC module registration
-```
-
-### 3.2 Refactored `src/Authentication` Structure (renamed from `src/Users`)
-
-```
-src/Authentication/
-├── ARCHITECTURE.md              # Architecture documentation
-├── meson.build                  # Build configuration
-├── User.vala                    # User data model
-├── Session.vala                 # Session data model
-├── UserService.vala             # User CRUD and authentication
-├── SessionService.vala          # Session management
-├── PermissionService.vala       # Permission management on users
-├── UsersMigration.vala          # Database migrations
-├── UserIdentityProvider.vala    # IdentityProvider implementation for User
-├── AuthenticationModule.vala    # IoC module registration
-└── Components/
-    ├── LoginFormComponent.vala
-    ├── UserFormComponent.vala
-    ├── UserListComponent.vala
-    ├── UserListItemComponent.vala
-    ├── PermissionEditorComponent.vala
-    └── UserManagementPage.vala
-```
-
----
-
-## 4. Core Interfaces and Classes
-
-### 4.1 Identity Interface
-
-The `Identity` interface is the contract between Authentication and Authorisation. Any authentication provider must implement this interface.
-
-```vala
-namespace Spry.Authorisation {
-
-    /**
-     * Interface representing an authenticated identity.
-     * 
-     * Implementations provide identity data that gets embedded in tokens
-     * and can be retrieved on subsequent requests.
-     * 
-     * Built-in implementation: Spry.Authentication.UserIdentityProvider
-     * Custom implementations: OAuth providers, certificate auth, etc.
-     */
-    public interface Identity : GLib.Object {
-
-        /**
-         * Unique identifier for this identity.
-         * Used to look up the full identity object.
-         */
-        public abstract string id { get; }
-
-        /**
-         * Human-readable name for this identity.
-         * Typically username or email.
-         */
-        public abstract string username { get; }
-
-        /**
-         * Permissions granted to this identity.
-         * Returns ImmutableLot for thread-safety.
-         */
-        public abstract ImmutableLot<string> permissions { get; }
-
-        /**
-         * Additional data to embed in the token.
-         * Implementation-specific data (e.g., roles, preferences).
-         */
-        public abstract Properties token_data { get; }
-    }
-}
-```
-
-### 4.2 IdentityProvider Interface
-
-The `IdentityProvider` interface allows the Authorisation system to retrieve full identity objects.
-
-```vala
-namespace Spry.Authorisation {
-
-    /**
-     * Interface for retrieving Identity objects by ID.
-     * 
-     * The AuthorisationContext uses this to get_current_identity().
-     * Applications register their implementation during startup.
-     */
-    public interface IdentityProvider : GLib.Object {
-
-        /**
-         * Retrieves an Identity by its unique ID.
-         * 
-         * @param id The identity ID from the token
-         * @return The Identity, or null if not found/inactive
-         */
-        public abstract async Identity? get_identity_async(string id) throws Error;
-    }
-}
-```
-
-### 4.3 TokenPayload Model
-
-The `TokenPayload` contains all data embedded in the encrypted token.
-
-```vala
-namespace Spry.Authorisation {
-
-    /**
-     * Data structure embedded in authorisation tokens.
-     * 
-     * Token contents (JSON, encrypted and signed):
-     * - id: Identity unique identifier
-     * - username: Human-readable name
-     * - permissions: Array of permission strings
-     * - data: Additional properties
-     * - issued_at: Token issuance timestamp
-     * - expires_at: Token expiry timestamp
-     */
-    public class TokenPayload : GLib.Object {
-
-        // Identity fields
-        public string id { get; set; }
-        public string username { get; set; }
-        public ImmutableLot<string> permissions { get; set; }
-        public Properties data { get; set; }
-
-        // Token metadata
-        public DateTime issued_at { get; set; }
-        public DateTime expires_at { get; set; }
-
-        /**
-         * Creates a TokenPayload from an Identity.
-         */
-        public TokenPayload.from_identity(Identity identity, TimeSpan duration) {
-            GLib.Object(
-                id: identity.id,
-                username: identity.username,
-                permissions: identity.permissions,
-                data: identity.data,
-                issued_at: new DateTime.now_utc(),
-                expires_at: new DateTime.now_utc().add(duration)
-            );
-        }
-
-        /**
-         * Checks if the token has expired.
-         */
-        public bool is_expired() {
-            return expires_at.compare(new DateTime.now_utc()) <= 0;
-        }
-
-        /**
-         * Serializes to JSON for token encryption.
-         */
-        public Json.Object to_json() {
-            var obj = new Json.Object();
-            obj.set_string_member("id", id ?? "");
-            obj.set_string_member("username", username ?? "");
-            
-            // Permissions array
-            var perms_array = new Json.Array();
-            foreach (var perm in permissions) {
-                perms_array.add_string_element(perm);
-            }
-            obj.set_array_member("permissions", perms_array);
-            
-            // Data object
-            var data_obj = new Json.Object();
-            if (data != null) {
-                var iter = data.iterator();
-                while (iter.next()) {
-                    var pair = iter.get();
-                    // Serialize based on type
-                    data_obj.set_string_member(pair.key, pair.value.to_string());
-                }
-            }
-            obj.set_object_member("data", data_obj);
-            
-            // Metadata
-            obj.set_string_member("issued_at", issued_at.format_iso8601());
-            obj.set_string_member("expires_at", expires_at.format_iso8601());
-            
-            return obj;
-        }
-
-        /**
-         * Deserializes from JSON after token decryption.
-         */
-        public static TokenPayload from_json(Json.Object obj) {
-            var payload = new TokenPayload();
-            payload.id = obj.get_string_member("id") ?? "";
-            payload.username = obj.get_string_member("username") ?? "";
-            
-            // Permissions
-            var perms = new LotBuilder<string>();
-            if (obj.has_member("permissions")) {
-                var arr = obj.get_array_member("permissions");
-                foreach (var element in arr.get_elements()) {
-                    perms.add(element.get_string() ?? "");
-                }
-            }
-            payload.permissions = perms.to_immutable();
-            
-            // Data
-            payload.data = new PropertyDictionary();
-            if (obj.has_member("data")) {
-                var data_obj = obj.get_object_member("data");
-                foreach (var member in data_obj.get_members()) {
-                    payload.data.set(member, new NativeElement<string>(
-                        data_obj.get_string_member(member) ?? ""
-                    ));
-                }
-            }
-            
-            // Metadata
-            if (obj.has_member("issued_at")) {
-                payload.issued_at = new DateTime.from_iso8601(
-                    obj.get_string_member("issued_at"), 
-                    new TimeZone.utc()
-                );
-            }
-            if (obj.has_member("expires_at")) {
-                payload.expires_at = new DateTime.from_iso8601(
-                    obj.get_string_member("expires_at"), 
-                    new TimeZone.utc()
-                );
-            }
-            
-            return payload;
-        }
-    }
-}
-```
-
-### 4.4 AuthorisationContext
-
-The `AuthorisationContext` is the primary interface for applications to check authorisation.
-
-```vala
-namespace Spry.Authorisation {
-
-    /**
-     * Request-scoped authorisation context.
-     * 
-     * Provides access to the current identity's authorisation state.
-     * Automatically populated from cookie or Bearer token on each request.
-     * 
-     * Usage:
-     *   var auth = inject<AuthorisationContext>();
-     *   if (!auth.is_authorised) {
-     *       // Redirect to login
-     *   }
-     *   if (auth.has_permission("admin")) {
-     *       // Show admin content
-     *   }
-     */
-    public class AuthorisationContext : GLib.Object {
-
-        private TokenPayload? _payload = null;
-        private IdentityProvider? _identity_provider = null;
-        private Identity? _cached_identity = null;
-
-        /**
-         * Whether the request has a valid authorisation token.
-         */
-        public bool is_authorised { get { return _payload != null; } }
-
-        /**
-         * The identity ID from the token.
-         * Returns null if not authorised.
-         */
-        public string? user_id { 
-            get { return _payload?.id; } 
-        }
-
-        /**
-         * The username from the token.
-         * Returns null if not authorised.
-         */
-        public string? username { 
-            get { return _payload?.username; } 
-        }
-
-        /**
-         * The permissions from the token.
-         * Returns empty lot if not authorised.
-         */
-        public ImmutableLot<string> permissions { 
-            get { return _payload?.permissions ?? new ImmutableLot<string>(); } 
-        }
-
-        /**
-         * Additional data from the token.
-         * Returns empty properties if not authorised.
-         */
-        public Properties data { 
-            get { return _payload?.data ?? new PropertyDictionary(); } 
-        }
-
-        /**
-         * The token payload (for advanced use).
-         */
-        public TokenPayload? payload { get { return _payload; } }
-
-        /**
-         * Sets the token payload (called by AuthorisationService).
-         */
-        internal void set_payload(TokenPayload? payload) {
-            _payload = payload;
-            _cached_identity = null;
-        }
-
-        /**
-         * Sets the identity provider (called by IoC during initialization).
-         */
-        internal void set_identity_provider(IdentityProvider? provider) {
-            _identity_provider = provider;
-        }
-
-        /**
-         * Checks if the current identity has a specific permission.
-         * 
-         * Supports wildcard matching:
-         * - "admin" matches everything
-         * - "user-*" matches "user-create", "user-delete", etc.
-         * - "*" matches everything
-         * 
-         * @param permission The permission to check
-         * @return true if the identity has the permission
-         */
-        public bool has_permission(string permission) {
-            if (_payload == null) return false;
-
-            foreach (var user_perm in _payload.permissions) {
-                if (permission_matches(user_perm, permission)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Requires a specific permission, throws if not present.
-         * 
-         * @param permission The required permission
-         * @throws AuthorisationError.PERMISSION_DENIED if not authorised
-         */
-        public void require_permission(string permission) throws Error {
-            if (!is_authorised) {
-                throw new AuthorisationError.NOT_AUTHORISED(
-                    "Authentication required"
-                );
-            }
-            if (!has_permission(permission)) {
-                throw new AuthorisationError.PERMISSION_DENIED(
-                    @"Permission '$permission' required"
-                );
-            }
-        }
-
-        /**
-         * Checks if the identity has ANY of the specified permissions.
-         */
-        public bool has_any_permission(Lot<string> permissions) {
-            foreach (var perm in permissions) {
-                if (has_permission(perm)) return true;
-            }
-            return false;
-        }
-
-        /**
-         * Checks if the identity has ALL of the specified permissions.
-         */
-        public bool has_all_permissions(Lot<string> permissions) {
-            foreach (var perm in permissions) {
-                if (!has_permission(perm)) return false;
-            }
-            return true;
-        }
-
-        /**
-         * Retrieves the full Identity object from the provider.
-         * 
-         * This calls the registered IdentityProvider to get the complete
-         * identity object (e.g., User from Spry.Authentication).
-         * 
-         * @return The Identity, or null if not found
-         */
-        public async Identity? get_current_identity_async() throws Error {
-            if (_payload == null) return null;
-            if (_cached_identity != null) return _cached_identity;
-            if (_identity_provider == null) return null;
-
-            _cached_identity = yield _identity_provider.get_identity_async(_payload.id);
-            return _cached_identity;
-        }
-
-        /**
-         * Synchronous version for cases where async is not available.
-         */
-        public Identity? get_current_identity() {
-            if (_payload == null) return null;
-            if (_cached_identity != null) return _cached_identity;
-            // Cannot call async - return null
-            return null;
-        }
-
-        // Private helper for permission matching
-        private bool permission_matches(string pattern, string permission) {
-            if (pattern == "admin" || pattern == "*") return true;
-            if (pattern == permission) return true;
-            if (pattern.has_suffix("*")) {
-                string prefix = pattern.substring(0, pattern.length - 1);
-                return permission.has_prefix(prefix);
-            }
-            return false;
-        }
-    }
-}
-```
-
-### 4.5 AuthorisationService
-
-The `AuthorisationService` handles token generation, extraction, and validation.
-
-```vala
-namespace Spry.Authorisation {
-
-    /**
-     * Service for generating and validating authorisation tokens.
-     * 
-     * Token Sources (in order of precedence):
-     * 1. Authorization: Bearer <token> header
-     * 2. Cookie named in cookie_name property
-     * 
-     * Token Format:
-     * - JSON payload containing identity data and metadata
-     * - Signed with Ed25519 (server signing key)
-     * - Encrypted with X25519 (server sealing key)
-     * - Base64url encoded
-     */
-    public class AuthorisationService : GLib.Object {
-
-        private CryptographyProvider _crypto = inject<CryptographyProvider>();
-        private AuthorisationContext _context = inject<AuthorisationContext>();
-        private IdentityProvider? _identity_provider = inject<IdentityProvider>();
-        private HttpContext _http_context = inject<HttpContext>();
-
-        // Configuration
-        private string _cookie_name = "spry_session";
-        private bool _cookie_secure = true;
-        private TimeSpan _token_duration = TimeSpan.HOUR * 24;
-
-        /**
-         * Cookie name for session tokens.
-         */
-        public string cookie_name { 
-            get { return _cookie_name; } 
-            set { _cookie_name = value; }
-        }
-
-        /**
-         * Whether cookies should be Secure (HTTPS only).
-         */
-        public bool cookie_secure { 
-            get { return _cookie_secure; } 
-            set { _cookie_secure = value; }
-        }
-
-        /**
-         * Default token validity duration.
-         */
-        public TimeSpan token_duration { 
-            get { return _token_duration; } 
-            set { _token_duration = value; }
-        }
-
-        /**
-         * Creates a new AuthorisationService.
-         */
-        public AuthorisationService() {
-            // Set up identity provider in context if available
-            if (_identity_provider != null) {
-                _context.set_identity_provider(_identity_provider);
-            }
-        }
-
-        // =========================================================================
-        // Token Generation
-        // =========================================================================
-
-        /**
-         * Generates an authorisation token for an identity.
-         * 
-         * @param identity The identity to create a token for
-         * @param duration Optional custom duration (defaults to token_duration)
-         * @return The encrypted token string
-         */
-        public string generate_token(Identity identity, TimeSpan? duration = null) {
-            var actual_duration = duration ?? _token_duration;
-            var payload = new TokenPayload.from_identity(identity, actual_duration);
-            return generate_token_from_payload(payload);
-        }
-
-        /**
-         * Generates a token from an existing payload.
-         */
-        public string generate_token_from_payload(TokenPayload payload) {
-            var json_obj = payload.to_json();
-            var node = new Json.Node(Json.NodeType.OBJECT);
-            node.set_object(json_obj);
-            var json_str = Json.to_string(node, false);
-
-            // Sign and seal using CryptographyProvider
-            return _crypto.sign_then_seal_token(json_str, payload.expires_at);
-        }
-
-        // =========================================================================
-        // Token Validation
-        // =========================================================================
-
-        /**
-         * Validates a token string and returns the payload.
-         * 
-         * @param token The encrypted token string
-         * @return The TokenPayload, or null if invalid
-         */
-        public TokenPayload? validate_token(string token) {
-            try {
-                var result = _crypto.unseal_then_verify_token(token);
-                
-                if (!result.is_valid || result.is_expired) {
-                    return null;
-                }
-
-                var json_str = result.payload;
-                if (json_str == null) return null;
-
-                var parser = new Json.Parser();
-                parser.load_from_data((!)json_str);
-                var root = parser.get_root();
-                
-                if (root.get_node_type() != Json.NodeType.OBJECT) {
-                    return null;
-                }
-
-                var payload = TokenPayload.from_json(root.get_object());
-                
-                // Double-check expiry
-                if (payload.is_expired()) {
-                    return null;
-                }
-
-                return payload;
-            } catch (Error e) {
-                return null;
-            }
-        }
-
-        // =========================================================================
-        // Request Processing
-        // =========================================================================
-
-        /**
-         * Extracts and validates token from the current HTTP request.
-         * 
-         * Checks Authorization header first, then cookie.
-         * Populates the AuthorisationContext if valid token found.
-         */
-        public async void process_request_async() throws Error {
-            string? token = null;
-
-            // 1. Check Authorization: Bearer header
-            var auth_header = _http_context.request.headers.get_any_or_default(
-                "Authorization", 
-                null
-            );
-            if (auth_header != null && auth_header.has_prefix("Bearer ")) {
-                token = ((!)auth_header).substring(7).strip();
-            }
-
-            // 2. Check cookie
-            if (token == null) {
-                token = _http_context.request.get_cookie(_cookie_name);
-            }
-
-            // 3. Validate and populate context
-            if (token != null) {
-                var payload = validate_token((!)token);
-                if (payload != null) {
-                    _context.set_payload(payload);
-                }
-            }
-        }
-
-        // =========================================================================
-        // Cookie Management
-        // =========================================================================
-
-        /**
-         * Sets the authorisation cookie on an HTTP response.
-         * 
-         * @param result The HttpResult to set the cookie on
-         * @param token The token to set
-         */
-        public void set_cookie(HttpResult result, string token) {
-            var max_age = (int)(_token_duration / TimeSpan.SECOND);
-            var cookie_value = @"$_cookie_name=$token; Path=/; Max-Age=$max_age; HttpOnly";
-            
-            if (_cookie_secure) {
-                cookie_value += "; Secure";
-            }
-            
-            cookie_value += "; SameSite=Strict";
-            
-            result.set_header("Set-Cookie", cookie_value);
-        }
-
-        /**
-         * Clears the authorisation cookie.
-         */
-        public void clear_cookie(HttpResult result) {
-            var cookie_value = @"$_cookie_name=; Path=/; Max-Age=0; HttpOnly";
-            
-            if (_cookie_secure) {
-                cookie_value += "; Secure";
-            }
-            
-            cookie_value += "; SameSite=Strict";
-            
-            result.set_header("Set-Cookie", cookie_value);
-        }
-    }
-}
-```
-
-### 4.6 AuthorisationError
-
-```vala
-namespace Spry.Authorisation {
-
-    /**
-     * Error domain for authorisation-related errors.
-     */
-    public errordomain AuthorisationError {
-        NOT_AUTHORISED,
-        PERMISSION_DENIED,
-        INVALID_TOKEN,
-        TOKEN_EXPIRED,
-        IDENTITY_NOT_FOUND
-    }
-}
-```
-
----
-
-## 5. Authentication System Refactoring
-
-### 5.1 UserIdentityProvider
-
-The `UserIdentityProvider` implements `IdentityProvider` for the User model.
-
-```vala
-namespace Spry.Authentication {
-
-    /**
-     * IdentityProvider implementation for Spry's built-in User model.
-     * 
-     * This bridges the Authentication User model with the Authorisation
-     * Identity interface.
-     */
-    public class UserIdentityProvider : GLib.Object, Authorisation.IdentityProvider {
-
-        private UserService _user_service = inject<UserService>();
-
-        /**
-         * Retrieves a User as an Identity by ID.
-         */
-        public async Authorisation.Identity? get_identity_async(string id) throws Error {
-            var user = yield _user_service.get_user_async(id);
-            if (user == null) return null;
-            
-            // User implements Identity, so we can return directly
-            return user as Authorisation.Identity;
-        }
-    }
-}
-```
-
-### 5.2 User Model (Updated)
-
-The `User` model now implements the `Identity` interface.
-
-```vala
-namespace Spry.Authentication {
-
-    /**
-     * User data model implementing the Identity interface.
-     */
-    public class User : GLib.Object, Authorisation.Identity {
-
-        // Identity fields (from interface)
-        public string id { get; set; }
-        public string username { get; set; }
-        
-        // User-specific fields
-        public string email { get; set; }
-        public string password_hash { get; set; }
-        public DateTime created_at { get; set; }
-        public DateTime? updated_at { get; set; }
-
-        // Permissions stored on user
-        private Vector<string> _permissions = new Vector<string>();
-        
-        // Application data
-        private Dictionary<string, string> _app_data = new Dictionary<string, string>();
-
-        // =========================================================================
-        // Identity Interface Implementation
-        // =========================================================================
-
-        /**
-         * Unique identifier (Identity interface).
-         */
-        public string identity_id { get { return id; } }
-
-        /**
-         * Human-readable name (Identity interface).
-         */
-        public string identity_username { get { return username; } }
-
-        /**
-         * Permissions as ImmutableLot (Identity interface).
-         */
-        public ImmutableLot<string> identity_permissions {
-            get {
-                var builder = new LotBuilder<string>();
-                foreach (var perm in _permissions) {
-                    builder.add(perm);
-                }
-                return builder.to_immutable();
-            }
-        }
-
-        /**
-         * Additional token data (Identity interface).
-         */
-        public Properties identity_data {
-            get {
-                var props = new PropertyDictionary();
-                props.set("email", new NativeElement<string>(email ?? ""));
-                var iter = _app_data.iterator();
-                while (iter.next()) {
-                    props.set(iter.get().key, new NativeElement<string>(iter.get().value));
-                }
-                return props;
-            }
-        }
-
-        // =========================================================================
-        // User-Specific Properties
-        // =========================================================================
-
-        /**
-         * Mutable permissions collection for management.
-         */
-        public Vector<string> permissions {
-            get { return _permissions; }
-            set { 
-                _permissions.clear();
-                foreach (var perm in value) {
-                    _permissions.add(perm);
-                }
-            }
-        }
-
-        /**
-         * Mutable application data for management.
-         */
-        public Dictionary<string, string> app_data {
-            get { return _app_data; }
-            set {
-                _app_data.clear();
-                var iter = value.iterator();
-                while (iter.next()) {
-                    _app_data.set(iter.get().key, iter.get().value);
-                }
-            }
-        }
-
-        // ... existing methods (from_json, to_json) ...
-    }
-}
-```
-
-### 5.3 Updated LoginFormComponent
-
-The login form now uses the AuthorisationService for token generation.
-
-```vala
-namespace Spry.Authentication.Components {
-
-    public class LoginFormComponent : Component {
-
-        private UserService _user_service = inject<UserService>();
-        private AuthorisationService _auth_service = inject<AuthorisationService>();
-        private HttpContext _http_context = inject<HttpContext>();
-
-        public string redirect_url { get; set; default = "/"; }
-        public string? error_message { get; private set; default = null; }
-
-        private async void handle_login_async() throws Error {
-            var query = _http_context.request.query_params;
-            var username = query.get_any_or_default("username", "").strip();
-            var password = query.get_any_or_default("password", "");
-
-            // Authenticate user
-            var user = yield _user_service.authenticate_async(username, password);
-            if (user == null) {
-                error_message = "Invalid username or password";
-                return;
-            }
-
-            // Generate authorisation token
-            var token = _auth_service.generate_token(user);
-
-            // Set cookie and redirect
-            response.set_cookie(
-                _auth_service.cookie_name,
-                token,
-                (int)(_auth_service.token_duration / TimeSpan.SECOND),
-                "/",
-                _auth_service.cookie_secure,
-                true,  // HttpOnly
-                "Strict"  // SameSite
-            );
-            response.redirect(redirect_url);
-        }
-    }
-}
-```
-
----
-
-## 6. IoC Module Registration
-
-### 6.1 AuthorisationModule
-
-```vala
-namespace Spry.Authorisation {
-
-    /**
-     * IoC module for the Authorisation system.
-     * 
-     * Registration order:
-     * 1. AuthorisationContext (scoped - per request)
-     * 2. AuthorisationService (scoped - per request)
-     * 3. IdentityProvider (optional - provided by Authentication or custom)
-     */
-    public class AuthorisationModule : GLib.Object, Inversion.Module {
-
-        public void register(Inversion.Application application) {
-            // Context is scoped (per-request)
-            application.add_scoped<AuthorisationContext>();
-
-            // Service is scoped (per-request, needs HttpContext)
-            application.add_scoped<AuthorisationService>();
-        }
-
-        public void initialize(Inversion.Application application) {
-            // Wire up request processing
-            // This would integrate with Spry's request pipeline
-        }
-    }
-}
-```
-
-### 6.2 AuthenticationModule
-
-```vala
-namespace Spry.Authentication {
-
-    /**
-     * IoC module for the Authentication system.
-     * 
-     * Depends on: AuthorisationModule (must be registered first)
-     */
-    public class AuthenticationModule : GLib.Object, Inversion.Module {
-
-        public void register(Inversion.Application application) {
-            // Register as IdentityProvider for Authorisation
-            application.add_scoped<UserIdentityProvider>();
-            application.add_alias<Authorisation.IdentityProvider, UserIdentityProvider>();
-
-            // User management services
-            application.add_scoped<UserService>();
-            application.add_scoped<SessionService>();
-            application.add_scoped<PermissionService>();
-
-            // Register UI components
-            var spry_cfg = application.configure_with<SpryConfigurator>();
-            spry_cfg.add_component<Components.LoginFormComponent>();
-            spry_cfg.add_component<Components.UserListComponent>();
-            spry_cfg.add_component<Components.UserListItemComponent>();
-            spry_cfg.add_component<Components.UserFormComponent>();
-            spry_cfg.add_component<Components.PermissionEditorComponent>();
-            spry_cfg.add_page<Components.UserManagementPage>(
-                new EndpointRoute("/admin/users")
-            );
-        }
-
-        public void initialize(Inversion.Application application) {
-            // Initialize storage structure
-            try {
-                var engine = application.resolve<Implexus.Core.Engine>();
-                initialize_storage_async.begin(engine);
-            } catch (Error e) {
-                error("Failed to initialize Authentication storage: %s", e.message);
-            }
-        }
-
-        private async void initialize_storage_async(Implexus.Core.Engine engine) throws Error {
-            // Create /spry/users container hierarchy
-            // ... (same as current UsersModule)
-        }
-    }
-}
-```
-
-### 6.3 Application Startup
-
-```vala
-// In application startup
-var application = new Inversion.Application();
-
-// 1. Register core Spry modules
-application.add_module<SpryModule>();
-
-// 2. Register Authorisation (must be before Authentication)
-application.add_module<AuthorisationModule>();
-
-// 3. Register built-in Authentication (optional)
-application.add_module<AuthenticationModule>();
-
-// OR: Register custom authentication provider
-// application.add_module<MyCustomAuthModule>();
-```
-
----
-
-## 7. Custom Authentication Provider Integration
-
-### 7.1 Implementing a Custom Provider
-
-To implement custom authentication (e.g., OAuth, certificates):
-
-```vala
-namespace MyApp.Auth {
-
-    /**
-     * Custom identity for OAuth authentication.
-     */
-    public class OAuthIdentity : GLib.Object, Authorisation.Identity {
-        
-        public string id { get; set; }
-        public string username { get; set; }
-        public ImmutableLot<string> permissions { get; set; }
-        public Properties data { get; set; }
-        
-        // OAuth-specific fields
-        public string provider { get; set; }  // e.g., "google", "github"
-        public string? avatar_url { get; set; }
-    }
-
-    /**
-     * Custom identity provider for OAuth.
-     */
-    public class OAuthIdentityProvider : GLib.Object, Authorisation.IdentityProvider {
-        
-        private OAuthService _oauth_service = inject<OAuthService>();
-        
-        public async Authorisation.Identity? get_identity_async(string id) throws Error {
-            return yield _oauth_service.get_identity_async(id);
-        }
-    }
-
-    /**
-     * Custom authentication module.
-     */
-    public class OAuthModule : GLib.Object, Inversion.Module {
-        
-        public void register(Inversion.Application application) {
-            // Register as IdentityProvider
-            application.add_scoped<OAuthIdentityProvider>();
-            application.add_alias<Authorisation.IdentityProvider, OAuthIdentityProvider>();
-            
-            // OAuth-specific services
-            application.add_singleton<OAuthService>();
-            application.add_scoped<OAuthCallbackHandler>();
-        }
-    }
-}
-```
-
-### 7.2 OAuth Login Flow Example
-
-```vala
-public class OAuthCallbackComponent : Component {
-    
-    private OAuthService _oauth = inject<OAuthService>();
-    private AuthorisationService _auth = inject<AuthorisationService>();
-    
-    public override async void prepare() throws Error {
-        var code = _http_context.request.query_params.get_any_or_default("code", "");
-        
-        // Exchange code for OAuth identity
-        var identity = yield _oauth.exchange_code_async(code);
-        if (identity == null) {
-            response.redirect("/login?error=oauth_failed");
-            return;
-        }
-        
-        // Generate Spry authorisation token
-        var token = _auth.generate_token(identity);
-        
-        // Set cookie
-        response.set_cookie(_auth.cookie_name, token, ...);
-        response.redirect("/dashboard");
-    }
-}
-```
-
----
-
-## 8. Request Processing Flow
-
-### 8.1 Sequence Diagram
-
-```mermaid
-sequenceDiagram
-    participant Client
-    participant Spry as Spry Framework
-    participant AuthZ as AuthorisationService
-    participant Context as AuthorisationContext
-    participant Provider as IdentityProvider
-    participant AuthN as UserService
-    
-    Client->>Spry: HTTP Request with Cookie/Bearer
-    Spry->>AuthZ: process_request_async
-    AuthZ->>AuthZ: Extract token from header/cookie
-    AuthZ->>AuthZ: Validate token signature/encryption
-    AuthZ->>Context: set_payload - TokenPayload
-    Spry->>Context: has_permission or require_permission
-    Context->>Context: Check permissions in payload
-    
-    alt Full identity needed
-        Spry->>Context: get_current_identity_async
-        Context->>Provider: get_identity_async
-        Provider->>AuthN: get_user_async
-        AuthN-->>Provider: User
-        Provider-->>Context: Identity
-        Context-->>Spry: Identity
-    end
-    
-    Spry-->>Client: Response
-```
-
-### 8.2 Component Diagram
-
-```mermaid
-graph TB
-    subgraph Authorisation System
-        AuthorisationModule[AuthorisationModule]
-        AuthorisationService[AuthorisationService]
-        AuthorisationContext[AuthorisationContext]
-        TokenPayload[TokenPayload]
-        Identity[Identity Interface]
-        IdentityProvider[IdentityProvider Interface]
-    end
-    
-    subgraph Authentication System
-        AuthenticationModule[AuthenticationModule]
-        UserService[UserService]
-        SessionService[SessionService]
-        PermissionService[PermissionService]
-        User[User Model]
-        UserIdentityProvider[UserIdentityProvider]
-        LoginFormComponent[LoginFormComponent]
-    end
-    
-    subgraph Custom Auth Example
-        OAuthModule[OAuthModule]
-        OAuthIdentityProvider[OAuthIdentityProvider]
-        OAuthIdentity[OAuthIdentity]
-    end
-    
-    AuthorisationModule --> AuthorisationService
-    AuthorisationModule --> AuthorisationContext
-    
-    AuthorisationService --> AuthorisationContext
-    AuthorisationService --> IdentityProvider
-    
-    AuthorisationContext --> IdentityProvider
-    AuthorisationContext --> TokenPayload
-    
-    IdentityProvider -.implements.-> IdentityProvider
-    Identity -.implements.-> Identity
-    
-    AuthenticationModule --> UserService
-    AuthenticationModule --> UserIdentityProvider
-    AuthenticationModule --> LoginFormComponent
-    
-    User -.implements.-> Identity
-    UserIdentityProvider -.implements.-> IdentityProvider
-    UserIdentityProvider --> UserService
-    UserIdentityProvider --> User
-    
-    LoginFormComponent --> UserService
-    LoginFormComponent --> AuthorisationService
-    
-    OAuthModule --> OAuthIdentityProvider
-    OAuthIdentity -.implements.-> Identity
-    OAuthIdentityProvider -.implements.-> IdentityProvider
-    OAuthIdentityProvider --> OAuthIdentity
-```
-
----
-
-## 9. Migration Guide
-
-### 9.1 For Existing Applications
-
-1. **Update imports**: Change `Spry.Users` to `Spry.Authentication`
-2. **Update module registration**: Register `AuthorisationModule` before `AuthenticationModule`
-3. **Update permission checks**: Use `inject<AuthorisationContext>()` instead of `inject<PermissionService>()`
-
-### 9.2 Before/After Comparison
-
-**Before (current system):**
-```vala
-// Module registration
-application.add_module<Spry.Users.UsersModule>();
-
-// Permission check
-var perms = inject<PermissionService>();
-if (!perms.has_permission(user, "admin")) {
-    throw new UserError.PERMISSION_DENIED("Admin required");
-}
-
-// Getting current user
-var session = inject<SessionService>();
-var user = yield session.get_current_user_async();
-```
-
-**After (refactored system):**
-```vala
-// Module registration
-application.add_module<Spry.Authorisation.AuthorisationModule>();
-application.add_module<Spry.Authentication.AuthenticationModule>();
-
-// Permission check
-var auth = inject<AuthorisationContext>();
-auth.require_permission("admin");  // Throws if not authorised
-
-// Getting current user
-var auth = inject<AuthorisationContext>();
-var user = yield auth.get_current_identity_async() as User;
-```
-
----
-
-## 10. Implementation Checklist
-
-### Phase 1: Authorisation System
-- [ ] Create `src/Authorisation/` directory structure
-- [ ] Implement `Identity` interface
-- [ ] Implement `IdentityProvider` interface
-- [ ] Implement `TokenPayload` class
-- [ ] Implement `AuthorisationContext` class
-- [ ] Implement `AuthorisationService` class
-- [ ] Implement `AuthorisationError` domain
-- [ ] Implement `AuthorisationModule` class
-- [ ] Create `meson.build` configuration
-
-### Phase 2: Authentication Refactoring
-- [ ] Rename `src/Users/` to `src/Authentication/`
-- [ ] Update `User` to implement `Identity` interface
-- [ ] Create `UserIdentityProvider` class
-- [ ] Update `UserService` namespace
-- [ ] Update `SessionService` namespace
-- [ ] Update `PermissionService` namespace
-- [ ] Update all component namespaces
-- [ ] Create `AuthenticationModule` class
-- [ ] Update `LoginFormComponent` to use `AuthorisationService`
-- [ ] Update `meson.build` configuration
-
-### Phase 3: Integration
-- [ ] Update root `meson.build` to include both modules
-- [ ] Update demo application
-- [ ] Update documentation
-- [ ] Create migration guide for existing applications
-
----
-
-## 11. Open Questions
-
-1. **Token Refresh**: Should we support token refresh without re-authentication?
-2. **Multiple Sessions**: Should we track active sessions per identity?
-3. **Permission Caching**: Should permissions be cached beyond token lifetime?
-4. **Token Revocation**: Future support for revoking tokens before expiry?
-
----
-
-## 12. Appendix: Token Format Details
-
-### Token Structure (Internal)
-
-```
-Base64url(
-  X25519-Seal(
-    Ed25519-Sign(
-      JSON {
-        "id": "user-uuid",
-        "username": "johndoe",
-        "permissions": ["admin", "user-management"],
-        "data": {
-          "email": "john@example.com"
-        },
-        "issued_at": "2026-03-15T12:00:00Z",
-        "expires_at": "2026-03-16T12:00:00Z"
-      }
-    )
-  )
-)
-```
-
-### Cookie Format
-
-```
-Set-Cookie: spry_session=<token>; Path=/; Max-Age=86400; HttpOnly; Secure; SameSite=Strict
-```
-
-### Bearer Header Format
-
-```
-Authorization: Bearer <token>
-```

+ 0 - 658
plans/authentication-implexus-analysis.md

@@ -1,658 +0,0 @@
-# Authentication System Implexus Usage Analysis
-
-## Executive Summary
-
-This document provides a comprehensive analysis of the current authentication system's usage of the Implexus database and maps out the migration path to InvercargillSql. The authentication system uses Implexus as a document store with catalogue-based indexing for user and session management.
-
-## 1. Implexus Usage Map
-
-### 1.1 Files with Direct Implexus Dependencies
-
-| File | Implexus Usage | Complexity |
-|------|----------------|------------|
-| [`UserService.vala`](../src/Authentication/UserService.vala) | Heavy - all CRUD operations | High |
-| [`SessionService.vala`](../src/Authentication/SessionService.vala) | Heavy - all CRUD operations | High |
-| [`AuthenticationMigration.vala`](../src/Authentication/AuthenticationMigration.vala) | Medium - schema setup | Medium |
-| [`PermissionService.vala`](../src/Authentication/PermissionService.vala) | None - delegates to UserService | N/A |
-| [`User.vala`](../src/Authentication/User.vala) | None - data model only | N/A |
-| [`Session.vala`](../src/Authentication/Session.vala) | None - data model only | N/A |
-| [`UserIdentityProvider.vala`](../src/Authentication/UserIdentityProvider.vala) | None - adapter only | N/A |
-| `Components/*.vala` | None - use inject<> for services | N/A |
-
-### 1.2 Implexus Import Patterns
-
-```vala
-// Standard imports in files using Implexus
-using Implexus.Core;                    // Engine, EntityPath, Container, Document
-using Invercargill;                     // Element, Properties
-using Invercargill.DataStructures;      // Vector, Dictionary, Series
-```
-
-### 1.3 Storage Paths and Structure
-
-```mermaid
-graph TB
-    subgraph Implexus Storage Structure
-        Root["/spry"]
-        Auth["/spry/authentication"]
-        Users["/spry/authentication/users"]
-        Sessions["/spry/authentication/sessions"]
-        SessionsByUser["/spry/authentication/sessions_by_user"]
-    end
-    
-    Root --> Auth
-    Auth --> Users
-    Auth --> Sessions
-    Auth --> SessionsByUser
-    
-    subgraph User Document
-        UserDoc["Document: {user_id}"]
-        UserProps["Properties: username, email, password_hash, etc."]
-    end
-    
-    subgraph Session Document
-        SessionDoc["Document: {session_id}"]
-        SessionProps["Properties: user_id, created_at, expires_at, etc."]
-    end
-    
-    Users --> UserDoc
-    UserDoc --> UserProps
-    
-    Sessions --> SessionDoc
-    SessionDoc --> SessionProps
-```
-
-### 1.4 Catalogue Configuration
-
-| Catalogue | Path | Indexed Property | Purpose |
-|-----------|------|------------------|---------|
-| `by_username` | `/spry/authentication/users` | `username` | Unique username lookup |
-| `by_email` | `/spry/authentication/users` | `email` | Unique email lookup |
-
----
-
-## 2. Data Models and Schemas
-
-### 2.1 User Model
-
-**File:** [`src/Authentication/User.vala`](../src/Authentication/User.vala)
-
-```vala
-public class Spry.Authentication.User : Object, Authorisation.Identity {
-    public string id { get; set; }
-    public string username { get; set; }
-    public string email { get; set; }
-    public string password_hash { get; set; }
-    public Vector<string> permissions { get; set; }
-    public Dictionary<string, string> app_data { get; set; }
-    public bool is_active { get; set; }
-    public DateTime created_at { get; set; }
-    public DateTime? updated_at { get; set; }
-    public DateTime? last_login_at { get; set; }
-}
-```
-
-**Implexus Property Mapping:**
-
-| Property | Implexus Storage | Type |
-|----------|------------------|------|
-| `id` | Document ID | `string` |
-| `username` | Property | `string` |
-| `email` | Property | `string` |
-| `password_hash` | Property | `string` |
-| `permissions` | Property (JSON array) | `Vector<string>` |
-| `app_data` | Property (JSON object) | `Dictionary<string, string>` |
-| `is_active` | Property | `bool` |
-| `created_at` | Property (ISO 8601) | `DateTime` |
-| `updated_at` | Property (ISO 8601) | `DateTime?` |
-| `last_login_at` | Property (ISO 8601) | `DateTime?` |
-
-### 2.2 Session Model
-
-**File:** [`src/Authentication/Session.vala`](../src/Authentication/Session.vala)
-
-```vala
-public class Spry.Authentication.Session : Object {
-    public string id { get; set; }
-    public string user_id { get; set; }
-    public DateTime created_at { get; set; }
-    public DateTime expires_at { get; set; }
-    public string? ip_address { get; set; }
-    public string? user_agent { get; set; }
-}
-```
-
-**Implexus Property Mapping:**
-
-| Property | Implexus Storage | Type |
-|----------|------------------|------|
-| `id` | Document ID | `string` |
-| `user_id` | Property | `string` |
-| `created_at` | Property (ISO 8601) | `DateTime` |
-| `expires_at` | Property (ISO 8601) | `DateTime` |
-| `ip_address` | Property | `string?` |
-| `user_agent` | Property | `string?` |
-
----
-
-## 3. Implexus API Usage Patterns
-
-### 3.1 UserService Implexus Operations
-
-**File:** [`src/Authentication/UserService.vala`](../src/Authentication/UserService.vala)
-
-#### Create User
-```vala
-// Current Implexus pattern
-var user_path = new EntityPath("/spry/authentication/users");
-var user_doc = yield engine.create_document_async(user_path);
-
-// Set properties
-yield engine.set_entity_property_async(user_doc.path, "username", new NativeElement<string>(username));
-yield engine.set_entity_property_async(user_doc.path, "email", new NativeElement<string>(email));
-yield engine.set_entity_property_async(user_doc.path, "password_hash", new NativeElement<string>(hash));
-// ... more properties
-```
-
-#### Read User
-```vala
-// Current Implexus pattern
-var user_path = new EntityPath("/spry/authentication/users/%s".printf(id));
-var user_doc = yield engine.get_entity_or_null_async(user_path);
-if (user_doc == null) return null;
-
-var props = yield engine.get_properties_async(user_doc.path);
-var user = new User();
-user.id = user_doc.id;
-user.username = props.get("username")?.as_string_or_null();
-// ... more properties
-```
-
-#### Update User
-```vala
-// Current Implexus pattern - property by property updates
-yield engine.set_entity_property_async(user_path, "email", new NativeElement<string>(email));
-yield engine.set_entity_property_async(user_path, "updated_at", new NativeElement<string>(now));
-```
-
-#### Delete User
-```vala
-// Current Implexus pattern
-var user_path = new EntityPath("/spry/authentication/users/%s".printf(id));
-yield engine.delete_entity_async(user_path);
-```
-
-#### Query by Username (Catalogue)
-```vala
-// Current Implexus pattern
-var catalogue = yield engine.get_catalogue_async("/spry/authentication/users/by_username");
-var entry = catalogue.get(username);
-if (entry != null) {
-    var user_id = entry.value.as_string_or_null();
-    // Then fetch user by ID
-}
-```
-
-### 3.2 SessionService Implexus Operations
-
-**File:** [`src/Authentication/SessionService.vala`](../src/Authentication/SessionService.vala)
-
-#### Create Session
-```vala
-// Current Implexus pattern
-var session_path = new EntityPath("/spry/authentication/sessions");
-var session_doc = yield engine.create_document_async(session_path);
-
-// Set properties
-yield engine.set_entity_property_async(session_doc.path, "user_id", new NativeElement<string>(user_id));
-yield engine.set_entity_property_async(session_doc.path, "created_at", new NativeElement<string>(created_at));
-// ... more properties
-
-// Also update sessions_by_user index
-var index_path = new EntityPath("/spry/authentication/sessions_by_user/%s".printf(user_id));
-// ... index management
-```
-
-#### Get Sessions by User
-```vala
-// Current Implexus pattern - uses secondary index
-var index_path = new EntityPath("/spry/authentication/sessions_by_user/%s".printf(user_id));
-var index_doc = yield engine.get_entity_or_null_async(index_path);
-// Parse session IDs from index
-```
-
-### 3.3 Migration Implexus Operations
-
-**File:** [`src/Authentication/AuthenticationMigration.vala`](../src/Authentication/AuthenticationMigration.vala)
-
-```vala
-public class Spry.Authentication.AuthenticationMigration : Implexus.Migrations.Migration {
-    public override async void up_async(Engine engine) throws Error {
-        // Create containers
-        var users_path = new EntityPath("/spry/authentication/users");
-        yield engine.create_container_async(users_path);
-        
-        var sessions_path = new EntityPath("/spry/authentication/sessions");
-        yield engine.create_container_async(sessions_path);
-        
-        // Create catalogues for unique constraints
-        yield engine.create_catalogue_async(users_path, "by_username", "username");
-        yield engine.create_catalogue_async(users_path, "by_email", "email");
-    }
-}
-```
-
----
-
-## 4. Key Interfaces to Maintain
-
-### 4.1 Public Service Interfaces
-
-These interfaces must be preserved during migration:
-
-#### UserService Public API
-```vala
-public async User? get_user_by_id_async(string id)
-public async User? get_user_by_username_async(string username)
-public async User? get_user_by_email_async(string email)
-public async User create_user_async(string username, string email, string password)
-public async User update_user_async(User user)
-public async void delete_user_async(string id)
-public async bool validate_credentials_async(string username, string password)
-public async bool username_exists_async(string username)
-public async bool email_exists_async(string email)
-```
-
-#### SessionService Public API
-```vala
-public async Session create_session_async(string user_id, string? ip_address, string? user_agent)
-public async Session? get_session_async(string session_id)
-public async void delete_session_async(string session_id)
-public async void delete_user_sessions_async(string user_id)
-public async Vector<Session> get_user_sessions_async(string user_id)
-public async bool validate_session_async(string session_id)
-public async Session? refresh_session_async(string session_id)
-```
-
-#### PermissionService Public API
-```vala
-public async void grant_permission_async(string user_id, string permission)
-public async void revoke_permission_async(string user_id, string permission)
-public async bool has_permission_async(string user_id, string permission)
-public async Vector<string> get_user_permissions_async(string user_id)
-```
-
-### 4.2 Dependency Injection Contracts
-
-```vala
-// Inversion IoC registration pattern
-container.register<UserService>().as_singleton();
-container.register<SessionService>().as_singleton();
-container.register<PermissionService>().as_singleton();
-container.register<UserIdentityProvider>().as_singleton();
-```
-
----
-
-## 5. Implexus vs InvercargillSql Comparison
-
-### 5.1 Architectural Differences
-
-```mermaid
-graph LR
-    subgraph Implexus - Document Store
-        I1[Engine]
-        I2[Container]
-        I3[Document]
-        I4[Properties]
-        I5[Catalogue]
-    end
-    
-    subgraph InvercargillSql - SQL Database
-        S1[Connection]
-        S2[Command]
-        S3[Table/Row]
-        S4[Properties]
-        S5[Index]
-    end
-    
-    I1 --> I2
-    I2 --> I3
-    I3 --> I4
-    I2 --> I5
-    
-    S1 --> S2
-    S2 --> S3
-    S3 --> S4
-    S1 --> S5
-```
-
-### 5.2 Feature Comparison
-
-| Feature | Implexus | InvercargillSql |
-|---------|----------|-----------------|
-| **Data Model** | Hierarchical document store | Relational tables |
-| **Schema** | Schemaless properties | Fixed schema with migrations |
-| **Indexing** | Catalogues (auto-maintained) | SQL indexes (manual) |
-| **Querying** | Path-based + catalogues | SQL queries |
-| **Transactions** | Not explicit | Full transaction support |
-| **Async** | Native async API | Thread-based async |
-| **Result Type** | `Properties` | `Enumerable<Properties>` |
-| **Parameter Binding** | N/A | Fluent `with_parameter<T>()` |
-| **Relationships** | Manual (via paths) | Foreign keys |
-
-### 5.3 API Mapping
-
-| Operation | Implexus | InvercargillSql |
-|-----------|----------|-----------------|
-| **Connect** | `Engine` construction | `ConnectionFactory.create()` + `open()` |
-| **Create** | `create_document_async()` | `INSERT` via `execute_non_query()` |
-| **Read** | `get_entity_or_null_async()` + `get_properties_async()` | `SELECT` via `execute_query()` |
-| **Update** | `set_entity_property_async()` | `UPDATE` via `execute_non_query()` |
-| **Delete** | `delete_entity_async()` | `DELETE` via `execute_non_query()` |
-| **Query** | Catalogue lookup | `SELECT WHERE` via `execute_query()` |
-| **Transaction** | N/A | `begin_transaction()` + `commit()`/`rollback()` |
-
-### 5.4 Code Pattern Comparison
-
-#### Create Operation
-
-**Implexus (Current):**
-```vala
-var path = new EntityPath("/spry/authentication/users");
-var doc = yield engine.create_document_async(path);
-yield engine.set_entity_property_async(doc.path, "username", new NativeElement<string>(username));
-yield engine.set_entity_property_async(doc.path, "email", new NativeElement<string>(email));
-// ... more properties
-return doc.id;
-```
-
-**InvercargillSql (Target):**
-```vala
-var sql = """
-    INSERT INTO users (id, username, email, password_hash, is_active, created_at)
-    VALUES (:id, :username, :email, :password_hash, :is_active, :created_at)
-""";
-yield conn.create_command(sql)
-    .with_parameter("id", generate_uuid())
-    .with_parameter("username", username)
-    .with_parameter("email", email)
-    .with_parameter("password_hash", hash)
-    .with_parameter("is_active", true)
-    .with_parameter("created_at", new DateTime.now_utc().format_iso8601())
-    .execute_non_query_async();
-return conn.last_insert_rowid.to_string();
-```
-
-#### Read Operation
-
-**Implexus (Current):**
-```vala
-var path = new EntityPath("/spry/authentication/users/%s".printf(id));
-var doc = yield engine.get_entity_or_null_async(path);
-if (doc == null) return null;
-var props = yield engine.get_properties_async(doc.path);
-return user_from_properties(props);
-```
-
-**InvercargillSql (Target):**
-```vala
-var sql = "SELECT * FROM users WHERE id = :id";
-var results = yield conn.create_command(sql)
-    .with_parameter("id", id)
-    .execute_query_async();
-var row = results.first_or_default();
-if (row == null) return null;
-return user_from_row(row);
-```
-
-#### Query by Index
-
-**Implexus (Current):**
-```vala
-var catalogue = yield engine.get_catalogue_async("/spry/authentication/users/by_username");
-var entry = catalogue.get(username);
-if (entry == null) return null;
-return yield get_user_by_id_async(entry.value.as_string_or_null());
-```
-
-**InvercargillSql (Target):**
-```vala
-var sql = "SELECT * FROM users WHERE username = :username";
-var results = yield conn.create_command(sql)
-    .with_parameter("username", username)
-    .execute_query_async();
-var row = results.first_or_default();
-if (row == null) return null;
-return user_from_row(row);
-```
-
----
-
-## 6. Migration Strategy Recommendations
-
-### 6.1 Proposed SQL Schema
-
-```sql
--- Users table
-CREATE TABLE users (
-    id TEXT PRIMARY KEY,
-    username TEXT NOT NULL UNIQUE,
-    email TEXT NOT NULL UNIQUE,
-    password_hash TEXT NOT NULL,
-    is_active INTEGER NOT NULL DEFAULT 1,
-    created_at TEXT NOT NULL,
-    updated_at TEXT,
-    last_login_at TEXT
-);
-
--- User permissions (normalized)
-CREATE TABLE user_permissions (
-    id INTEGER PRIMARY KEY AUTOINCREMENT,
-    user_id TEXT NOT NULL,
-    permission TEXT NOT NULL,
-    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
-    UNIQUE(user_id, permission)
-);
-
--- User app data (key-value store)
-CREATE TABLE user_app_data (
-    id INTEGER PRIMARY KEY AUTOINCREMENT,
-    user_id TEXT NOT NULL,
-    key TEXT NOT NULL,
-    value TEXT,
-    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
-    UNIQUE(user_id, key)
-);
-
--- Sessions table
-CREATE TABLE sessions (
-    id TEXT PRIMARY KEY,
-    user_id TEXT NOT NULL,
-    created_at TEXT NOT NULL,
-    expires_at TEXT NOT NULL,
-    ip_address TEXT,
-    user_agent TEXT,
-    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
-);
-
--- Indexes for common queries
-CREATE INDEX idx_users_username ON users(username);
-CREATE INDEX idx_users_email ON users(email);
-CREATE INDEX idx_sessions_user_id ON sessions(user_id);
-CREATE INDEX idx_sessions_expires_at ON sessions(expires_at);
-```
-
-### 6.2 Migration Phases
-
-```mermaid
-flowchart TB
-    subgraph Phase 1 - Infrastructure
-        A1[Create SQL schema migration]
-        A2[Create ConnectionProvider]
-        A3[Update meson.build dependencies]
-    end
-    
-    subgraph Phase 2 - Data Access Layer
-        B1[Create UserRepository interface]
-        B2[Implement SqlUserRepository]
-        B3[Create SessionRepository interface]
-        B4[Implement SqlSessionRepository]
-    end
-    
-    subgraph Phase 3 - Service Migration
-        C1[Refactor UserService to use repository]
-        C2[Refactor SessionService to use repository]
-        C3[Update PermissionService]
-    end
-    
-    subgraph Phase 4 - Cleanup
-        D1[Remove Implexus dependency]
-        D2[Delete AuthenticationMigration]
-        D3[Update documentation]
-    end
-    
-    A1 --> A2 --> A3 --> B1
-    B1 --> B2 --> B3 --> B4
-    B4 --> C1 --> C2 --> C3
-    C3 --> D1 --> D2 --> D3
-```
-
-### 6.3 Recommended Repository Pattern
-
-To minimize impact on existing code and allow for future database changes, implement a repository pattern:
-
-```vala
-// Abstract repository interfaces
-public interface UserRepository : Object {
-    public abstract async User? get_by_id_async(string id);
-    public abstract async User? get_by_username_async(string username);
-    public abstract async User? get_by_email_async(string email);
-    public abstract async User create_async(User user);
-    public abstract async User update_async(User user);
-    public abstract async void delete_async(string id);
-    public abstract async bool username_exists_async(string username);
-    public abstract async bool email_exists_async(string email);
-}
-
-public interface SessionRepository : Object {
-    public abstract async Session create_async(Session session);
-    public abstract async Session? get_by_id_async(string id);
-    public abstract async void delete_async(string id);
-    public abstract async void delete_by_user_async(string user_id);
-    public abstract async Vector<Session> get_by_user_async(string user_id);
-}
-```
-
-### 6.4 Key Migration Considerations
-
-1. **Data Type Mapping:**
-   - `DateTime` → ISO 8601 string storage
-   - `Vector<string>` (permissions) → Separate table with foreign key
-   - `Dictionary<string, string>` (app_data) → Separate key-value table
-
-2. **Catalogue Replacement:**
-   - `by_username` catalogue → `UNIQUE` constraint + index
-   - `by_email` catalogue → `UNIQUE` constraint + index
-   - `sessions_by_user` index → Foreign key + index on `user_id`
-
-3. **Transaction Support:**
-   - InvercargillSql provides explicit transactions
-   - Use transactions for multi-step operations (e.g., create user + permissions)
-
-4. **Async Patterns:**
-   - Both use async/await
-   - InvercargillSql uses thread-based async (transparent to caller)
-
-5. **Connection Management:**
-   - Use singleton Connection injected via IoC
-   - Consider connection pooling for future scalability
-
----
-
-## 7. Files Requiring Modification
-
-### 7.1 Files to Modify
-
-| File | Changes Required |
-|------|------------------|
-| `src/Authentication/UserService.vala` | Replace Implexus with repository |
-| `src/Authentication/SessionService.vala` | Replace Implexus with repository |
-| `src/Authentication/PermissionService.vala` | May need updates if directly accessing user permissions |
-| `src/Authentication/meson.build` | Replace `implexus_dep` with `invercargill_sql_dep` |
-| `meson.build` (root) | Update dependency declaration |
-
-### 7.2 Files to Create
-
-| File | Purpose |
-|------|---------|
-| `src/Authentication/Repositories/UserRepository.vala` | Abstract user repository interface |
-| `src/Authentication/Repositories/SqlUserRepository.vala` | SQLite implementation |
-| `src/Authentication/Repositories/SessionRepository.vala` | Abstract session repository interface |
-| `src/Authentication/Repositories/SqlSessionRepository.vala` | SQLite implementation |
-| `src/Authentication/Migrations/CreateAuthTables.vala` | SQL schema migration |
-
-### 7.3 Files to Delete
-
-| File | Reason |
-|------|--------|
-| `src/Authentication/AuthenticationMigration.vala` | Replaced by SQL migration |
-
----
-
-## 8. Dependency Changes
-
-### 8.1 Current Dependencies (meson.build)
-
-```meson
-# src/Authentication/meson.build
-dependencies: [spry_dep, spry_authorisation_dep, implexus_dep, sodium_deps, invercargill_dep, astralis_dep]
-```
-
-### 8.2 Proposed Dependencies
-
-```meson
-# src/Authentication/meson.build
-dependencies: [spry_dep, spry_authorisation_dep, invercargill_sql_dep, sodium_deps, invercargill_dep, astralis_dep]
-```
-
-### 8.3 Root meson.build Changes
-
-```meson
-# Current
-implexus_dep = dependency('implexus-0.1')
-
-# Proposed
-invercargill_sql_dep = dependency('invercargill-sql-1')
-```
-
----
-
-## 9. Risk Assessment
-
-| Risk | Impact | Mitigation |
-|------|--------|------------|
-| Data loss during migration | High | Implement data migration script, backup strategy |
-| Breaking existing API | High | Maintain service interfaces, use repository pattern |
-| Performance regression | Medium | Benchmark critical paths, optimize queries |
-| Async behavior differences | Low | Both use async/await patterns consistently |
-| Transaction semantics | Low | InvercargillSql provides more robust transactions |
-
----
-
-## 10. Summary
-
-The authentication system's Implexus usage is concentrated in two main service classes: `UserService` and `SessionService`. The migration to InvercargillSql is straightforward from an API perspective since both libraries:
-
-1. Use the `Properties` interface for data representation
-2. Support async operations
-3. Are part of the Invercargill ecosystem
-
-The main differences are:
-
-1. **Query paradigm**: Path-based document lookup → SQL queries
-2. **Indexing**: Catalogues → SQL indexes with UNIQUE constraints
-3. **Transactions**: Implicit → Explicit with commit/rollback
-4. **Schema**: Schemaless → Fixed schema with migrations
-
-Implementing a repository pattern will isolate the database implementation details and allow the services to remain largely unchanged in their public API.

+ 0 - 1258
plans/invercargill-sql-migration-plan.md

@@ -1,1258 +0,0 @@
-# InvercargillSql Migration Implementation Plan
-
-## Overview
-
-This document provides a step-by-step implementation plan for migrating the Spry Authentication module from Implexus (document store) to InvercargillSql (relational database). The migration preserves all public APIs while replacing the storage backend.
-
-## Reference Documents
-
-- Analysis: [`plans/authentication-implexus-analysis.md`](authentication-implexus-analysis.md)
-- Current UserService: [`src/Authentication/UserService.vala`](../src/Authentication/UserService.vala)
-- Current SessionService: [`src/Authentication/SessionService.vala`](../src/Authentication/SessionService.vala)
-
----
-
-## 1. Repository Interface Design
-
-### 1.1 UserRepository Interface
-
-**File:** `src/Authentication/Repositories/UserRepository.vala`
-
-```vala
-using Invercargill.DataStructures;
-
-namespace Spry.Authentication {
-
-    /**
-     * Repository interface for User persistence operations.
-     * Abstracts the storage mechanism from the service layer.
-     */
-    public interface UserRepository : GLib.Object {
-
-        // =========================================================================
-        // Retrieval Operations
-        // =========================================================================
-
-        /**
-         * Gets a user by their unique ID.
-         *
-         * @param id The user's unique identifier
-         * @return The User, or null if not found
-         * @throws Error on storage failure
-         */
-        public abstract async User? get_by_id_async(string id) throws Error;
-
-        /**
-         * Gets a user by their username.
-         *
-         * @param username The username to look up
-         * @return The User, or null if not found
-         * @throws Error on storage failure
-         */
-        public abstract async User? get_by_username_async(string username) throws Error;
-
-        /**
-         * Gets a user by their email address.
-         *
-         * @param email The email address to look up
-         * @return The User, or null if not found
-         * @throws Error on storage failure
-         */
-        public abstract async User? get_by_email_async(string email) throws Error;
-
-        // =========================================================================
-        // Mutation Operations
-        // =========================================================================
-
-        /**
-         * Creates a new user.
-         *
-         * @param user The user to create (id should be pre-generated)
-         * @return The created User
-         * @throws UserError.DUPLICATE_USERNAME if username exists
-         * @throws UserError.DUPLICATE_EMAIL if email exists
-         * @throws Error on storage failure
-         */
-        public abstract async User create_async(User user) throws Error;
-
-        /**
-         * Updates an existing user.
-         *
-         * @param user The user to update
-         * @throws UserError.USER_NOT_FOUND if user doesn't exist
-         * @throws UserError.DUPLICATE_USERNAME if new username conflicts
-         * @throws UserError.DUPLICATE_EMAIL if new email conflicts
-         * @throws Error on storage failure
-         */
-        public abstract async void update_async(User user) throws Error;
-
-        /**
-         * Deletes a user by their unique ID.
-         *
-         * @param id The user's unique identifier
-         * @throws UserError.USER_NOT_FOUND if user doesn't exist
-         * @throws Error on storage failure
-         */
-        public abstract async void delete_async(string id) throws Error;
-
-        // =========================================================================
-        // Query Operations
-        // =========================================================================
-
-        /**
-         * Checks if a username already exists.
-         *
-         * @param username The username to check
-         * @return true if the username exists
-         * @throws Error on storage failure
-         */
-        public abstract async bool username_exists_async(string username) throws Error;
-
-        /**
-         * Checks if an email already exists.
-         *
-         * @param email The email to check
-         * @return true if the email exists
-         * @throws Error on storage failure
-         */
-        public abstract async bool email_exists_async(string email) throws Error;
-
-        /**
-         * Lists users with pagination support.
-         *
-         * @param offset The number of users to skip
-         * @param limit The maximum number of users to return
-         * @return A Vector of users
-         * @throws Error on storage failure
-         */
-        public abstract async Vector<User> list_async(int offset = 0, int limit = 100) throws Error;
-
-        /**
-         * Gets the total count of users.
-         *
-         * @return The number of users
-         * @throws Error on storage failure
-         */
-        public abstract async int count_async() throws Error;
-
-        // =========================================================================
-        // Permission Operations
-        // =========================================================================
-
-        /**
-         * Gets all permissions for a user.
-         *
-         * @param user_id The user's unique identifier
-         * @return A Vector of permission strings
-         * @throws Error on storage failure
-         */
-        public abstract async Vector<string> get_permissions_async(string user_id) throws Error;
-
-        /**
-         * Adds a permission to a user.
-         *
-         * @param user_id The user's unique identifier
-         * @param permission The permission to add
-         * @throws Error on storage failure
-         */
-        public abstract async void add_permission_async(string user_id, string permission) throws Error;
-
-        /**
-         * Removes a permission from a user.
-         *
-         * @param user_id The user's unique identifier
-         * @param permission The permission to remove
-         * @throws Error on storage failure
-         */
-        public abstract async void remove_permission_async(string user_id, string permission) throws Error;
-
-        /**
-         * Clears all permissions from a user.
-         *
-         * @param user_id The user's unique identifier
-         * @throws Error on storage failure
-         */
-        public abstract async void clear_permissions_async(string user_id) throws Error;
-
-        // =========================================================================
-        // App Data Operations
-        // =========================================================================
-
-        /**
-         * Gets app data for a user.
-         *
-         * @param user_id The user's unique identifier
-         * @return A Dictionary of app data key-value pairs
-         * @throws Error on storage failure
-         */
-        public abstract async Dictionary<string, string> get_app_data_async(string user_id) throws Error;
-
-        /**
-         * Sets an app data value for a user.
-         *
-         * @param user_id The user's unique identifier
-         * @param key The app data key
-         * @param value The app data value
-         * @throws Error on storage failure
-         */
-        public abstract async void set_app_data_value_async(string user_id, string key, string value) throws Error;
-
-        /**
-         * Removes an app data key from a user.
-         *
-         * @param user_id The user's unique identifier
-         * @param key The app data key to remove
-         * @throws Error on storage failure
-         */
-        public abstract async void remove_app_data_value_async(string user_id, string key) throws Error;
-    }
-}
-```
-
-### 1.2 SessionRepository Interface
-
-**File:** `src/Authentication/Repositories/SessionRepository.vala`
-
-```vala
-using Invercargill.DataStructures;
-
-namespace Spry.Authentication {
-
-    /**
-     * Repository interface for Session persistence operations.
-     * Abstracts the storage mechanism from the service layer.
-     */
-    public interface SessionRepository : GLib.Object {
-
-        // =========================================================================
-        // Retrieval Operations
-        // =========================================================================
-
-        /**
-         * Gets a session by its unique ID.
-         *
-         * @param id The session's unique identifier
-         * @return The Session, or null if not found
-         * @throws Error on storage failure
-         */
-        public abstract async Session? get_by_id_async(string id) throws Error;
-
-        /**
-         * Gets all sessions for a user.
-         *
-         * @param user_id The user's unique identifier
-         * @return A Vector of sessions (excluding expired)
-         * @throws Error on storage failure
-         */
-        public abstract async Vector<Session> get_by_user_async(string user_id) throws Error;
-
-        // =========================================================================
-        // Mutation Operations
-        // =========================================================================
-
-        /**
-         * Creates a new session.
-         *
-         * @param session The session to create (id should be pre-generated)
-         * @return The created Session
-         * @throws Error on storage failure
-         */
-        public abstract async Session create_async(Session session) throws Error;
-
-        /**
-         * Updates an existing session.
-         *
-         * @param session The session to update
-         * @throws SessionError.SESSION_NOT_FOUND if session doesn't exist
-         * @throws Error on storage failure
-         */
-        public abstract async void update_async(Session session) throws Error;
-
-        /**
-         * Deletes a session by its unique ID.
-         *
-         * @param id The session's unique identifier
-         * @throws Error on storage failure
-         */
-        public abstract async void delete_async(string id) throws Error;
-
-        /**
-         * Deletes all sessions for a user.
-         *
-         * @param user_id The user's unique identifier
-         * @throws Error on storage failure
-         */
-        public abstract async void delete_by_user_async(string user_id) throws Error;
-
-        // =========================================================================
-        // Cleanup Operations
-        // =========================================================================
-
-        /**
-         * Removes all expired sessions from storage.
-         *
-         * @throws Error on storage failure
-         */
-        public abstract async void cleanup_expired_async() throws Error;
-    }
-}
-```
-
----
-
-## 2. SQL Schema Design
-
-### 2.1 Users Table
-
-```sql
-CREATE TABLE users (
-    id TEXT PRIMARY KEY NOT NULL,
-    username TEXT NOT NULL UNIQUE,
-    email TEXT NOT NULL UNIQUE,
-    password_hash TEXT NOT NULL,
-    is_active INTEGER NOT NULL DEFAULT 1,
-    created_at TEXT NOT NULL,
-    updated_at TEXT,
-    last_login_at TEXT
-);
-
--- Index for username lookups (also enforces uniqueness)
-CREATE UNIQUE INDEX idx_users_username ON users(username);
-
--- Index for email lookups (also enforces uniqueness)
-CREATE UNIQUE INDEX idx_users_email ON users(email);
-```
-
-### 2.2 User Permissions Table
-
-```sql
-CREATE TABLE user_permissions (
-    id INTEGER PRIMARY KEY AUTOINCREMENT,
-    user_id TEXT NOT NULL,
-    permission TEXT NOT NULL,
-    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
-    UNIQUE(user_id, permission)
-);
-
--- Index for permission lookups by user
-CREATE INDEX idx_user_permissions_user_id ON user_permissions(user_id);
-```
-
-### 2.3 User App Data Table
-
-```sql
-CREATE TABLE user_app_data (
-    id INTEGER PRIMARY KEY AUTOINCREMENT,
-    user_id TEXT NOT NULL,
-    key TEXT NOT NULL,
-    value TEXT,
-    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
-    UNIQUE(user_id, key)
-);
-
--- Index for app data lookups by user
-CREATE INDEX idx_user_app_data_user_id ON user_app_data(user_id);
-```
-
-### 2.4 Sessions Table
-
-```sql
-CREATE TABLE sessions (
-    id TEXT PRIMARY KEY NOT NULL,
-    user_id TEXT NOT NULL,
-    created_at TEXT NOT NULL,
-    expires_at TEXT NOT NULL,
-    ip_address TEXT,
-    user_agent TEXT,
-    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
-);
-
--- Index for session lookups by user
-CREATE INDEX idx_sessions_user_id ON sessions(user_id);
-
--- Index for expired session cleanup
-CREATE INDEX idx_sessions_expires_at ON sessions(expires_at);
-```
-
-### 2.5 Schema Diagram
-
-```mermaid
-erDiagram
-    users ||--o{ user_permissions : has
-    users ||--o{ user_app_data : has
-    users ||--o{ sessions : has
-
-    users {
-        TEXT id PK
-        TEXT username UK
-        TEXT email UK
-        TEXT password_hash
-        INTEGER is_active
-        TEXT created_at
-        TEXT updated_at
-        TEXT last_login_at
-    }
-
-    user_permissions {
-        INTEGER id PK
-        TEXT user_id FK
-        TEXT permission
-    }
-
-    user_app_data {
-        INTEGER id PK
-        TEXT user_id FK
-        TEXT key UK
-        TEXT value
-    }
-
-    sessions {
-        TEXT id PK
-        TEXT user_id FK
-        TEXT created_at
-        TEXT expires_at
-        TEXT ip_address
-        TEXT user_agent
-    }
-```
-
----
-
-## 3. Implementation Details
-
-### 3.1 SqlUserRepository Implementation
-
-**File:** `src/Authentication/Repositories/SqlUserRepository.vala`
-
-**Constructor:**
-```vala
-public class SqlUserRepository : GLib.Object, UserRepository {
-
-    private InvercargillSql.Connection _connection;
-
-    public SqlUserRepository(InvercargillSql.Connection connection) {
-        _connection = connection;
-    }
-    
-    // ... implementation
-}
-```
-
-**Key Implementation Patterns:**
-
-1. **INSERT with Parameters:**
-```vala
-public async User create_async(User user) throws Error {
-    var sql = """
-        INSERT INTO users (id, username, email, password_hash, is_active, created_at)
-        VALUES (:id, :username, :email, :password_hash, :is_active, :created_at)
-    """;
-    
-    yield _connection.create_command(sql)
-        .with_parameter("id", user.id)
-        .with_parameter("username", user.username)
-        .with_parameter("email", user.email)
-        .with_parameter("password_hash", user.password_hash)
-        .with_parameter("is_active", 1)
-        .with_parameter("created_at", user.created_at.format_iso8601())
-        .execute_non_query_async();
-    
-    return user;
-}
-```
-
-2. **SELECT with Properties Mapping:**
-```vala
-public async User? get_by_id_async(string id) throws Error {
-    var sql = "SELECT * FROM users WHERE id = :id";
-    
-    var results = yield _connection.create_command(sql)
-        .with_parameter("id", id)
-        .execute_query_async();
-    
-    var row = results.first_or_default();
-    if (row == null) return null;
-    
-    return user_from_properties(row);
-}
-
-private User user_from_properties(Properties props) {
-    var user = new User();
-    user.set_id(props.get("id").as<string>());
-    user.set_username(props.get("username").as<string>());
-    user.email = props.get("email").as<string>();
-    user.password_hash = props.get("password_hash").as<string>());
-    
-    var created_str = props.get("created_at").as<string>();
-    user.created_at = new DateTime.from_iso8601(created_str, new TimeZone.utc());
-    
-    // Handle nullable fields
-    if (props.has("updated_at") && props.get("updated_at") != null) {
-        var updated_str = props.get("updated_at").as<string>();
-        user.updated_at = new DateTime.from_iso8601(updated_str, new TimeZone.utc());
-    }
-    
-    return user;
-}
-```
-
-3. **Permissions as Sub-query:**
-```vala
-public async User? get_by_id_async(string id) throws Error {
-    // Get user with permissions in single query
-    var sql = """
-        SELECT u.*, GROUP_CONCAT(up.permission, ',') as permissions
-        FROM users u
-        LEFT JOIN user_permissions up ON u.id = up.user_id
-        WHERE u.id = :id
-        GROUP BY u.id
-    """;
-    
-    // ... execute and parse
-}
-```
-
-### 3.2 SqlSessionRepository Implementation
-
-**File:** `src/Authentication/Repositories/SqlSessionRepository.vala`
-
-**Constructor:**
-```vala
-public class SqlSessionRepository : GLib.Object, SessionRepository {
-
-    private InvercargillSql.Connection _connection;
-
-    public SqlSessionRepository(InvercargillSql.Connection connection) {
-        _connection = connection;
-    }
-    
-    // ... implementation
-}
-```
-
-**Key Implementation Patterns:**
-
-1. **Create Session:**
-```vala
-public async Session create_async(Session session) throws Error {
-    var sql = """
-        INSERT INTO sessions (id, user_id, created_at, expires_at, ip_address, user_agent)
-        VALUES (:id, :user_id, :created_at, :expires_at, :ip_address, :user_agent)
-    """;
-    
-    yield _connection.create_command(sql)
-        .with_parameter("id", session.id)
-        .with_parameter("user_id", session.user_id)
-        .with_parameter("created_at", session.created_at.format_iso8601())
-        .with_parameter("expires_at", session.expires_at.format_iso8601())
-        .with_parameter("ip_address", session.ip_address ?? "")
-        .with_parameter("user_agent", session.user_agent ?? "")
-        .execute_non_query_async();
-    
-    return session;
-}
-```
-
-2. **Get Sessions by User:**
-```vala
-public async Vector<Session> get_by_user_async(string user_id) throws Error {
-    var sql = """
-        SELECT * FROM sessions 
-        WHERE user_id = :user_id AND expires_at > :now
-        ORDER BY created_at DESC
-    """;
-    
-    var now = new DateTime.now_utc().format_iso8601();
-    
-    var results = yield _connection.create_command(sql)
-        .with_parameter("user_id", user_id)
-        .with_parameter("now", now)
-        .execute_query_async();
-    
-    var sessions = new Vector<Session>();
-    foreach (var row in results) {
-        sessions.add(session_from_properties(row));
-    }
-    return sessions;
-}
-```
-
-3. **Cleanup Expired:**
-```vala
-public async void cleanup_expired_async() throws Error {
-    var sql = "DELETE FROM sessions WHERE expires_at < :now";
-    var now = new DateTime.now_utc().format_iso8601();
-    
-    yield _connection.create_command(sql)
-        .with_parameter("now", now)
-        .execute_non_query_async();
-}
-```
-
-### 3.3 Schema Migration Class
-
-**File:** `src/Authentication/Migrations/CreateAuthTables.vala`
-
-```vala
-namespace Spry.Authentication.Migrations {
-
-    /**
-     * Creates the authentication database schema.
-     * Run once during application initialization.
-     */
-    public class CreateAuthTables : GLib.Object {
-
-        private InvercargillSql.Connection _connection;
-
-        public CreateAuthTables(InvercargillSql.Connection connection) {
-            _connection = connection;
-        }
-
-        /**
-         * Creates all authentication tables if they don't exist.
-         */
-        public async void migrate_async() throws Error {
-            // Users table
-            yield _connection.create_command("""
-                CREATE TABLE IF NOT EXISTS users (
-                    id TEXT PRIMARY KEY NOT NULL,
-                    username TEXT NOT NULL UNIQUE,
-                    email TEXT NOT NULL UNIQUE,
-                    password_hash TEXT NOT NULL,
-                    is_active INTEGER NOT NULL DEFAULT 1,
-                    created_at TEXT NOT NULL,
-                    updated_at TEXT,
-                    last_login_at TEXT
-                )
-            """).execute_non_query_async();
-
-            // User permissions table
-            yield _connection.create_command("""
-                CREATE TABLE IF NOT EXISTS user_permissions (
-                    id INTEGER PRIMARY KEY AUTOINCREMENT,
-                    user_id TEXT NOT NULL,
-                    permission TEXT NOT NULL,
-                    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
-                    UNIQUE(user_id, permission)
-                )
-            """).execute_non_query_async();
-
-            // User app data table
-            yield _connection.create_command("""
-                CREATE TABLE IF NOT EXISTS user_app_data (
-                    id INTEGER PRIMARY KEY AUTOINCREMENT,
-                    user_id TEXT NOT NULL,
-                    key TEXT NOT NULL,
-                    value TEXT,
-                    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
-                    UNIQUE(user_id, key)
-                )
-            """).execute_non_query_async();
-
-            // Sessions table
-            yield _connection.create_command("""
-                CREATE TABLE IF NOT EXISTS sessions (
-                    id TEXT PRIMARY KEY NOT NULL,
-                    user_id TEXT NOT NULL,
-                    created_at TEXT NOT NULL,
-                    expires_at TEXT NOT NULL,
-                    ip_address TEXT,
-                    user_agent TEXT,
-                    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
-                )
-            """).execute_non_query_async();
-
-            // Create indexes
-            yield create_index_async("idx_users_username", "users(username)");
-            yield create_index_async("idx_users_email", "users(email)");
-            yield create_index_async("idx_user_permissions_user_id", "user_permissions(user_id)");
-            yield create_index_async("idx_user_app_data_user_id", "user_app_data(user_id)");
-            yield create_index_async("idx_sessions_user_id", "sessions(user_id)");
-            yield create_index_async("idx_sessions_expires_at", "sessions(expires_at)");
-        }
-
-        private async void create_index_async(string name, string definition) throws Error {
-            yield _connection.create_command(
-                "CREATE INDEX IF NOT EXISTS %s ON %s".printf(name, definition)
-            ).execute_non_query_async();
-        }
-    }
-}
-```
-
----
-
-## 4. Code Migration Strategy
-
-### 4.1 UserService Changes
-
-**Current Dependencies (to remove):**
-```vala
-using Implexus.Core;
-private Engine _engine = inject<Engine>();
-```
-
-**New Dependencies (to add):**
-```vala
-private UserRepository _user_repository = inject<UserRepository>();
-```
-
-**Methods to Modify:**
-
-| Method | Current Implementation | New Implementation |
-|--------|----------------------|-------------------|
-| [`create_user_async()`](../src/Authentication/UserService.vala:65) | Uses `create_document_async()`, `set_entity_property_async()` | Call `_user_repository.create_async()` |
-| [`get_user_async()`](../src/Authentication/UserService.vala:116) | Uses `get_entity_or_null_async()`, `get_properties_async()` | Call `_user_repository.get_by_id_async()` |
-| [`get_user_by_username_async()`](../src/Authentication/UserService.vala:137) | Uses catalogue path lookup | Call `_user_repository.get_by_username_async()` |
-| [`get_user_by_email_async()`](../src/Authentication/UserService.vala:170) | Uses catalogue path lookup | Call `_user_repository.get_by_email_async()` |
-| [`update_user_async()`](../src/Authentication/UserService.vala:207) | Uses `set_entity_property_async()` | Call `_user_repository.update_async()` |
-| [`delete_user_async()`](../src/Authentication/UserService.vala:256) | Uses `delete_async()` on entity | Call `_user_repository.delete_async()` |
-| [`list_users_async()`](../src/Authentication/UserService.vala:281) | Iterates container children | Call `_user_repository.list_async()` |
-| [`username_exists_async()`](../src/Authentication/UserService.vala:414) | Uses `entity_exists_async()` on catalogue path | Call `_user_repository.username_exists_async()` |
-| [`email_exists_async()`](../src/Authentication/UserService.vala:426) | Uses `entity_exists_async()` on catalogue path | Call `_user_repository.email_exists_async()` |
-| [`user_count_async()`](../src/Authentication/UserService.vala:437) | Counts document children | Call `_user_repository.count_async()` |
-
-**Methods to Remove (Private Helpers):**
-- [`get_users_container_async()`](../src/Authentication/UserService.vala:459) - No longer needed
-- [`store_user_in_document_async()`](../src/Authentication/UserService.vala:483) - No longer needed
-- [`load_user_from_document_async()`](../src/Authentication/UserService.vala:493) - No longer needed
-- [`json_to_element()`](../src/Authentication/UserService.vala:503) - No longer needed
-- [`properties_to_json()`](../src/Authentication/UserService.vala:534) - No longer needed
-- [`element_to_json()`](../src/Authentication/UserService.vala:544) - No longer needed
-
-**Refactored UserService (simplified):**
-```vala
-using Invercargill.DataStructures;
-using Inversion;
-
-namespace Spry.Authentication {
-
-    public class UserService : GLib.Object {
-
-        private UserRepository _user_repository = inject<UserRepository>();
-        private CryptographyProvider _crypto = inject<CryptographyProvider>();
-
-        public async User create_user_async(string username, string email, string password) throws Error {
-            // Validate username uniqueness
-            if (yield _user_repository.username_exists_async(username)) {
-                throw new UserError.DUPLICATE_USERNAME("Username already exists");
-            }
-
-            // Validate email uniqueness
-            if (yield _user_repository.email_exists_async(email)) {
-                throw new UserError.DUPLICATE_EMAIL("Email already exists");
-            }
-
-            // Hash password
-            var password_hash = hash_password(password);
-            if (password_hash == null) {
-                throw new UserError.STORAGE_ERROR("Failed to hash password");
-            }
-
-            // Create user object
-            var user = new User();
-            user.set_id(generate_uuid());
-            user.set_username(username);
-            user.email = email;
-            user.password_hash = (!)password_hash;
-            user.created_at = new DateTime.now_utc();
-
-            // Persist via repository
-            return yield _user_repository.create_async(user);
-        }
-
-        public async User? get_user_async(string user_id) throws Error {
-            return yield _user_repository.get_by_id_async(user_id);
-        }
-
-        public async User? get_user_by_username_async(string username) throws Error {
-            return yield _user_repository.get_by_username_async(username);
-        }
-
-        public async User? get_user_by_email_async(string email) throws Error {
-            return yield _user_repository.get_by_email_async(email);
-        }
-
-        public async void update_user_async(User user) throws Error {
-            // Check for username/email conflicts before update
-            var existing = yield _user_repository.get_by_id_async(user.id);
-            if (existing == null) {
-                throw new UserError.USER_NOT_FOUND("User not found");
-            }
-
-            if (existing.username != user.username) {
-                if (yield _user_repository.username_exists_async(user.username)) {
-                    throw new UserError.DUPLICATE_USERNAME("Username already exists");
-                }
-            }
-
-            if (existing.email != user.email) {
-                if (yield _user_repository.email_exists_async(user.email)) {
-                    throw new UserError.DUPLICATE_EMAIL("Email already exists");
-                }
-            }
-
-            user.updated_at = new DateTime.now_utc();
-            yield _user_repository.update_async(user);
-        }
-
-        public async void delete_user_async(string user_id) throws Error {
-            yield _user_repository.delete_async(user_id);
-        }
-
-        public async Vector<User> list_users_async(int offset = 0, int limit = 100) throws Error {
-            return yield _user_repository.list_async(offset, limit);
-        }
-
-        public async bool username_exists_async(string username) throws Error {
-            return yield _user_repository.username_exists_async(username);
-        }
-
-        public async bool email_exists_async(string email) throws Error {
-            return yield _user_repository.email_exists_async(email);
-        }
-
-        public async int user_count_async() throws Error {
-            return yield _user_repository.count_async();
-        }
-
-        // Password methods remain unchanged
-        public string? hash_password(string password) {
-            return Sodium.PasswordHashing.hash(password);
-        }
-
-        public bool verify_password(User user, string password) {
-            return Sodium.PasswordHashing.check(user.password_hash, password);
-        }
-
-        public async void set_password_async(User user, string new_password) throws Error {
-            var password_hash = hash_password(new_password);
-            if (password_hash == null) {
-                throw new UserError.STORAGE_ERROR("Failed to hash password");
-            }
-            user.password_hash = (!)password_hash;
-            user.updated_at = new DateTime.now_utc();
-            yield update_user_async(user);
-        }
-
-        public async User? authenticate_async(string username_or_email, string password) throws Error {
-            User? user = yield get_user_by_username_async(username_or_email);
-            if (user == null) {
-                user = yield get_user_by_email_async(username_or_email);
-            }
-            if (user == null) return null;
-
-            if (!verify_password(user, password)) return null;
-            return user;
-        }
-
-        private string generate_uuid() {
-            uint8[] bytes = new uint8[16];
-            Sodium.Random.random_bytes(bytes);
-            bytes[6] = (bytes[6] & 0x0f) | 0x40;
-            bytes[8] = (bytes[8] & 0x3f) | 0x80;
-            return "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x".printf(
-                bytes[0], bytes[1], bytes[2], bytes[3],
-                bytes[4], bytes[5], bytes[6], bytes[7],
-                bytes[8], bytes[9], bytes[10], bytes[11],
-                bytes[12], bytes[13], bytes[14], bytes[15]
-            );
-        }
-    }
-}
-```
-
-### 4.2 SessionService Changes
-
-**Current Dependencies (to remove):**
-```vala
-using Implexus.Core;
-private Engine _engine = inject<Engine>();
-```
-
-**New Dependencies (to add):**
-```vala
-private SessionRepository _session_repository = inject<SessionRepository>();
-```
-
-**Methods to Modify:**
-
-| Method | Current Implementation | New Implementation |
-|--------|----------------------|-------------------|
-| [`create_session_async()`](../src/Authentication/SessionService.vala:209) | Creates document + updates user index | Call `_session_repository.create_async()` |
-| [`get_session_async()`](../src/Authentication/SessionService.vala:387) | Uses `get_entity_or_null_async()` | Call `_session_repository.get_by_id_async()` |
-| [`get_sessions_for_user_async()`](../src/Authentication/SessionService.vala:412) | Uses secondary index | Call `_session_repository.get_by_user_async()` |
-| [`delete_session_async()`](../src/Authentication/SessionService.vala:441) | Deletes document + updates index | Call `_session_repository.delete_async()` |
-| [`delete_all_sessions_for_user_async()`](../src/Authentication/SessionService.vala:468) | Iterates index + deletes | Call `_session_repository.delete_by_user_async()` |
-| [`cleanup_expired_sessions_async()`](../src/Authentication/SessionService.vala:562) | Iterates all sessions | Call `_session_repository.cleanup_expired_async()` |
-
-**Methods to Remove (Private Helpers):**
-- [`get_sessions_container_async()`](../src/Authentication/SessionService.vala:641) - No longer needed
-- [`get_sessions_by_user_container_async()`](../src/Authentication/SessionService.vala:665) - No longer needed
-- [`store_session_in_document_async()`](../src/Authentication/SessionService.vala:688) - No longer needed
-- [`load_session_from_document_async()`](../src/Authentication/SessionService.vala:698) - No longer needed
-- [`json_to_element()`](../src/Authentication/SessionService.vala:708) - No longer needed
-- [`properties_to_json()`](../src/Authentication/SessionService.vala:740) - No longer needed
-- [`element_to_json()`](../src/Authentication/SessionService.vala:750) - No longer needed
-- [`add_session_to_user_index_async()`](../src/Authentication/SessionService.vala:834) - No longer needed
-- [`remove_session_from_user_index_async()`](../src/Authentication/SessionService.vala:873) - No longer needed
-- [`clear_user_sessions_index_async()`](../src/Authentication/SessionService.vala:897) - No longer needed
-- [`get_session_ids_for_user_async()`](../src/Authentication/SessionService.vala:906) - No longer needed
-- [`load_session_ids_from_document_async()`](../src/Authentication/SessionService.vala:917) - No longer needed
-- [`store_session_ids_in_document_async()`](../src/Authentication/SessionService.vala:940) - No longer needed
-
-### 4.3 PermissionService Changes
-
-PermissionService already delegates to UserService, so minimal changes are needed. The `update_user_async()` call in PermissionService will work transparently with the repository-based UserService.
-
----
-
-## 5. Build System Changes
-
-### 5.1 Root meson.build Changes
-
-**File:** [`meson.build`](../meson.build)
-
-**Add InvercargillSql dependency:**
-```meson
-# Add after existing dependencies (around line 17)
-invercargill_sql_dep = dependency('invercargill-sql-1')
-```
-
-**Note:** The `implexus_dep` can be removed from the root meson.build if no other modules use it. For this migration, keep it temporarily until full removal is confirmed.
-
-### 5.2 src/meson.build Changes
-
-**File:** [`src/meson.build`](../src/meson.build)
-
-No changes needed - the main Spry library doesn't directly use Implexus.
-
-### 5.3 src/Authentication/meson.build Changes
-
-**File:** [`src/Authentication/meson.build`](../src/Authentication/meson.build)
-
-**Current content:**
-```meson
-authentication_sources = files(
-    'User.vala',
-    'Session.vala',
-    'UserService.vala',
-    'SessionService.vala',
-    'PermissionService.vala',
-    'UserIdentityProvider.vala',
-    'Components/LoginFormComponent.vala',
-    'Components/UserManagementComponent.vala',
-    'Components/UserDetailsComponent.vala',
-    'Components/NewUserComponent.vala',
-    'AuthenticationMigration.vala'
-)
-
-libspry_authentication = static_library('spry-authentication',
-    authentication_sources,
-    dependencies: [spry_dep, spry_authorisation_dep, implexus_dep, sodium_deps, invercargill_dep, astralis_dep],
-    include_directories: include_directories('..')
-)
-
-spry_authentication_inc = include_directories('.')
-spry_authentication_dep = declare_dependency(
-    link_with: libspry_authentication,
-    include_directories: spry_authentication_inc,
-    dependencies: [spry_dep, spry_authorisation_dep, implexus_dep]
-)
-```
-
-**New content:**
-```meson
-authentication_sources = files(
-    'User.vala',
-    'Session.vala',
-    'UserService.vala',
-    'SessionService.vala',
-    'PermissionService.vala',
-    'UserIdentityProvider.vala',
-    'Components/LoginFormComponent.vala',
-    'Components/UserManagementComponent.vala',
-    'Components/UserDetailsComponent.vala',
-    'Components/NewUserComponent.vala',
-    'Repositories/UserRepository.vala',
-    'Repositories/SqlUserRepository.vala',
-    'Repositories/SessionRepository.vala',
-    'Repositories/SqlSessionRepository.vala',
-    'Migrations/CreateAuthTables.vala'
-)
-
-libspry_authentication = static_library('spry-authentication',
-    authentication_sources,
-    dependencies: [spry_dep, spry_authorisation_dep, invercargill_sql_dep, sodium_deps, invercargill_dep, astralis_dep],
-    include_directories: include_directories('..')
-)
-
-spry_authentication_inc = include_directories('.')
-spry_authentication_dep = declare_dependency(
-    link_with: libspry_authentication,
-    include_directories: spry_authentication_inc,
-    dependencies: [spry_dep, spry_authorisation_dep, invercargill_sql_dep]
-)
-```
-
-**Summary of changes:**
-1. Remove `'AuthenticationMigration.vala'` from sources
-2. Add new repository files to sources
-3. Add new migration file to sources
-4. Replace `implexus_dep` with `invercargill_sql_dep` in dependencies
-
----
-
-## 6. Migration Path
-
-### 6.1 Implementation Order
-
-```mermaid
-flowchart TB
-    subgraph Phase 1 - Infrastructure
-        A1[Add invercargill_sql_dep to meson.build]
-        A2[Create Repositories directory]
-        A3[Create Migrations directory]
-    end
-    
-    subgraph Phase 2 - Repository Layer
-        B1[Create UserRepository interface]
-        B2[Create SessionRepository interface]
-        B3[Implement SqlUserRepository]
-        B4[Implement SqlSessionRepository]
-        B5[Create CreateAuthTables migration]
-    end
-    
-    subgraph Phase 3 - Service Migration
-        C1[Update UserService to use UserRepository]
-        C2[Update SessionService to use SessionRepository]
-        C3[Remove Implexus imports and helpers]
-    end
-    
-    subgraph Phase 4 - Build Updates
-        D1[Update src/Authentication/meson.build]
-        D2[Delete AuthenticationMigration.vala]
-        D3[Remove implexus_dep from root meson.build]
-    end
-    
-    subgraph Phase 5 - IoC Registration
-        E1[Register Connection in IoC container]
-        E2[Register UserRepository to SqlUserRepository]
-        E3[Register SessionRepository to SqlSessionRepository]
-        E4[Run migration at startup]
-    end
-    
-    A1 --> A2 --> A3 --> B1
-    B1 --> B2 --> B3 --> B4 --> B5
-    B5 --> C1 --> C2 --> C3
-    C3 --> D1 --> D2 --> D3
-    D3 --> E1 --> E2 --> E3 --> E4
-```
-
-### 6.2 Step-by-Step Implementation Checklist
-
-#### Phase 1: Infrastructure Setup
-- [ ] Add `invercargill_sql_dep = dependency('invercargill-sql-1')` to root [`meson.build`](../meson.build)
-- [ ] Create directory `src/Authentication/Repositories/`
-- [ ] Create directory `src/Authentication/Migrations/`
-
-#### Phase 2: Repository Interfaces
-- [ ] Create [`src/Authentication/Repositories/UserRepository.vala`](../src/Authentication/Repositories/UserRepository.vala) with interface definition
-- [ ] Create [`src/Authentication/Repositories/SessionRepository.vala`](../src/Authentication/Repositories/SessionRepository.vala) with interface definition
-
-#### Phase 3: Repository Implementations
-- [ ] Create [`src/Authentication/Repositories/SqlUserRepository.vala`](../src/Authentication/Repositories/SqlUserRepository.vala)
-  - Implement `get_by_id_async()`
-  - Implement `get_by_username_async()`
-  - Implement `get_by_email_async()`
-  - Implement `create_async()`
-  - Implement `update_async()`
-  - Implement `delete_async()`
-  - Implement `username_exists_async()`
-  - Implement `email_exists_async()`
-  - Implement `list_async()`
-  - Implement `count_async()`
-  - Implement permission methods
-  - Implement app data methods
-- [ ] Create [`src/Authentication/Repositories/SqlSessionRepository.vala`](../src/Authentication/Repositories/SqlSessionRepository.vala)
-  - Implement `get_by_id_async()`
-  - Implement `get_by_user_async()`
-  - Implement `create_async()`
-  - Implement `update_async()`
-  - Implement `delete_async()`
-  - Implement `delete_by_user_async()`
-  - Implement `cleanup_expired_async()`
-
-#### Phase 4: Schema Migration
-- [ ] Create [`src/Authentication/Migrations/CreateAuthTables.vala`](../src/Authentication/Migrations/CreateAuthTables.vala)
-
-#### Phase 5: Service Refactoring
-- [ ] Update [`src/Authentication/UserService.vala`](../src/Authentication/UserService.vala):
-  - Remove `using Implexus.Core;`
-  - Replace `Engine _engine` with `UserRepository _user_repository`
-  - Refactor all methods to use repository
-  - Remove private helper methods for Implexus
-- [ ] Update [`src/Authentication/SessionService.vala`](../src/Authentication/SessionService.vala):
-  - Remove `using Implexus.Core;`
-  - Replace `Engine _engine` with `SessionRepository _session_repository`
-  - Refactor all methods to use repository
-  - Remove private helper methods for Implexus
-  - Remove user index management methods
-
-#### Phase 6: Build System Updates
-- [ ] Update [`src/Authentication/meson.build`](../src/Authentication/meson.build):
-  - Add new repository files to sources
-  - Add new migration file to sources
-  - Remove `AuthenticationMigration.vala` from sources
-  - Replace `implexus_dep` with `invercargill_sql_dep`
-- [ ] Delete [`src/Authentication/AuthenticationMigration.vala`](../src/Authentication/AuthenticationMigration.vala)
-- [ ] Optionally remove `implexus_dep` from root [`meson.build`](../meson.build) if no other modules use it
-
-#### Phase 7: IoC Registration Updates
-- [ ] Update application startup code to:
-  - Create/open SQLite database connection
-  - Register `InvercargillSql.Connection` as singleton in IoC container
-  - Register `UserRepository` → `SqlUserRepository` in IoC container
-  - Register `SessionRepository` → `SqlSessionRepository` in IoC container
-  - Run `CreateAuthTables.migrate_async()` on first startup
-
-### 6.3 IoC Registration Example
-
-**In application startup code (e.g., main application entry point):**
-
-```vala
-using Inversion;
-using InvercargillSql;
-
-// Create and open database connection
-var db_path = Path.build_filename(Environment.get_user_data_dir(), "spry", "authentication.db");
-var connection = new Connection(db_path);
-yield connection.open_async();
-
-// Register in IoC container
-var container = new Container();
-container.register<Connection>(() => connection).as_singleton();
-container.register<UserRepository, SqlUserRepository>().as_singleton();
-container.register<SessionRepository, SqlSessionRepository>().as_singleton();
-container.register<UserService>().as_singleton();
-container.register<SessionService>().as_singleton();
-container.register<PermissionService>().as_singleton();
-
-// Run schema migration
-var migration = new Migrations.CreateAuthTables(connection);
-yield migration.migrate_async();
-```
-
-### 6.4 Data Migration Considerations
-
-If there is existing production data in Implexus:
-
-1. **Create a data migration script** that:
-   - Reads all users from Implexus
-   - Reads all sessions from Implexus
-   - Inserts them into the SQL tables
-   - Verifies data integrity
-
-2. **Migration script outline:**
-```vala
-public async void migrate_data_from_implexus_async(
-    Engine implexus_engine,
-    InvercargillSql.Connection sql_connection
-) throws Error {
-    // Migrate users
-    var users_path = new EntityPath("/spry/authentication/users");
-    var users_container = yield implexus_engine.get_entity_or_null_async(users_path);
-    
-    if (users_container != null) {
-        var children = yield users_container.get_children_async();
-        foreach (var child in children) {
-            if (child.entity_type == EntityType.DOCUMENT) {
-                var props = yield child.get_properties_async();
-                // Convert to User object and insert into SQL
-            }
-        }
-    }
-    
-    // Migrate sessions similarly
-}
-```
-
-### 6.5 Testing Strategy
-
-1. **Unit Tests for Repositories:**
-   - Test each repository method in isolation
-   - Use in-memory SQLite database for fast tests
-   - Test edge cases (null values, empty results, duplicates)
-
-2. **Integration Tests for Services:**
-   - Test UserService with SqlUserRepository
-   - Test SessionService with SqlSessionRepository
-   - Verify public API remains unchanged
-
-3. **Migration Tests:**
-   - Test schema creation on fresh database
-   - Test idempotency (running migration twice)
-   - Test data migration from Implexus (if applicable)
-
-4. **Performance Tests:**
-   - Benchmark user lookup by username
-   - Benchmark session listing by user
-   - Compare with Implexus performance
-
----
-
-## 7. Files Summary
-
-### 7.1 New Files to Create
-
-| File | Purpose |
-|------|---------|
-| `src/Authentication/Repositories/UserRepository.vala` | User repository interface |
-| `src/Authentication/Repositories/SessionRepository.vala` | Session repository interface |
-| `src/Authentication/Repositories/SqlUserRepository.vala` | SQLite user repository implementation |
-| `src/Authentication/Repositories/SqlSessionRepository.vala` | SQLite session repository implementation |
-| `src/Authentication/Migrations/CreateAuthTables.vala` | SQL schema migration |
-
-### 7.2 Files to Modify
-
-| File | Changes |
-|------|---------|
-| [`meson.build`](../meson.build) | Add `invercargill_sql_dep` dependency |
-| [`src/Authentication/meson.build`](../src/Authentication/meson.build) | Update sources and dependencies |
-| [`src/Authentication/UserService.vala`](../src/Authentication/UserService.vala) | Replace Implexus with repository |
-| [`src/Authentication/SessionService.vala`](../src/Authentication/SessionService.vala) | Replace Implexus with repository |
-
-### 7.3 Files to Delete
-
-| File | Reason |
-|------|--------|
-| [`src/Authentication/AuthenticationMigration.vala`](../src/Authentication/AuthenticationMigration.vala) | Replaced by SQL migration |
-
----
-
-## 8. Risk Mitigation
-
-| Risk | Mitigation |
-|------|------------|
-| Breaking existing API | Repository pattern isolates changes; public service APIs unchanged |
-| Data loss during migration | Create backup before migration; implement data migration script |
-| Performance regression | SQL indexes replicate catalogue performance; benchmark critical paths |
-| Async behavior differences | Both use async/await; InvercargillSql uses thread-based async (transparent) |
-| Missing features in InvercargillSql | Verify API coverage before starting; implement workarounds if needed |
-
----
-
-## 9. Verification Checklist
-
-After implementation, verify:
-
-- [ ] All existing tests pass
-- [ ] User CRUD operations work correctly
-- [ ] Session CRUD operations work correctly
-- [ ] Username/email uniqueness is enforced
-- [ ] Permissions are correctly stored and retrieved
-- [ ] App data is correctly stored and retrieved
-- [ ] Expired sessions are cleaned up
-- [ ] Foreign key constraints work (deleting user deletes sessions)
-- [ ] Build completes without errors
-- [ ] No Implexus references remain in Authentication module

+ 0 - 406
plans/response-state-design.md

@@ -1,406 +0,0 @@
-# Response State Design for Spry Components
-
-## Problem Statement
-
-Authentication works correctly (user is found, password verified), but:
-1. **Cookie is not being set** - The `Set-Cookie` header is set on a discarded `HttpResult`
-2. **Redirect is not happening** - `hx-redirect` is set as an HTML attribute instead of an HTTP header
-
-### Root Cause Analysis
-
-#### Root Cause #1: Cookie Set on Discarded HttpResult
-
-```mermaid
-sequenceDiagram
-    participant CE as ComponentEndpoint
-    participant C as Component
-    participant SS as SessionService
-    
-    CE->>C: handle_action - login
-    C->>C: to_result - creates HttpResult A
-    C->>SS: set_session_cookie - Result A, token
-    SS->>SS: result.set_header - Set-Cookie on A
-    Note over C: Result A is discarded - async void!
-    C-->>CE: void return
-    CE->>C: to_result - creates NEW HttpResult B
-    C-->>CE: Result B - no cookie!
-```
-
-The problem: `handle_action()` is `async void` - it cannot return an `HttpResult`. The cookie is set on a temporary result that gets discarded.
-
-#### Root Cause #2: HTML Attribute vs HTTP Header
-
-```vala
-// WRONG - This sets an HTML attribute
-this[login-form].set_attribute(hx-redirect, redirect_url);
-
-// CORRECT - This sets an HTTP response header
-result.set_header(HX-Redirect, redirect_url);
-```
-
-HTMX requires `HX-Redirect` as an **HTTP response header**, not an HTML attribute.
-
----
-
-## Proposed Solution: ResponseState
-
-### Design Overview
-
-Add a `ResponseState` class that components use to accumulate response modifications during action handling. The state is then applied when `to_result()` creates the final `HttpResult`.
-
-```mermaid
-sequenceDiagram
-    participant CE as ComponentEndpoint
-    participant C as Component
-    participant RS as ResponseState
-    participant SS as SessionService
-    
-    CE->>C: handle_action - login
-    C->>RS: add_header - Set-Cookie, token
-    C->>RS: redirect - /dashboard
-    C-->>CE: void return - state accumulated
-    CE->>C: to_result
-    C->>C: create HttpResult
-    C->>RS: apply_to - result
-    RS->>C: result.set_header - Set-Cookie
-    RS->>C: result.set_header - HX-Redirect
-    C-->>CE: Result with headers!
-```
-
-### Key Components
-
-#### 1. ResponseState Class
-
-A new class to hold response modifications:
-
-```vala
-namespace Spry {
-
-    /**
-     * Redirect type for component responses.
-     */
-    public enum RedirectType {
-        /** Client-side redirect using HX-Redirect header - default for HTMX */
-        CLIENT_SIDE,
-        /** HTTP 302 temporary redirect using Location header */
-        TEMPORARY,
-        /** HTTP 301 permanent redirect using Location header */
-        PERMANENT
-    }
-
-    /**
-     * Holds response state that will be applied to the final HttpResult.
-     * 
-     * Components can modify this during action handling to influence
-     * the HTTP response without needing to return an HttpResult directly.
-     */
-    public class ResponseState : GLib.Object {
-        
-        // Headers to add to the response
-        private HashTable<string, string> _headers;
-        
-        // HTTP status code override
-        private StatusCode? _status_code = null;
-        
-        // Redirect configuration
-        private string? _redirect_url = null;
-        private RedirectType _redirect_type = RedirectType.CLIENT_SIDE;
-        
-        /**
-         * Adds a header to the response.
-         * If the header already exists, it will be replaced.
-         */
-        public void set_header(string name, string value) { ... }
-        
-        /**
-         * Adds a header to the response.
-         * Multiple headers with the same name can be added.
-         */
-        public void add_header(string name, string value) { ... }
-        
-        /**
-         * Sets the HTTP status code for the response.
-         */
-        public void set_status(StatusCode status) { ... }
-        
-        /**
-         * Sets up a redirect.
-         * Default type is CLIENT_SIDE which uses HX-Redirect header.
-         */
-        public void redirect(string url, RedirectType type = RedirectType.CLIENT_SIDE) { ... }
-        
-        /**
-         * Applies all accumulated state to an HttpResult.
-         * Called internally by Component.to_result().
-         */
-        internal void apply_to(HttpResult result) { ... }
-        
-        /**
-         * Clears all accumulated state.
-         * Called after to_result() to prepare for next request.
-         */
-        internal void reset() { ... }
-    }
-}
-```
-
-#### 2. Component Changes
-
-Add `ResponseState` property and convenience methods to the base `Component` class:
-
-```vala
-public abstract class Component : Object, Renderable {
-    
-    // Response state for action handlers
-    private ResponseState _response_state = new ResponseState();
-    
-    /**
-     * The response state for this component.
-     * Modify during handle_action to influence the HTTP response.
-     */
-    public ResponseState response { get { return _response_state; } }
-    
-    // Convenience methods that delegate to response_state:
-    
-    /**
-     * Adds a header to the response.
-     */
-    protected void set_header(string name, string value) {
-        _response_state.set_header(name, value);
-    }
-    
-    /**
-     * Sets the HTTP status code.
-     */
-    protected void set_status(StatusCode status) {
-        _response_state.set_status(status);
-    }
-    
-    /**
-     * Sets up a redirect.
-     * Default type is CLIENT_SIDE which uses HX-Redirect header.
-     */
-    protected void redirect(string url, RedirectType type = RedirectType.CLIENT_SIDE) {
-        _response_state.redirect(url, type);
-    }
-    
-    // Modified to_result():
-    public async HttpResult to_result() throws Error {
-        var document = yield to_document();
-        var result = document.to_result(get_status());
-        
-        // Apply accumulated response state
-        _response_state.apply_to(result);
-        
-        // Reset state for next request
-        _response_state.reset();
-        
-        return result;
-    }
-}
-```
-
----
-
-## Usage Examples
-
-### Example 1: Login with Cookie and Redirect
-
-```vala
-public class LoginFormComponent : Component {
-    
-    private SessionService _session_service = inject<SessionService>();
-    
-    public override async void handle_action(string action) throws Error {
-        if (action == "login") {
-            yield handle_login();
-        }
-    }
-    
-    private async void handle_login() throws Error {
-        // ... authenticate user ...
-        
-        // Create session
-        var session = yield _session_service.create_session_async(user.id);
-        var token = _session_service.generate_session_token(session);
-        
-        // Set cookie using convenience method
-        var cookie_value = @"spry_session=$token; Path=/; Max-Age=86400; HttpOnly; Secure; SameSite=Strict";
-        set_header("Set-Cookie", cookie_value);
-        
-        // Set up HTMX redirect
-        redirect("/dashboard");
-    }
-}
-```
-
-### Example 2: Unauthorized Response
-
-```vala
-public override async void handle_action(string action) throws Error {
-    if (!user_is_admin) {
-        set_status(StatusCode.UNAUTHORIZED);
-        error_message = "Admin access required";
-        return;
-    }
-    // ... handle action ...
-}
-```
-
-### Example 3: HTTP 302 Redirect
-
-```vala
-public override async void handle_action(string action) throws Error {
-    if (action == "logout") {
-        // Clear session
-        yield _session_service.delete_session_async(session_id);
-        
-        // HTTP redirect to login page
-        redirect("/login", RedirectType.TEMPORARY);
-    }
-}
-```
-
-### Example 4: Custom Headers
-
-```vala
-public override async void handle_action(string action) throws Error {
-    // Set custom response headers
-    set_header("X-Custom-Header", "value");
-    set_header("Cache-Control", "no-cache");
-    
-    // Multiple Set-Cookie headers
-    add_header("Set-Cookie", "pref=dark; Path=/");
-    add_header("Set-Cookie", "lang=en; Path=/");
-}
-```
-
----
-
-## Implementation Details
-
-### Header Accumulation Strategy
-
-Headers use a `HashTable<string, string>` with the following behavior:
-- `set_header()`: Replaces existing header with same name
-- `add_header()`: Appends to header list - for headers that can appear multiple times like `Set-Cookie`
-
-### Redirect Implementation
-
-The `apply_to()` method handles redirects:
-
-```vala
-internal void apply_to(HttpResult result) {
-    // Apply headers first
-    foreach (var header in _headers) {
-        result.set_header(header.key, header.value);
-    }
-    
-    // Handle redirect
-    if (_redirect_url != null) {
-        switch (_redirect_type) {
-            case RedirectType.CLIENT_SIDE:
-                result.set_header("HX-Redirect", _redirect_url);
-                break;
-            case RedirectType.TEMPORARY:
-                result.set_header("Location", _redirect_url);
-                result.set_status(StatusCode.FOUND); // 302
-                break;
-            case RedirectType.PERMANENT:
-                result.set_header("Location", _redirect_url);
-                result.set_status(StatusCode.MOVED_PERMANENTLY); // 301
-                break;
-        }
-    }
-    
-    // Apply status code if set - redirects may override this
-    if (_status_code != null && _redirect_url == null) {
-        result.set_status(_status_code);
-    }
-}
-```
-
-### Interaction with get_status()
-
-The existing `get_status()` virtual method continues to work for initial page renders. `ResponseState` status only applies when set during action handling.
-
-Priority order:
-1. Redirect status (301/302) if redirect is set
-2. ResponseState status if set
-3. `get_status()` return value
-
----
-
-## Files to Modify
-
-| File | Changes |
-|------|---------|
-| `src/ResponseState.vala` | **NEW** - ResponseState class |
-| `src/Component.vala` | Add ResponseState property, convenience methods, modify to_result |
-| `src/Users/Components/LoginFormComponent.vala` | Use new API for cookie and redirect |
-| `src/Users/SessionService.vala` | May need minor updates for cookie helper |
-| `src/meson.build` | Add ResponseState.vala to build |
-
----
-
-## API Summary
-
-### New Classes
-
-- `Spry.ResponseState` - Holds response modifications
-- `Spry.RedirectType` - Enum for redirect types
-
-### Component Additions
-
-| Method | Description |
-|--------|-------------|
-| `response` | Property to access ResponseState |
-| `set_header(name, value)` | Set a response header |
-| `add_header(name, value)` | Add a response header |
-| `set_status(status)` | Set HTTP status code |
-| `redirect(url, type)` | Redirect with optional type - default is CLIENT_SIDE |
-
-### ResponseState Methods
-
-| Method | Description |
-|--------|-------------|
-| `set_header(name, value)` | Set/replace a header |
-| `add_header(name, value)` | Add a header |
-| `set_status(status)` | Set status code |
-| `redirect(url, type)` | Redirect with optional type - default is CLIENT_SIDE |
-| `has_modifications()` | Check if any state is set |
-
----
-
-## Questions for Consideration
-
-1. **Should headers be accumulated or replaced by default?**
-   - Current design: `set_header` replaces, `add_header` appends
-   - Alternative: Always accumulate, provide `replace_header` for explicit replacement
-
-2. **Should there be a distinction between HTMX redirects and HTTP redirects?**
-   - Current design: Yes, via `RedirectType` enum
-   - Default is HTMX redirect since Spry is HTMX-focused
-
-3. **How should this interact with prepare and to_result?**
-   - Current design: State is applied in `to_result()`, then reset
-   - Alternative: Apply in `ComponentEndpoint` after `to_result()`
-
-4. **Should there be convenience methods like set_cookie?**
-   - Could add `set_cookie(name, value, options)` helper
-   - Would encapsulate cookie formatting logic
-
-5. **What happens if both redirect and status are set?**
-   - Current design: Redirect takes precedence for status code
-   - Headers are still applied
-
----
-
-## Next Steps
-
-1. Review and approve this design
-2. Implement `ResponseState.vala`
-3. Modify `Component.vala` to integrate ResponseState
-4. Update `LoginFormComponent.vala` to use new API
-5. Test login flow with cookie and redirect
-6. Update documentation

+ 0 - 804
plans/user-management-component-redesign.md

@@ -1,804 +0,0 @@
-# User Management Component Redesign
-
-## Executive Summary
-
-This document outlines the redesign of the Spry Authentication user management components. The redesign focuses on:
-1. Converting `UserManagementPage` to `UserManagementComponent` for better placement control
-2. Removing all CSS classes to avoid conflicts with application-defined styles
-3. Implementing an HTML5 `<details>`/`<summary>` pattern for user display
-4. Using separate view/edit components that swap via HTMX for cleaner separation
-5. Integrating permission editing directly into the edit component (removing standalone `PermissionEditorComponent`)
-
----
-
-## Current Implementation Overview
-
-### Component Hierarchy
-
-```mermaid
-graph TD
-    A[UserManagementPage - PageComponent] --> B[UserListComponent]
-    A --> C[UserFormComponent]
-    B --> D[UserListItemComponent - per user]
-    C --> E[PermissionEditorComponent]
-```
-
-### Current Components
-
-| Component | Type | Purpose |
-|-----------|------|---------|
-| [`UserManagementPage`](src/Authentication/Components/UserManagementPage.vala) | PageComponent | Full HTML page with embedded CSS, permission check, orchestrates child components |
-| [`UserListComponent`](src/Authentication/Components/UserListComponent.vala) | Component | Table of users with search/pagination, creates UserListItemComponent per row |
-| [`UserListItemComponent`](src/Authentication/Components/UserListItemComponent.vala) | Component | Single table row with user info and action buttons |
-| [`UserFormComponent`](src/Authentication/Components/UserFormComponent.vala) | Component | Modal form for create/edit with validation |
-| [`PermissionEditorComponent`](src/Authentication/Components/PermissionEditorComponent.vala) | Component | Checkbox-based permission selection |
-
-### Current Issues
-
-1. **Tight Coupling to Page Structure**: `UserManagementPage` is a `PageComponent` that generates a full HTML document, limiting where it can be placed
-2. **CSS Class Pollution**: Extensive use of CSS classes like `.admin-container`, `.btn`, `.modal-overlay`, `.spry-user-list` may conflict with application styles
-3. **Modal-Based Editing**: Separate modal form disrupts the flow and requires additional clicks
-4. **Complex Component Tree**: Five separate components increase maintenance burden
-
----
-
-## New Design
-
-### Component Hierarchy
-
-```mermaid
-graph TD
-    A[UserManagementComponent - Container] --> B[UserDetailsComponent - view mode per user]
-    A --> C[UserDetailEditComponent - edit mode swaps in]
-    A --> D[NewUserComponent - for creation]
-    C --> E[Integrated Permission Editing]
-    D --> E
-```
-
-### Simplified Component Structure
-
-| Component | Type | Purpose |
-|-----------|------|---------|
-| `UserManagementComponent` | Component | Container with header, new user button, user list outlet |
-| `UserDetailsComponent` | Component | View-only `<details>` element for displaying one user |
-| `UserDetailEditComponent` | Component | Edit mode `<details>` element with form fields and integrated permission editing |
-| `NewUserComponent` | Component | Create form using same pattern as edit, with integrated permission editing |
-
-### Key Changes
-
-1. **`UserManagementPage` → `UserManagementComponent`**:
-   - Changed from `PageComponent` to `Component`
-   - No longer generates full HTML document
-   - Application can place it anywhere
-
-2. **Separate View/Edit Components**:
-   - `UserDetailsComponent` handles read-only display
-   - `UserDetailEditComponent` handles editing (swapped in via HTMX)
-   - Clean separation of concerns - each component has a single responsibility
-
-3. **Remove `PermissionEditorComponent`**:
-   - Permission editing functionality integrated directly into `UserDetailEditComponent` and `NewUserComponent`
-   - Reduces component complexity and eliminates unnecessary abstraction
-
-4. **Remove `UserFormComponent`, `UserListComponent`, `UserListItemComponent`**:
-   - Functionality distributed among new focused components
-
----
-
-## HTML Structure Design
-
-### UserManagementComponent
-
-```html
-<div sid="user-management" id="user-management" hx-swap="outerHTML">
-    <script spry-res="htmx.js"></script>
-    
-    <!-- Header with Create Button -->
-    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
-        <h3 style="margin: 0;">Users</h3>
-        <button sid="create-btn" 
-                spry-action=":ShowCreateUser"
-                spry-target="user-management"
-                style="padding: 0.5rem 1rem; cursor: pointer;">
-            + Create User
-        </button>
-    </div>
-    
-    <!-- Success/Error Messages -->
-    <div spry-if="this.success_message != null" 
-         style="padding: 0.75rem; margin-bottom: 1rem; background: #d4edda; color: #155724; border-radius: 4px;">
-        <span content-expr="this.success_message"></span>
-    </div>
-    
-    <div spry-if="this.error_message != null"
-         style="padding: 0.75rem; margin-bottom: 1rem; background: #f8d7da; color: #721c24; border-radius: 4px;">
-        <span content-expr="this.error_message"></span>
-    </div>
-    
-    <!-- New User Form (conditionally visible) -->
-    <div spry-if="this.show_create_form" sid="new-user-container">
-        <spry-component name="Spry.Authentication.Components.NewUserComponent" sid="new-user"/>
-    </div>
-    
-    <!-- User List -->
-    <div sid="user-list" style="display: flex; flex-direction: column; gap: 0.5rem;">
-        <spry-outlet sid="users"/>
-    </div>
-</div>
-```
-
-### UserDetailsComponent - View Mode Only
-
-This component handles read-only display of a single user. When the user clicks "Edit", the entire component is swapped out for `UserDetailEditComponent`.
-
-```html
-<details sid="user-details"
-         id-expr="'user-' + this.user_id"
-         hx-swap="outerHTML"
-         open>
-    
-    <!-- Summary: Always visible, shows key info -->
-    <summary style="display: flex; align-items: center; gap: 1rem; padding: 0.75rem; background: #f8f9fa; border-radius: 4px; cursor: pointer;">
-        <span content-expr="this.username" style="font-weight: 500; min-width: 120px;"></span>
-        <span content-expr="this.email" style="color: #6c757d;"></span>
-        <span spry-if="this.permissions.length > 0" style="margin-left: auto; font-size: 0.85rem; color: #495057;">
-            <span content-expr="this.permissions.length"></span> permission(s)
-        </span>
-    </summary>
-    
-    <!-- Details: Visible when expanded - VIEW ONLY -->
-    <div style="padding: 1rem; border: 1px solid #e9ecef; border-top: none; border-radius: 0 0 4px 4px;">
-        <table style="width: 100%; border-collapse: collapse;">
-            <tbody>
-                <tr>
-                    <td style="padding: 0.5rem 0; font-weight: 500; width: 150px;">User ID</td>
-                    <td style="padding: 0.5rem 0;"><code content-expr="this.user_id"></code></td>
-                </tr>
-                <tr>
-                    <td style="padding: 0.5rem 0; font-weight: 500;">Username</td>
-                    <td style="padding: 0.5rem 0;"><span content-expr="this.username"></span></td>
-                </tr>
-                <tr>
-                    <td style="padding: 0.5rem 0; font-weight: 500;">Email</td>
-                    <td style="padding: 0.5rem 0;"><span content-expr="this.email"></span></td>
-                </tr>
-                <tr>
-                    <td style="padding: 0.5rem 0; font-weight: 500;">Created</td>
-                    <td style="padding: 0.5rem 0;"><span content-expr="this.created_at"></span></td>
-                </tr>
-                <tr>
-                    <td style="padding: 0.5rem 0; font-weight: 500; vertical-align: top;">Permissions</td>
-                    <td style="padding: 0.5rem 0;">
-                        <div style="display: flex; flex-wrap: wrap; gap: 0.25rem;">
-                            <spry-outlet sid="permission-badges"/>
-                        </div>
-                    </td>
-                </tr>
-            </tbody>
-        </table>
-        
-        <!-- View Mode Actions -->
-        <div style="display: flex; gap: 0.5rem; margin-top: 1rem;">
-            <button sid="edit-btn"
-                    spry-action=":StartEdit"
-                    spry-target="user-details"
-                    style="padding: 0.25rem 0.75rem; cursor: pointer; font-size: 0.875rem;">
-                Edit
-            </button>
-            <button sid="delete-btn"
-                    spry-action=":DeleteUser"
-                    spry-target="user-management"
-                    style="padding: 0.25rem 0.75rem; cursor: pointer; font-size: 0.875rem; background: #dc3545; color: white; border: none; border-radius: 4px;">
-                Delete
-            </button>
-        </div>
-    </div>
-</details>
-```
-
-### UserDetailEditComponent - Edit Mode with Integrated Permissions
-
-This component is swapped in when editing. It includes inline permission editing (no separate component).
-
-```html
-<details sid="user-details-edit"
-         id-expr="'user-' + this.user_id"
-         hx-swap="outerHTML"
-         open>
-    
-    <!-- Summary: Shows user being edited -->
-    <summary style="display: flex; align-items: center; gap: 1rem; padding: 0.75rem; background: #fff3cd; border-radius: 4px; cursor: pointer; border: 2px solid #ffc107;">
-        <span content-expr="this.username" style="font-weight: 500; min-width: 120px;"></span>
-        <span style="color: #856404; font-style: italic;">Editing...</span>
-    </summary>
-    
-    <!-- Edit Form -->
-    <div style="padding: 1rem; border: 2px solid #ffc107; border-top: none; border-radius: 0 0 4px 4px; background: #fffdf5;">
-        <form sid="edit-form"
-              spry-action=":SaveEdit"
-              spry-target="user-details-edit">
-            <input type="hidden" name="user_id" sid="user-id-input" value-expr="this.user_id"/>
-            
-            <table style="width: 100%; border-collapse: collapse;">
-                <tbody>
-                    <tr>
-                        <td style="padding: 0.5rem 0; font-weight: 500; width: 150px;">User ID</td>
-                        <td style="padding: 0.5rem 0;"><code content-expr="this.user_id"></code></td>
-                    </tr>
-                    <tr>
-                        <td style="padding: 0.5rem 0; font-weight: 500;">Username *</td>
-                        <td style="padding: 0.5rem 0;">
-                            <input type="text"
-                                   name="username"
-                                   sid="username-input"
-                                   required
-                                   minlength="3"
-                                   pattern="[a-zA-Z0-9_]+"
-                                   style="width: 100%; padding: 0.5rem; border: 1px solid #ced4da; border-radius: 4px;"
-                                   value-expr="this.username"/>
-                        </td>
-                    </tr>
-                    <tr>
-                        <td style="padding: 0.5rem 0; font-weight: 500;">Email *</td>
-                        <td style="padding: 0.5rem 0;">
-                            <input type="email"
-                                   name="email"
-                                   sid="email-input"
-                                   required
-                                   style="width: 100%; padding: 0.5rem; border: 1px solid #ced4da; border-radius: 4px;"
-                                   value-expr="this.email"/>
-                        </td>
-                    </tr>
-                    <tr>
-                        <td style="padding: 0.5rem 0; font-weight: 500;">New Password</td>
-                        <td style="padding: 0.5rem 0;">
-                            <input type="password"
-                                   name="new_password"
-                                   sid="password-input"
-                                   minlength="8"
-                                   placeholder="Leave blank to keep current"
-                                   style="width: 100%; padding: 0.5rem; border: 1px solid #ced4da; border-radius: 4px;"/>
-                            <small style="color: #6c757d;">Minimum 8 characters if changing</small>
-                        </td>
-                    </tr>
-                    
-                    <!-- Integrated Permission Editing -->
-                    <tr>
-                        <td style="padding: 0.5rem 0; font-weight: 500; vertical-align: top;">Permissions</td>
-                        <td style="padding: 0.5rem 0;">
-                            <!-- Common Permissions as Checkboxes -->
-                            <div style="margin-bottom: 0.75rem;">
-                                <div style="font-size: 0.85rem; color: #6c757d; margin-bottom: 0.25rem;">Common:</div>
-                                <div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_user-management" value="user-management"/>
-                                        User Management
-                                    </label>
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_user-create" value="user.create"/>
-                                        Create Users
-                                    </label>
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_user-read" value="user.read"/>
-                                        Read Users
-                                    </label>
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_user-update" value="user.update"/>
-                                        Update Users
-                                    </label>
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_user-delete" value="user.delete"/>
-                                        Delete Users
-                                    </label>
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_admin" value="admin"/>
-                                        Admin
-                                    </label>
-                                </div>
-                            </div>
-                            
-                            <!-- Custom Permissions -->
-                            <div>
-                                <div style="font-size: 0.85rem; color: #6c757d; margin-bottom: 0.25rem;">Custom Permissions:</div>
-                                <div sid="custom-perms" style="display: flex; flex-wrap: wrap; gap: 0.25rem; margin-bottom: 0.5rem;">
-                                    <spry-outlet sid="custom-permission-tags"/>
-                                </div>
-                                <div style="display: flex; gap: 0.25rem;">
-                                    <input type="text"
-                                           name="new_permission"
-                                           sid="new-perm-input"
-                                           placeholder="e.g., reports.view"
-                                           style="flex: 1; padding: 0.25rem 0.5rem; border: 1px solid #ced4da; border-radius: 4px; font-size: 0.875rem;"/>
-                                    <button type="button"
-                                            sid="add-perm-btn"
-                                            spry-action=":AddPermission"
-                                            spry-target="user-details-edit"
-                                            style="padding: 0.25rem 0.5rem; font-size: 0.875rem; cursor: pointer;">
-                                        Add
-                                    </button>
-                                </div>
-                            </div>
-                        </td>
-                    </tr>
-                </tbody>
-            </table>
-            
-            <!-- Error Message -->
-            <div spry-if="this.error_message != null"
-                 style="padding: 0.5rem; margin: 0.5rem 0; background: #f8d7da; color: #721c24; border-radius: 4px;">
-                <span content-expr="this.error_message"></span>
-            </div>
-            
-            <!-- Edit Actions -->
-            <div style="display: flex; gap: 0.5rem; margin-top: 1rem;">
-                <button type="submit" style="padding: 0.5rem 1rem; cursor: pointer;">Save Changes</button>
-                <button type="button"
-                        sid="cancel-btn"
-                        spry-action=":CancelEdit"
-                        spry-target="user-details-edit"
-                        style="padding: 0.5rem 1rem; cursor: pointer; background: #6c757d; color: white; border: none; border-radius: 4px;">
-                    Cancel
-                </button>
-            </div>
-        </form>
-    </div>
-</details>
-```
-
-### NewUserComponent - For Creating New Users
-
-Uses the same pattern as edit mode with integrated permission editing.
-
-```html
-<details sid="new-user"
-         id="new-user"
-         hx-swap="outerHTML"
-         open>
-    
-    <summary style="display: flex; align-items: center; gap: 1rem; padding: 0.75rem; background: #e7f3ff; border-radius: 4px; cursor: pointer; border: 2px dashed #007bff;">
-        <span style="font-weight: 500; color: #007bff;">+ New User</span>
-    </summary>
-    
-    <div style="padding: 1rem; border: 2px dashed #007bff; border-top: none; border-radius: 0 0 4px 4px; background: #f8faff;">
-        <form sid="create-form"
-              spry-action=":CreateUser"
-              spry-target="new-user">
-            
-            <table style="width: 100%; border-collapse: collapse;">
-                <tbody>
-                    <tr>
-                        <td style="padding: 0.5rem 0; font-weight: 500; width: 150px;">Username *</td>
-                        <td style="padding: 0.5rem 0;">
-                            <input type="text"
-                                   name="username"
-                                   sid="username-input"
-                                   required
-                                   minlength="3"
-                                   pattern="[a-zA-Z0-9_]+"
-                                   placeholder="Enter username"
-                                   style="width: 100%; padding: 0.5rem; border: 1px solid #ced4da; border-radius: 4px;"/>
-                            <small style="color: #6c757d;">Alphanumeric and underscores only, min 3 chars</small>
-                        </td>
-                    </tr>
-                    <tr>
-                        <td style="padding: 0.5rem 0; font-weight: 500;">Email *</td>
-                        <td style="padding: 0.5rem 0;">
-                            <input type="email"
-                                   name="email"
-                                   sid="email-input"
-                                   required
-                                   placeholder="Enter email address"
-                                   style="width: 100%; padding: 0.5rem; border: 1px solid #ced4da; border-radius: 4px;"/>
-                        </td>
-                    </tr>
-                    <tr>
-                        <td style="padding: 0.5rem 0; font-weight: 500;">Password *</td>
-                        <td style="padding: 0.5rem 0;">
-                            <input type="password"
-                                   name="password"
-                                   sid="password-input"
-                                   required
-                                   minlength="8"
-                                   placeholder="Enter password"
-                                   style="width: 100%; padding: 0.5rem; border: 1px solid #ced4da; border-radius: 4px;"/>
-                            <small style="color: #6c757d;">Minimum 8 characters</small>
-                        </td>
-                    </tr>
-                    
-                    <!-- Integrated Permission Editing (same as edit component) -->
-                    <tr>
-                        <td style="padding: 0.5rem 0; font-weight: 500; vertical-align: top;">Permissions</td>
-                        <td style="padding: 0.5rem 0;">
-                            <div style="margin-bottom: 0.75rem;">
-                                <div style="font-size: 0.85rem; color: #6c757d; margin-bottom: 0.25rem;">Common:</div>
-                                <div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_user-management" value="user-management"/>
-                                        User Management
-                                    </label>
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_user-create" value="user.create"/>
-                                        Create Users
-                                    </label>
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_user-read" value="user.read"/>
-                                        Read Users
-                                    </label>
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_user-update" value="user.update"/>
-                                        Update Users
-                                    </label>
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_user-delete" value="user.delete"/>
-                                        Delete Users
-                                    </label>
-                                    <label style="display: flex; align-items: center; gap: 0.25rem; font-size: 0.875rem;">
-                                        <input type="checkbox" name="perm_admin" value="admin"/>
-                                        Admin
-                                    </label>
-                                </div>
-                            </div>
-                            
-                            <div>
-                                <div style="font-size: 0.85rem; color: #6c757d; margin-bottom: 0.25rem;">Custom Permissions:</div>
-                                <div sid="custom-perms" style="display: flex; flex-wrap: wrap; gap: 0.25rem; margin-bottom: 0.5rem;">
-                                    <spry-outlet sid="custom-permission-tags"/>
-                                </div>
-                                <div style="display: flex; gap: 0.25rem;">
-                                    <input type="text"
-                                           name="new_permission"
-                                           sid="new-perm-input"
-                                           placeholder="e.g., reports.view"
-                                           style="flex: 1; padding: 0.25rem 0.5rem; border: 1px solid #ced4da; border-radius: 4px; font-size: 0.875rem;"/>
-                                    <button type="button"
-                                            sid="add-perm-btn"
-                                            spry-action=":AddPermission"
-                                            spry-target="new-user"
-                                            style="padding: 0.25rem 0.5rem; font-size: 0.875rem; cursor: pointer;">
-                                        Add
-                                    </button>
-                                </div>
-                            </div>
-                        </td>
-                    </tr>
-                </tbody>
-            </table>
-            
-            <!-- Error Message -->
-            <div spry-if="this.error_message != null"
-                 style="padding: 0.5rem; margin: 0.5rem 0; background: #f8d7da; color: #721c24; border-radius: 4px;">
-                <span content-expr="this.error_message"></span>
-            </div>
-            
-            <!-- Actions -->
-            <div style="display: flex; gap: 0.5rem; margin-top: 1rem;">
-                <button type="submit" style="padding: 0.5rem 1rem; cursor: pointer; background: #007bff; color: white; border: none; border-radius: 4px;">
-                    Create User
-                </button>
-                <button type="button"
-                        sid="cancel-btn"
-                        spry-action=":CancelCreate"
-                        spry-target="user-management"
-                        style="padding: 0.5rem 1rem; cursor: pointer; background: #6c757d; color: white; border: none; border-radius: 4px;">
-                    Cancel
-                </button>
-            </div>
-        </form>
-    </div>
-</details>
-```
-
----
-
-## HTMX Attributes and Targets
-
-### Target Strategy
-
-All actions must properly target the correct DOM elements for HTMX swapping. The key insight is that view and edit components swap each other out using the same element ID:
-
-| Action | Source Component | Target | Swap | Result |
-|--------|------------------|--------|------|--------|
-| `:StartEdit` | UserDetailsComponent | `user-{user_id}` | outerHTML | Swaps in UserDetailEditComponent |
-| `:SaveEdit` | UserDetailEditComponent | `user-{user_id}` | outerHTML | Swaps in UserDetailsComponent - view |
-| `:CancelEdit` | UserDetailEditComponent | `user-{user_id}` | outerHTML | Swaps in UserDetailsComponent - view |
-| `:AddPermission` | UserDetailEditComponent | `user-{user_id}` | outerHTML | Re-renders edit component with new permission |
-| `:RemovePermission` | UserDetailEditComponent | `user-{user_id}` | outerHTML | Re-renders edit component without permission |
-| `:DeleteUser` | UserDetailsComponent | `user-management` | outerHTML | Refreshes entire user list |
-| `:CreateUser` | NewUserComponent | `user-management` | outerHTML | Refreshes list with new user added |
-| `:CancelCreate` | NewUserComponent | `user-management` | outerHTML | Hides create form |
-| `:ShowCreateUser` | UserManagementComponent | `user-management` | outerHTML | Shows NewUserComponent |
-
-### Global ID Strategy
-
-- `UserManagementComponent`: `id="user-management"` (static, for cross-component targeting)
-- `UserDetailsComponent`: `id="user-{user_id}"` (dynamic per user)
-- `UserDetailEditComponent`: `id="user-{user_id}"` (same ID - they swap each other)
-- `NewUserComponent`: `id="new-user"` (static)
-
-### Component Swap Flow Diagram
-
-```mermaid
-sequenceDiagram
-    participant U as User
-    participant UV as UserDetailsComponent - View
-    participant UE as UserDetailEditComponent - Edit
-    participant UM as UserManagementComponent
-    participant S as Server/Service
-    
-    Note over U,S: Edit Flow - Component Swap
-    U->>UV: Click Edit button
-    UV->>S: POST with :StartEdit action
-    S->>S: Create UserDetailEditComponent with user data
-    S->>UE: Return UserDetailEditComponent - swaps in at same ID
-    U->>UE: Modify fields, click Save
-    UE->>S: POST with :SaveEdit action
-    S->>S: Validate and save to UserService
-    S->>S: Create UserDetailsComponent with updated data
-    S->>UV: Return UserDetailsComponent - swaps back at same ID
-    
-    Note over U,S: Delete Flow
-    U->>UV: Click Delete button
-    UV->>S: POST with :DeleteUser action targeting user-management
-    S->>S: Delete user via UserService
-    S->>UM: Return refreshed UserManagementComponent
-    
-    Note over U,S: Create Flow
-    U->>UM: Click Create User button
-    UM->>S: POST with :ShowCreateUser action
-    S->>UM: Return UserManagementComponent with NewUserComponent
-    U->>UM: Fill form, click Create
-    UM->>S: POST with :CreateUser action targeting user-management
-    S->>S: Create user via UserService
-    S->>UM: Return refreshed UserManagementComponent without form
-```
-
----
-
-## Inline Editing Behavior
-
-### State Management
-
-Each `UserDetailsComponent` maintains its own editing state:
-
-```vala
-public class UserDetailsComponent : Component {
-    // State
-    private User _user;
-    public bool is_editing { get; private set; default = false; }
-    public string? error_message { get; private set; default = null; }
-    
-    // Exposed for template
-    public string user_id { get { return _user.id; } }
-    public string username { get { return _user.username; } }
-    public string email { get { return _user.email; } }
-    public string created_at { get { return _user.created_at.format("%Y-%m-%d"); } }
-    public string[] permissions { get { return _user.permissions; } }
-    
-    // Actions
-    public void start_edit() {
-        is_editing = true;
-        error_message = null;
-    }
-    
-    public void cancel_edit() {
-        is_editing = false;
-        error_message = null;
-    }
-}
-```
-
-### Edit Toggle Flow
-
-1. **View Mode** (default): Shows read-only table with Edit/Delete buttons
-2. **Click Edit**: Triggers `:StartEdit` action, sets `is_editing = true`, re-renders
-3. **Edit Mode**: Shows form inputs in table rows with Save/Cancel buttons
-4. **Save**: Validates input, calls UserService, on success sets `is_editing = false`
-5. **Cancel**: Sets `is_editing = false`, discards changes
-
----
-
-## New User Creation Pattern
-
-### Visibility Control
-
-The `UserManagementComponent` controls whether the create form is visible:
-
-```vala
-public class UserManagementComponent : Component {
-    public bool show_create_form { get; private set; default = false; }
-    public string? success_message { get; private set; default = null; }
-    public string? error_message { get; private set; default = null; }
-    
-    public async override void handle_action(string action) throws Error {
-        switch (action) {
-            case "ShowCreateUser":
-                show_create_form = true;
-                break;
-            case "CancelCreate":
-                show_create_form = false;
-                break;
-            case "CreateUser":
-                // Handled by NewUserDetailsComponent, but we refresh here
-                show_create_form = false;
-                success_message = "User created successfully";
-                yield refresh_users_async();
-                break;
-            case "DeleteUser":
-                // Handle delete, refresh list
-                yield handle_delete_async();
-                break;
-        }
-    }
-}
-```
-
-### Creation Flow
-
-1. User clicks "Create User" button in header
-2. `UserManagementComponent` sets `show_create_form = true`
-3. `NewUserDetailsComponent` renders at top of list with empty fields
-4. User fills in fields and clicks "Create User"
-5. On success: form hides, success message shows, user list refreshes
-6. On error: error message shows in form, form stays visible
-
----
-
-## CSS Removal Strategy
-
-### Before (CSS Classes)
-
-```html
-<div class="admin-container">
-    <div class="admin-header">
-        <h1>User Management</h1>
-        <button class="btn btn-primary">Create User</button>
-    </div>
-    <div class="alert alert-success">...</div>
-    <table class="user-table">...</table>
-</div>
-```
-
-### After (Inline Styles)
-
-```html
-<div style="max-width: 1200px; margin: 0 auto; padding: 1rem;">
-    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
-        <h3 style="margin: 0;">User Management</h3>
-        <button style="padding: 0.5rem 1rem; cursor: pointer;">Create User</button>
-    </div>
-    <div style="padding: 0.75rem; margin-bottom: 1rem; background: #d4edda; color: #155724; border-radius: 4px;">...</div>
-    <!-- Table uses minimal inline styles -->
-</div>
-```
-
-### Style Guidelines
-
-1. **Use minimal inline styles** only for essential layout
-2. **No class attributes** except for semantic purposes (not styling)
-3. **Prefer semantic HTML** (`<details>`, `<summary>`, `<table>`)
-4. **Use CSS custom properties** if the application wants to override defaults:
-   ```html
-   <div style="background: var(--spry-alert-success-bg, #d4edda);">
-   ```
-
----
-
-## API/Endpoint Requirements
-
-### No New Endpoints Required
-
-The redesign uses the existing Spry component action pattern:
-- Actions are handled within components via `handle_action()`
-- No new HTTP endpoints need to be created
-- Existing `UserService` and `PermissionService` methods are sufficient
-
-### Service Dependencies
-
-Components continue to use:
-- `UserService`: create_user_async, get_user_async, update_user_async, delete_user_async, list_users_async
-- `PermissionService`: set_permission_async, has_permission_by_id_async
-- `SessionService`: authenticate_request_async (for permission checks)
-- `ComponentFactory`: create child components
-
-### Potential Future Enhancements
-
-1. **Bulk Operations**: Add `delete_users_async(string[] ids)` for multi-select delete
-2. **Search API**: Add `search_users_async(string query)` to UserService for efficient searching
-3. **Audit Logging**: Add methods to track who changed what and when
-
----
-
-## Implementation Checklist
-
-### Files to Create
-
-- [ ] `src/Authentication/Components/UserManagementComponent.vala` - New container component
-- [ ] `src/Authentication/Components/UserDetailsComponent.vala` - View-only details/summary component
-- [ ] `src/Authentication/Components/UserDetailEditComponent.vala` - Edit mode with integrated permissions
-- [ ] `src/Authentication/Components/NewUserComponent.vala` - Create form with integrated permissions
-
-### Files to Modify
-
-- [ ] `src/Authentication/meson.build` - Add new component files, remove old ones
-- [ ] `examples/UsersExample.vala` - Update to use new component
-
-### Files to Deprecate/Remove
-
-- [ ] `src/Authentication/Components/UserManagementPage.vala` - Replace with UserManagementComponent
-- [ ] `src/Authentication/Components/UserListComponent.vala` - Merged into UserManagementComponent
-- [ ] `src/Authentication/Components/UserListItemComponent.vala` - Replaced by UserDetailsComponent
-- [ ] `src/Authentication/Components/UserFormComponent.vala` - Functionality moved to UserDetailEditComponent and NewUserComponent
-- [ ] `src/Authentication/Components/PermissionEditorComponent.vala` - Functionality integrated directly into edit/create components
-
----
-
-## Migration Guide for Applications
-
-### Before (using UserManagementPage)
-
-```vala
-// Register as a page - generates full HTML document
-application.add_transient<UserManagementPage>();
-application.add_endpoint<UserManagementPage>(new EndpointRoute("/admin/users"));
-```
-
-### After (using UserManagementComponent)
-
-```vala
-// Option 1: Use in your own PageComponent
-public class AdminPage : PageComponent {
-    public override string markup {
-        return """
-        <!DOCTYPE html>
-        <html>
-        <head>...</head>
-        <body>
-            <nav>...</nav>
-            <main>
-                <!-- Place component anywhere in your layout -->
-                <spry-component name="Spry.Authentication.Components.UserManagementComponent" sid="user-mgmt"/>
-            </main>
-        </body>
-        </html>
-        """;
-    }
-}
-
-// Option 2: Create a simple wrapper page
-public class UserAdminPage : PageComponent {
-    private ComponentFactory _factory = inject<ComponentFactory>();
-    
-    public override string markup {
-        return """
-        <!DOCTYPE html>
-        <html>
-        <head>
-            <title>User Management</title>
-            <script spry-res="htmx.js"></script>
-        </head>
-        <body>
-            <spry-outlet sid="content"/>
-        </body>
-        </html>
-        """;
-    }
-    
-    public override async void prepare() throws Error {
-        var component = _factory.create<UserManagementComponent>();
-        add_outlet_child("content", component);
-        add_globals_from(component);
-    }
-}
-```
-
----
-
-## Summary
-
-This redesign simplifies the user management component architecture from 5 components to 3, removes all CSS class dependencies, and implements a modern `<details>`/`<summary>` pattern with inline editing. The key benefits are:
-
-1. **Flexibility**: Applications can place `UserManagementComponent` anywhere in their layout
-2. **No Style Conflicts**: Inline styles avoid CSS class collisions
-3. **Better UX**: Inline editing is more intuitive than modal forms
-4. **Maintainability**: Fewer components with clearer responsibilities
-5. **Consistency**: Same editable table pattern for both editing and creating

+ 122 - 0
src/Actions/AlterUserAction.vala

@@ -0,0 +1,122 @@
+using Statum;
+
+namespace Spry.Actions {
+
+	/**
+	 * Rewrites the profile of the user targeted by the sealed private data
+	 * ({@link UserActionPrivate}.`user_id`, falling back to the `user_id`
+	 * form field when no blob was sent) from the `username`, `email`,
+	 * `forename`, `surname`, `date_of_birth` (YYYY-MM-DD) and `enabled` form
+	 * fields (the profile fields are validated by the shared {@link
+	 * ProfileValidation}), optionally setting a new password when a
+	 * non-empty `new_password` field is supplied. Refuses to alter the
+	 * invoking admin's own account (self-disable/self-rename would break
+	 * their session and password-change lookup). Admin-guarded.
+	 */
+	public class AlterUserAction : UserManagementAction {
+
+		/** Notification shown when no `user_id` was supplied. */
+		protected virtual string user_required_message { get { return "A user id is required."; } }
+
+		/** Notification shown when the admin targets their own account. */
+		protected virtual string self_alter_message { get { return "You cannot alter your own account."; } }
+
+		/** Notification shown when the username is too short. */
+		protected virtual string username_too_short_message { get { return "Username must be at least 3 characters"; } }
+
+		/** Notification shown when the email address is malformed. */
+		protected virtual string invalid_email_message { get { return "Please enter a valid email address"; } }
+
+		/** Notification shown when the forename/surname fields are empty. */
+		protected virtual string name_required_message { get { return "Please enter your first and last name"; } }
+
+		/** Notification shown when no date of birth was entered. */
+		protected virtual string date_of_birth_required_message { get { return "Please enter your date of birth"; } }
+
+		/** Notification shown when the date of birth is malformed. */
+		protected virtual string invalid_date_of_birth_message { get { return "Please enter a valid date of birth (YYYY-MM-DD)"; } }
+
+		/** Notification shown when the new password is too short. */
+		protected virtual string password_too_short_message { get { return "Password must be at least 6 characters"; } }
+
+		/** Notification shown when the username is already taken. */
+		protected virtual string duplicate_username_message { get { return "Username already exists. Please choose another."; } }
+
+		/** Notification shown when the email is already registered. */
+		protected virtual string duplicate_email_message { get { return "Email already registered. Please login instead."; } }
+
+		/** Notification shown when another uniqueness constraint fired. */
+		protected virtual string duplicate_user_message { get { return "A user with this information already exists."; } }
+
+		/** Notification shown after a successful update. */
+		protected virtual string user_updated_message { get { return "User updated."; } }
+
+		/** Notification template (`%s` = error message) for storage failures. */
+		protected virtual string update_failed_message { get { return "Could not update the user: %s"; } }
+
+		public override async DirectiveBuilder handle() throws GLib.Error {
+			var guard = yield require_permission_guard();
+			if (guard != null) {
+				return (!)guard;
+			}
+
+			string enabled_text = "";
+			string new_password = "";
+			if (request.form != null) {
+				enabled_text = request.form.get_field("enabled") ?? "";
+				new_password = request.form.get_field("new_password") ?? "";
+			}
+
+			int64 user_id = target_user_id();
+			if (user_id == 0) {
+				return directives().notify("error", user_required_message);
+			}
+			if (SpryAuth.current(request).user_id == user_id) {
+				return directives().notify("error", self_alter_message);
+			}
+
+			ProfileValidation.Rejection rejection;
+			var fields = ProfileValidation.validate(request, out rejection);
+			if (fields == null) {
+				return directives().notify("error", rejection_message(rejection));
+			}
+			var profile = (!)fields;
+
+			if (new_password.length > 0 && new_password.length < 6) {
+				return directives().notify("error", password_too_short_message);
+			}
+
+			bool enabled = enabled_text.down() == "on" || enabled_text.down() == "true" || enabled_text.down() == "1";
+			try {
+				yield users.alter_user(user_id, profile.username, profile.email, profile.forename, profile.surname, profile.date_of_birth, enabled);
+				if (new_password.length > 0) {
+					yield users.set_password(user_id, new_password.dup());
+				}
+				return directives().notify("success", user_updated_message);
+			} catch (Error e) {
+				var duplicate = ProfileValidation.duplicate_message(e, duplicate_username_message, duplicate_email_message, duplicate_user_message);
+				if (duplicate != null) {
+					return directives().notify("error", (!)duplicate);
+				}
+				return directives().notify("error", update_failed_message.printf(e.message));
+			}
+		}
+
+		private string rejection_message(ProfileValidation.Rejection rejection) {
+			switch (rejection) {
+				case ProfileValidation.Rejection.USERNAME_TOO_SHORT:
+					return username_too_short_message;
+				case ProfileValidation.Rejection.INVALID_EMAIL:
+					return invalid_email_message;
+				case ProfileValidation.Rejection.NAME_REQUIRED:
+					return name_required_message;
+				case ProfileValidation.Rejection.DATE_OF_BIRTH_REQUIRED:
+					return date_of_birth_required_message;
+				case ProfileValidation.Rejection.INVALID_DATE_OF_BIRTH:
+				default:
+					return invalid_date_of_birth_message;
+			}
+		}
+	}
+
+}

+ 79 - 0
src/Actions/ChangePasswordAction.vala

@@ -0,0 +1,79 @@
+using Inversion;
+using Statum;
+using Spry.Authentication;
+
+namespace Spry.Actions {
+
+	/**
+	 * Changes the logged-in user's password from the `current_password`,
+	 * `new_password` and `confirm_password` form fields, verifying
+	 * `current_password` against the stored hash before anything is
+	 * written. Requires a live `auth` slot (guards via {@link
+	 * Spry.SpryAuth.require_login}, which re-validates the account
+	 * against the user store).
+	 */
+	public class ChangePasswordAction : StatumAction {
+
+		private UserService users = inject<UserService>();
+
+		/** URI navigated to when no `auth` slot is held. */
+		protected virtual string login_uri { get { return "/login"; } }
+
+		/** Notification shown when no current password was supplied. */
+		protected virtual string current_password_required_message { get { return "Your current password is required."; } }
+
+		/** Notification shown when the current password does not verify. */
+		protected virtual string current_password_invalid_message { get { return "Your current password is incorrect."; } }
+
+		/** Notification shown when the new password is too short. */
+		protected virtual string password_too_short_message { get { return "Password must be at least 6 characters."; } }
+
+		/** Notification shown when the password fields do not match. */
+		protected virtual string password_mismatch_message { get { return "Passwords do not match."; } }
+
+		/** Notification shown after a successful change. */
+		protected virtual string password_changed_message { get { return "Your password has been changed."; } }
+
+		/** Notification template (`%s` = error message) for storage failures. */
+		protected virtual string change_failed_message { get { return "Could not change password: %s"; } }
+
+		public override async DirectiveBuilder handle() throws GLib.Error {
+			var guard = yield SpryAuth.require_login(directives(), request, users, login_uri);
+			if (guard != null) {
+				return (!)guard;
+			}
+
+			string current_password = "";
+			string new_password = "";
+			string confirm = "";
+			if (request.form != null) {
+				current_password = request.form.get_field("current_password") ?? "";
+				new_password = request.form.get_field("new_password") ?? "";
+				confirm = request.form.get_field("confirm_password") ?? "";
+			}
+
+			if (current_password.length == 0) {
+				return directives().notify("error", current_password_required_message);
+			}
+			if (new_password.length < 6) {
+				return directives().notify("error", password_too_short_message);
+			}
+			if (new_password != confirm) {
+				return directives().notify("error", password_mismatch_message);
+			}
+
+			var me = SpryAuth.current(request);
+			try {
+				var existing = yield users.authenticate_user(me.username, current_password);
+				if (existing == null) {
+					return directives().notify("error", current_password_invalid_message);
+				}
+				yield users.set_password(me.user_id, new_password.dup());
+				return directives().notify("success", password_changed_message);
+			} catch (Error e) {
+				return directives().notify("error", change_failed_message.printf(e.message));
+			}
+		}
+	}
+
+}

+ 48 - 0
src/Actions/DeleteUserAction.vala

@@ -0,0 +1,48 @@
+using Statum;
+
+namespace Spry.Actions {
+
+	/**
+	 * Deletes the user targeted by the sealed private data ({@link
+	 * UserActionPrivate}.`user_id`, falling back to the `user_id` form field
+	 * when no blob was sent), refusing to delete the invoking admin's own
+	 * account (their `auth` slot would outlive the user row). Admin-guarded.
+	 */
+	public class DeleteUserAction : UserManagementAction {
+
+		/** Notification shown when no `user_id` was supplied. */
+		protected virtual string user_required_message { get { return "A user id is required."; } }
+
+		/** Notification shown when the admin targets their own account. */
+		protected virtual string self_delete_message { get { return "You cannot delete your own account."; } }
+
+		/** Notification shown after a successful delete. */
+		protected virtual string user_deleted_message { get { return "User deleted."; } }
+
+		/** Notification template (`%s` = error message) for storage failures. */
+		protected virtual string delete_failed_message { get { return "Could not delete the user: %s"; } }
+
+		public override async DirectiveBuilder handle() throws GLib.Error {
+			var guard = yield require_permission_guard();
+			if (guard != null) {
+				return (!)guard;
+			}
+
+			int64 user_id = target_user_id();
+			if (user_id == 0) {
+				return directives().notify("error", user_required_message);
+			}
+			if (SpryAuth.current(request).user_id == user_id) {
+				return directives().notify("error", self_delete_message);
+			}
+
+			try {
+				yield users.delete_user(user_id);
+				return directives().notify("success", user_deleted_message);
+			} catch (Error e) {
+				return directives().notify("error", delete_failed_message.printf(e.message));
+			}
+		}
+	}
+
+}

+ 57 - 0
src/Actions/GrantPermissionAction.vala

@@ -0,0 +1,57 @@
+using Statum;
+
+namespace Spry.Actions {
+
+	/**
+	 * Grants a permission to the user targeted by the sealed private data
+	 * ({@link UserActionPrivate}.`user_id`, falling back to the `user_id`
+	 * form field when no blob was sent); the permission comes from {@link
+	 * UserManagementAction.target_permission}. Idempotent — granting a
+	 * permission the user already holds succeeds without duplicating the
+	 * row. A missing target user is refused with the failure notification,
+	 * so a stale id cannot orphan a permission row. Admin-guarded.
+	 */
+	public class GrantPermissionAction : UserManagementAction {
+
+		/** Notification shown when no `user_id` was supplied. */
+		protected virtual string user_required_message { get { return "A user id is required."; } }
+
+		/** Notification shown when no permission was supplied. */
+		protected virtual string permission_required_message { get { return "A permission is required."; } }
+
+		/** Notification shown after a successful grant. */
+		protected virtual string permission_granted_message { get { return "Permission granted."; } }
+
+		/** Notification template (`%s` = error message) for storage failures. */
+		protected virtual string grant_failed_message { get { return "Could not grant the permission: %s"; } }
+
+		public override async DirectiveBuilder handle() throws GLib.Error {
+			var guard = yield require_permission_guard();
+			if (guard != null) {
+				return (!)guard;
+			}
+
+			int64 user_id = target_user_id();
+			if (user_id == 0) {
+				return directives().notify("error", user_required_message);
+			}
+
+			string permission = target_permission();
+			if (permission.length == 0) {
+				return directives().notify("error", permission_required_message);
+			}
+
+			try {
+				var target = yield users.get_user(user_id);
+				if (target == null) {
+					return directives().notify("error", grant_failed_message.printf(@"No user exists with id $(user_id)"));
+				}
+				yield users.set_user_permission(user_id, permission);
+				return directives().notify("success", permission_granted_message);
+			} catch (Error e) {
+				return directives().notify("error", grant_failed_message.printf(e.message));
+			}
+		}
+	}
+
+}

+ 43 - 0
src/Actions/LoginAction.vala

@@ -0,0 +1,43 @@
+using Inversion;
+using Statum;
+using Spry.Authentication;
+
+namespace Spry.Actions {
+
+	/**
+	 * Verifies the `username`/`password` form fields and establishes the
+	 * SESSION `auth` slot via {@link Spry.SpryAuth.login}, then navigates to
+	 * {@link landing_uri}.
+	 *
+	 * Unknown usernames and wrong passwords both answer the generic
+	 * {@link invalid_credentials_message} notify, so the response leaks no
+	 * account existence.
+	 */
+	public class LoginAction : StatumAction {
+
+		private UserService users = inject<UserService>();
+
+		/** URI navigated to after a successful login. */
+		protected virtual string landing_uri { get { return "/"; } }
+
+		/** Notification shown when the credentials do not match an account. */
+		protected virtual string invalid_credentials_message { get { return "Invalid username or password"; } }
+
+		public override async DirectiveBuilder handle() throws GLib.Error {
+			string username = "";
+			string password = "";
+			if (request.form != null) {
+				username = request.form.get_field("username") ?? "";
+				password = request.form.get_field("password") ?? "";
+			}
+
+			var user = yield users.authenticate_user(username, password);
+			if (user == null) {
+				return directives().notify("error", invalid_credentials_message);
+			}
+
+			return SpryAuth.login(directives(), (!)user, action_registry).navigate(landing_uri);
+		}
+	}
+
+}

+ 25 - 0
src/Actions/LogoutAction.vala

@@ -0,0 +1,25 @@
+using Statum;
+
+namespace Spry.Actions {
+
+	/**
+	 * Clears the held `auth` slot and navigates to {@link logged_out_uri}.
+	 * A reference to this action is embedded in the slot at login (see
+	 * {@link Spry.AuthPublic.logout}).
+	 */
+	public class LogoutAction : StatumAction {
+
+		/** URI navigated to after logging out. */
+		protected virtual string logged_out_uri { get { return "/"; } }
+
+		public override async DirectiveBuilder handle() throws GLib.Error {
+			HeldSlot auth;
+			if (request.held.try_get(SpryAuth.SLOT_TYPE, out auth) && auth != null) {
+				yield state_service.clear_slot(((!)auth).key);
+				return directives().clear(((!)auth).key).navigate(logged_out_uri);
+			}
+			return directives().navigate(logged_out_uri);
+		}
+	}
+
+}

+ 137 - 0
src/Actions/ProfileValidation.vala

@@ -0,0 +1,137 @@
+using Statum;
+
+namespace Spry.Actions {
+
+    /**
+     * Shared profile-field validation for {@link RegisterAction} and
+     * {@link AlterUserAction}: the single source of the `username`,
+     * `email`, `forename`, `surname` and `date_of_birth` (YYYY-MM-DD)
+     * checks and of the duplicate-row error mapping, so identical input
+     * yields identical outcomes from both actions. Actions map the
+     * results onto their own overridable notification messages.
+     */
+    public class ProfileValidation : Object {
+
+        /**
+         * Validates the shared profile fields read from `request`'s form:
+         * returns the parsed {@link Fields}, or `null` with {@link
+         * rejection} naming the first failed check. Impossible calendar
+         * dates (e.g. 31 February) are rejected by round-tripping the
+         * parsed date through GLib.
+         */
+        public static Fields? validate(StatumRequest request, out Rejection rejection) {
+            string username = "";
+            string email = "";
+            string forename = "";
+            string surname = "";
+            string date_of_birth_text = "";
+            if (request.form != null) {
+                username = (request.form.get_field("username") ?? "").strip();
+                email = (request.form.get_field("email") ?? "").strip();
+                forename = (request.form.get_field("forename") ?? "").strip();
+                surname = (request.form.get_field("surname") ?? "").strip();
+                date_of_birth_text = request.form.get_field("date_of_birth") ?? "";
+            }
+
+            rejection = Rejection.USERNAME_TOO_SHORT;
+            if (username.length < 3) {
+                return null;
+            }
+            rejection = Rejection.INVALID_EMAIL;
+            if (!email.contains("@") || !email.contains(".")) {
+                return null;
+            }
+            rejection = Rejection.NAME_REQUIRED;
+            if (forename.length == 0 || surname.length == 0) {
+                return null;
+            }
+
+            rejection = Rejection.DATE_OF_BIRTH_REQUIRED;
+            var date_parts = date_of_birth_text.split("-");
+            if (date_parts.length != 3) {
+                return null;
+            }
+            rejection = Rejection.INVALID_DATE_OF_BIRTH;
+            int year = int.parse(date_parts[0]);
+            int month = int.parse(date_parts[1]);
+            int day = int.parse(date_parts[2]);
+            if (year < 1900 || month < 1 || month > 12 || day < 1 || day > 31) {
+                return null;
+            }
+            DateTime? date_of_birth = new DateTime.utc(year, month, day, 0, 0, 0.0);
+            if (date_of_birth == null
+                || date_of_birth.get_year() != year
+                || date_of_birth.get_month() != month
+                || date_of_birth.get_day_of_month() != day) {
+                return null;
+            }
+
+            return new Fields(username, email, forename, surname, date_of_birth);
+        }
+
+        /**
+         * Maps a failed register/alter `e` onto a friendly duplicate
+         * notification: returns `null` when `e` is not a uniqueness
+         * failure, else whichever of `username_message`, `email_message`
+         * or `other_message` matches the constraint that fired (so no raw
+         * database error text leaks to the client).
+         */
+        public static string? duplicate_message(Error e, string username_message, string email_message, string other_message) {
+            string message = e.message;
+            if (!message.contains("UNIQUE constraint failed") && !message.contains("duplicate")) {
+                return null;
+            }
+            if (message.contains("username")) {
+                return username_message;
+            }
+            if (message.contains("email")) {
+                return email_message;
+            }
+            return other_message;
+        }
+
+        /** Why {@link validate} rejected the submitted profile fields. */
+        public enum Rejection {
+            /** The username is shorter than three characters. */
+            USERNAME_TOO_SHORT,
+            /** The email address contains no `@` or `.`. */
+            INVALID_EMAIL,
+            /** The forename or surname is empty. */
+            NAME_REQUIRED,
+            /** No date of birth was submitted. */
+            DATE_OF_BIRTH_REQUIRED,
+            /** The date of birth is malformed or an impossible calendar date. */
+            INVALID_DATE_OF_BIRTH
+        }
+
+        /**
+         * Parsed, validated profile fields ready for the user store;
+         * only created by {@link validate}.
+         */
+        public class Fields : Object {
+
+            /** The account's login name. */
+            public string username { get; private set; }
+
+            /** The account's email address. */
+            public string email { get; private set; }
+
+            /** The account's forename. */
+            public string forename { get; private set; }
+
+            /** The account's surname. */
+            public string surname { get; private set; }
+
+            /** The account's date of birth at UTC midnight. */
+            public DateTime date_of_birth { get; private set; }
+
+            internal Fields(string username, string email, string forename, string surname, DateTime date_of_birth) {
+                this.username = username;
+                this.email = email;
+                this.forename = forename;
+                this.surname = surname;
+                this.date_of_birth = date_of_birth;
+            }
+        }
+    }
+}

+ 109 - 0
src/Actions/RegisterAction.vala

@@ -0,0 +1,109 @@
+using Inversion;
+using Statum;
+using Spry.Authentication;
+
+namespace Spry.Actions {
+
+	/**
+	 * Registers a new account from the `username`, `email`, `forename`,
+	 * `surname`, `date_of_birth` (YYYY-MM-DD), `password` and
+	 * `confirm_password` form fields (the profile fields are validated by
+	 * the shared {@link ProfileValidation}), then notifies success and
+	 * navigates to {@link login_uri}. Every validation message is
+	 * overridable.
+	 */
+	public class RegisterAction : StatumAction {
+
+		private UserService users = inject<UserService>();
+
+		/** URI navigated to after a successful registration. */
+		protected virtual string login_uri { get { return "/login"; } }
+
+		/** Notification shown after a successful registration. */
+		protected virtual string account_created_message { get { return "Account created — you can now log in."; } }
+
+		/** Notification shown when the username is too short. */
+		protected virtual string username_too_short_message { get { return "Username must be at least 3 characters"; } }
+
+		/** Notification shown when the email address is malformed. */
+		protected virtual string invalid_email_message { get { return "Please enter a valid email address"; } }
+
+		/** Notification shown when the forename/surname fields are empty. */
+		protected virtual string name_required_message { get { return "Please enter your first and last name"; } }
+
+		/** Notification shown when no date of birth was entered. */
+		protected virtual string date_of_birth_required_message { get { return "Please enter your date of birth"; } }
+
+		/** Notification shown when the date of birth is malformed. */
+		protected virtual string invalid_date_of_birth_message { get { return "Please enter a valid date of birth (YYYY-MM-DD)"; } }
+
+		/** Notification shown when the password is too short. */
+		protected virtual string password_too_short_message { get { return "Password must be at least 6 characters"; } }
+
+		/** Notification shown when the password fields do not match. */
+		protected virtual string password_mismatch_message { get { return "Passwords do not match"; } }
+
+		/** Notification shown when the username is already taken. */
+		protected virtual string duplicate_username_message { get { return "Username already exists. Please choose another."; } }
+
+		/** Notification shown when the email is already registered. */
+		protected virtual string duplicate_email_message { get { return "Email already registered. Please login instead."; } }
+
+		/** Notification shown when another uniqueness constraint fired. */
+		protected virtual string duplicate_user_message { get { return "A user with this information already exists."; } }
+
+		/** Notification template (`%s` = error message) for storage failures. */
+		protected virtual string registration_failed_message { get { return "Registration failed: %s"; } }
+
+		public override async DirectiveBuilder handle() throws GLib.Error {
+			string password = "";
+			string confirm = "";
+			if (request.form != null) {
+				password = request.form.get_field("password") ?? "";
+				confirm = request.form.get_field("confirm_password") ?? "";
+			}
+
+			ProfileValidation.Rejection rejection;
+			var fields = ProfileValidation.validate(request, out rejection);
+			if (fields == null) {
+				return directives().notify("error", rejection_message(rejection));
+			}
+			var profile = (!)fields;
+
+			if (password.length < 6) {
+				return directives().notify("error", password_too_short_message);
+			}
+			if (password != confirm) {
+				return directives().notify("error", password_mismatch_message);
+			}
+
+			try {
+				yield users.register_user(profile.username, profile.email, profile.forename, profile.surname, profile.date_of_birth, password, true);
+				return directives().notify("success", account_created_message).navigate(login_uri);
+			} catch (Error e) {
+				var duplicate = ProfileValidation.duplicate_message(e, duplicate_username_message, duplicate_email_message, duplicate_user_message);
+				if (duplicate != null) {
+					return directives().notify("error", (!)duplicate);
+				}
+				return directives().notify("error", registration_failed_message.printf(e.message));
+			}
+		}
+
+		private string rejection_message(ProfileValidation.Rejection rejection) {
+			switch (rejection) {
+				case ProfileValidation.Rejection.USERNAME_TOO_SHORT:
+					return username_too_short_message;
+				case ProfileValidation.Rejection.INVALID_EMAIL:
+					return invalid_email_message;
+				case ProfileValidation.Rejection.NAME_REQUIRED:
+					return name_required_message;
+				case ProfileValidation.Rejection.DATE_OF_BIRTH_REQUIRED:
+					return date_of_birth_required_message;
+				case ProfileValidation.Rejection.INVALID_DATE_OF_BIRTH:
+				default:
+					return invalid_date_of_birth_message;
+			}
+		}
+	}
+
+}

+ 58 - 0
src/Actions/RevokePermissionAction.vala

@@ -0,0 +1,58 @@
+using Statum;
+
+namespace Spry.Actions {
+
+	/**
+	 * Revokes a single permission from the user targeted by the sealed
+	 * private data ({@link UserActionPrivate}.`user_id`, falling back to
+	 * the `user_id` form field when no blob was sent); the permission
+	 * comes from {@link UserManagementAction.target_permission}, and only
+	 * the matching rows are removed (the user's remaining permissions are
+	 * untouched). A missing target user is refused with the failure
+	 * notification rather than reporting an empty revoke as success.
+	 * Admin-guarded.
+	 */
+	public class RevokePermissionAction : UserManagementAction {
+
+		/** Notification shown when no `user_id` was supplied. */
+		protected virtual string user_required_message { get { return "A user id is required."; } }
+
+		/** Notification shown when no permission was supplied. */
+		protected virtual string permission_required_message { get { return "A permission is required."; } }
+
+		/** Notification shown after a successful revoke. */
+		protected virtual string permission_revoked_message { get { return "Permission revoked."; } }
+
+		/** Notification template (`%s` = error message) for storage failures. */
+		protected virtual string revoke_failed_message { get { return "Could not revoke the permission: %s"; } }
+
+		public override async DirectiveBuilder handle() throws GLib.Error {
+			var guard = yield require_permission_guard();
+			if (guard != null) {
+				return (!)guard;
+			}
+
+			int64 user_id = target_user_id();
+			if (user_id == 0) {
+				return directives().notify("error", user_required_message);
+			}
+
+			string permission = target_permission();
+			if (permission.length == 0) {
+				return directives().notify("error", permission_required_message);
+			}
+
+			try {
+				var target = yield users.get_user(user_id);
+				if (target == null) {
+					return directives().notify("error", revoke_failed_message.printf(@"No user exists with id $(user_id)"));
+				}
+				yield users.remove_user_permission(user_id, permission);
+				return directives().notify("success", permission_revoked_message);
+			} catch (Error e) {
+				return directives().notify("error", revoke_failed_message.printf(e.message));
+			}
+		}
+	}
+
+}

+ 51 - 0
src/Actions/SetUserEnabledAction.vala

@@ -0,0 +1,51 @@
+using Statum;
+
+namespace Spry.Actions {
+
+	/**
+	 * Enables or disables the user targeted by the sealed private data
+	 * ({@link UserActionPrivate}.`user_id`, falling back to the `user_id`
+	 * form field when no blob was sent), toggled by the `enabled` form field
+	 * (checkbox-style: the field is absent when unchecked). Admin-guarded.
+	 */
+	public class SetUserEnabledAction : UserManagementAction {
+
+		/** Notification shown when no `user_id` was supplied. */
+		protected virtual string user_required_message { get { return "A user id is required."; } }
+
+		/** Notification shown after enabling a user. */
+		protected virtual string user_enabled_message { get { return "User has been enabled."; } }
+
+		/** Notification shown after disabling a user. */
+		protected virtual string user_disabled_message { get { return "User has been disabled."; } }
+
+		/** Notification template (`%s` = error message) for storage failures. */
+		protected virtual string update_failed_message { get { return "Could not update the user: %s"; } }
+
+		public override async DirectiveBuilder handle() throws GLib.Error {
+			var guard = yield require_permission_guard();
+			if (guard != null) {
+				return (!)guard;
+			}
+
+			string enabled_text = "";
+			if (request.form != null) {
+				enabled_text = request.form.get_field("enabled") ?? "";
+			}
+
+			int64 user_id = target_user_id();
+			if (user_id == 0) {
+				return directives().notify("error", user_required_message);
+			}
+
+			bool enabled = enabled_text.down() == "on" || enabled_text.down() == "true" || enabled_text.down() == "1";
+			try {
+				yield users.set_user_enabled(user_id, enabled);
+				return directives().notify("success", enabled ? user_enabled_message : user_disabled_message);
+			} catch (Error e) {
+				return directives().notify("error", update_failed_message.printf(e.message));
+			}
+		}
+	}
+
+}

+ 21 - 0
src/Actions/UserActionPrivate.vala

@@ -0,0 +1,21 @@
+using Statum;
+
+namespace Spry.Actions {
+
+	/**
+	 * Private data sealed into the user-management row action references: the
+	 * target row's `user_id`, encrypted under the acting action's namespace
+	 * (see {@link UserManagementAction.private_namespace}) and decrypted by
+	 * the shipped actions themselves.
+	 *
+	 * Author references with
+	 * `action_registry.author_private<Spry.Actions.GrantPermissionAction, UserActionPrivate>(model)`
+	 * (likewise for the other management actions) — no app-side action
+	 * subclasses are required to consume the sealed id.
+	 */
+	public class UserActionPrivate : Object {
+
+		/** The `spry_users.id` of the user the action targets. */
+		public int64 user_id { get; set; }
+	}
+}

+ 78 - 0
src/Actions/UserManagementAction.vala

@@ -0,0 +1,78 @@
+using Inversion;
+using Statum;
+using Spry.Authentication;
+
+namespace Spry.Actions {
+
+	/**
+	 * Base for the admin-guarded user-management actions: holds the injected
+	 * {@link UserService} and the permission guard every management action
+	 * applies before touching the store, and resolves the targeted user from
+	 * sealed private data or the form.
+	 */
+	public abstract class UserManagementAction : StatumAction {
+
+		protected UserService users = inject<UserService>();
+
+		/**
+		 * Seals and reads this action's private blobs under the action's own
+		 * type name (mirroring `Statum.TypedStatumAction`), so a reference
+		 * authored with
+		 * `ActionRegistry.author_private<SetUserEnabledAction, UserActionPrivate>`
+		 * decrypts into `request.action_private`. Unlike typed actions the
+		 * blob is optional: {@link target_user_id} falls back to the
+		 * `user_id` form field when a request carries none.
+		 */
+		protected override string private_namespace { get { return this.get_type().name(); } }
+
+		/** Permission the invoking user must hold; `admin` matches everything. */
+		protected virtual string required_permission { get { return SpryAuth.ADMIN_PERMISSION; } }
+
+		/** URI navigated to when the invoking user is not permitted. */
+		protected virtual string unauthorised_uri { get { return "/login"; } }
+
+		/**
+		 * Returns `null` when the current user holds {@link
+		 * required_permission}, else the `navigate` builder to return.
+		 * Re-validates the session against the user store on every call
+		 * (see {@link Spry.SpryAuth.require_permission}).
+		 */
+		protected async DirectiveBuilder? require_permission_guard() {
+			return yield SpryAuth.require_permission(directives(), request, users, required_permission, unauthorised_uri);
+		}
+
+		/**
+		 * The id of the user this invocation targets: {@link
+		 * UserActionPrivate}.`user_id` from the decrypted private blob when
+		 * present, else the `user_id` form field, else 0.
+		 */
+		protected int64 target_user_id() {
+			var action_private = request.action_private;
+			if (action_private != null) {
+				try {
+					var priv = GObjectMapping.from_properties_typed<UserActionPrivate>(typeof(UserActionPrivate), action_private);
+					if (priv.user_id != 0) {
+						return priv.user_id;
+					}
+				} catch (GLib.Error e) {
+				}
+			}
+			if (request.form != null) {
+				return int64.parse(request.form.get_field("user_id") ?? "");
+			}
+			return 0;
+		}
+
+		/**
+		 * The permission this invocation targets: the `permission` form
+		 * field, stripped of surrounding whitespace ("" when absent).
+		 */
+		protected string target_permission() {
+			if (request.form != null) {
+				return (request.form.get_field("permission") ?? "").strip();
+			}
+			return "";
+		}
+	}
+
+}

+ 306 - 0
src/Auth.vala

@@ -0,0 +1,306 @@
+using Statum;
+using Spry.Authentication;
+
+namespace Spry {
+
+	/**
+	 * Public projection of the logged-in user, held in the {@link
+	 * SpryAuth.SLOT_TYPE} session slot.
+	 *
+	 * The whole slot is signed, so these fields are tamper-proof while staying
+	 * readable by the browser — bind them for nav displays and `stm-if` guards
+	 * (e.g. `auth.username`, `auth.permissions`).
+	 */
+	public class AuthPublic : Object {
+
+		/** The account's login name. */
+		public string username { get; set; default = ""; }
+
+		/** Human-friendly name (forename + surname, falling back to username). */
+		public string display_name { get; set; default = ""; }
+
+		/** Permission patterns granted at login; `admin` and `*` match everything. */
+		public string[] permissions { get; set; }
+
+		/** Reference to the registered {@link Actions.LogoutAction}, embedded at login. */
+		public Statum.Model.ActionDto? logout { get; set; }
+	}
+
+	/**
+	 * Server-only identity held in the {@link SpryAuth.SLOT_TYPE} slot's
+	 * encrypted private data. Never reaches the browser; the authoritative
+	 * user id lives here.
+	 */
+	public class AuthPrivate : Object {
+
+		/** The `spry_users.id` of the logged-in user. */
+		public int64 user_id { get; set; }
+	}
+
+	/**
+	 * Resolved identity for the current request, read from the held (signed)
+	 * `auth` slot rather than a cookie. Replaces the old Spry
+	 * `AuthorisationContext`. Reflects the slot snapshot minted at login —
+	 * the authoritative guards ({@link SpryAuth.require_login}, {@link
+	 * SpryAuth.require_permission}) re-validate against the user store.
+	 */
+	public class CurrentUser : Object {
+
+		/** The user's database id, or 0 when anonymous. */
+		public int64 user_id { get; private set; }
+
+		/** The user's login name, or "" when anonymous. */
+		public string username { get; private set; }
+
+		/** The user's display name, or "" when anonymous. */
+		public string display_name { get; private set; }
+
+		/** The user's permission patterns (may include wildcards). */
+		public string[] permissions { get; private set; }
+
+		/** True when no `auth` slot is held. */
+		public bool is_anonymous { get; private set; }
+
+		public CurrentUser() {
+			user_id = 0;
+			username = "";
+			display_name = "";
+			permissions = new string[0];
+			is_anonymous = true;
+		}
+
+		public CurrentUser.authenticated(int64 user_id, string username, string display_name, string[] permissions) {
+			this.user_id = user_id;
+			this.username = username;
+			this.display_name = display_name;
+			this.permissions = permissions;
+			is_anonymous = false;
+		}
+
+		/**
+		 * True when one of the user's permission patterns matches
+		 * `permission` (see {@link SpryAuth.permission_matches} for the
+		 * matching semantics).
+		 */
+		public bool has_permission(string permission) {
+			return SpryAuth.permission_matches(permissions, permission);
+		}
+	}
+
+	/**
+	 * Static helpers for slot-based authentication: resolving the current user,
+	 * establishing the `auth` slot, guard builders, admin seeding and action
+	 * registration. The ready-made {@link Spry.Actions} delegate here.
+	 */
+	public class SpryAuth : Object {
+
+		/** Slot type name of the authentication session slot. */
+		public const string SLOT_TYPE = "auth";
+
+		/** The super-user permission granted by {@link ensure_admin}. */
+		public const string ADMIN_PERMISSION = "admin";
+
+		/**
+		 * Resolves the current user from the held `auth` slot, or an
+		 * anonymous {@link CurrentUser} when no slot is held.
+		 *
+		 * This is the signed snapshot minted at login: cheap display
+		 * identity for nav bars, greetings and `stm-if` guards, but a
+		 * disabled, deleted or revoked account still resolves here until
+		 * its slot is cleared. Authorisation decisions must go through
+		 * {@link require_login} or {@link require_permission}, which
+		 * re-validate against the user store on every guarded request.
+		 */
+		public static CurrentUser current(StatumRequest request) {
+			HeldSlot slot;
+			if (!request.held.try_get(SLOT_TYPE, out slot) || slot == null) {
+				return new CurrentUser();
+			}
+
+			var pub = request.held_as<AuthPublic>(SLOT_TYPE);
+			AuthPrivate priv = null;
+			try {
+				priv = GObjectMapping.from_properties_typed<AuthPrivate>(typeof(AuthPrivate), ((!)slot).@private);
+			} catch (GLib.Error e) {
+				priv = null;
+			}
+
+			int64 user_id = priv != null ? priv.user_id : 0;
+			if (user_id == 0) {
+				return new CurrentUser();
+			}
+
+			string username = pub != null ? pub.username : "";
+			string display_name = pub != null ? pub.display_name : "";
+			string[] permissions = pub != null && pub.permissions != null ? pub.permissions : new string[0];
+			return new CurrentUser.authenticated(user_id, username, display_name, permissions);
+		}
+
+		/**
+		 * Establishes `user`'s identity: builds the SESSION `auth` slot (typed
+		 * public + private data, the private half encrypted) and chains its
+		 * `set` directive onto `directives`, embedding a {@link
+		 * Actions.LogoutAction} reference for client-side logout buttons.
+		 * Returns the builder for further chaining (e.g. `.navigate("/")`).
+		 */
+		public static DirectiveBuilder login(DirectiveBuilder directives, UserProjection user, ActionRegistry action_registry) throws GLib.Error {
+			var pub = new AuthPublic();
+			pub.username = user.username;
+			pub.display_name = display_name_for(user);
+			pub.permissions = user.permissions.to_array();
+			pub.logout = action_registry.author<Actions.LogoutAction>();
+
+			var priv = new AuthPrivate();
+			priv.user_id = user.id;
+
+			return directives.set_private_typed<AuthPublic, AuthPrivate>(SLOT_TYPE, Scope.SESSION, pub, priv);
+		}
+
+		/**
+		 * Guard for handlers that need a logged-in user: returns `null`
+		 * when the held `auth` slot maps to a live, enabled account, else a
+		 * builder navigating to `redirect`.
+		 *
+		 * The guard is authoritative — unlike {@link current}, it
+		 * re-validates the slot's user id against `users` on every call, so
+		 * disabling, deleting or revoking the account takes effect on the
+		 * next guarded request. A store failure fails closed (the request
+		 * is treated as anonymous) after logging a warning.
+		 */
+		public static async DirectiveBuilder? require_login(DirectiveBuilder directives, StatumRequest request, UserService users, string redirect = "/login") {
+			var user = yield revalidate(request, users);
+			if (user != null) {
+				return null;
+			}
+			return directives.navigate(redirect);
+		}
+
+		/**
+		 * Guard for handlers that need `permission`: returns `null` when
+		 * the current user still holds it, else a builder navigating to
+		 * `redirect`.
+		 *
+		 * Authoritative like {@link require_login}: the permission set is
+		 * re-derived from the user store on every call, so a revocation
+		 * takes effect on the next guarded request. A store failure fails
+		 * closed after logging a warning.
+		 */
+		public static async DirectiveBuilder? require_permission(DirectiveBuilder directives, StatumRequest request, UserService users, string permission, string redirect = "/login") {
+			var user = yield revalidate(request, users);
+			if (user != null && permission_matches(user.permissions.to_array(), permission)) {
+				return null;
+			}
+			return directives.navigate(redirect);
+		}
+
+		/**
+		 * True when one of `patterns` matches `permission`.
+		 *
+		 * Matching preserves the old `PermissionMatcher` semantics: `admin`
+		 * and `*` match everything, a trailing `*` matches any permission
+		 * with that prefix, and anything else requires an exact match.
+		 */
+		public static bool permission_matches(string[] patterns, string permission) {
+			foreach (string pattern in patterns) {
+				if (pattern == "admin" || pattern == "*") {
+					return true;
+				}
+				if (pattern.has_suffix("*")) {
+					if (permission.has_prefix(pattern.substring(0, pattern.length - 1))) {
+						return true;
+					}
+					continue;
+				}
+				if (pattern == permission) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		/**
+		 * Idempotent startup seeding: creates an enabled `username` account
+		 * when absent (looked up by username rather than a paged listing),
+		 * and grants it the {@link ADMIN_PERMISSION} permission when not
+		 * already held. Resolve a {@link Spry.Authentication.UserService}
+		 * from a startup scope and pass it in:
+		 *
+		 * ```
+		 * var scope = container.create_scope();
+		 * yield SpryAuth.ensure_admin(scope.resolve<UserService>(),
+		 *     "admin", "admin@example.com", "change-me");
+		 * ```
+		 */
+		public static async void ensure_admin(UserService users, string username, string email, string password) throws Error {
+			var existing = yield users.get_user_by_username(username);
+
+			int64 user_id;
+			if (existing != null) {
+				user_id = existing.id;
+			} else {
+				var admin = yield users.register_user(username, email, "Admin", "User",
+					new DateTime.utc(1980, 1, 1, 0, 0, 0.0), password, true);
+				user_id = admin.id;
+			}
+
+			bool granted = false;
+			foreach (var permission in yield users.get_user_permissions(user_id)) {
+				if (permission == ADMIN_PERMISSION) {
+					granted = true;
+					break;
+				}
+			}
+			if (!granted) {
+				yield users.set_user_permission(user_id, ADMIN_PERMISSION);
+			}
+		}
+
+		/**
+		 * Registers every shipped {@link Spry.Actions} action with `cfg` —
+		 * login, register, logout, change-password and the admin-guarded
+		 * user-management actions.
+		 */
+		public static void register_actions(StatumConfigurator cfg) {
+			cfg.action<Actions.LoginAction>();
+			cfg.action<Actions.RegisterAction>();
+			cfg.action<Actions.LogoutAction>();
+			cfg.action<Actions.ChangePasswordAction>();
+			cfg.action<Actions.SetUserEnabledAction>();
+			cfg.action<Actions.GrantPermissionAction>();
+			cfg.action<Actions.RevokePermissionAction>();
+			cfg.action<Actions.AlterUserAction>();
+			cfg.action<Actions.DeleteUserAction>();
+		}
+
+		private static string display_name_for(UserProjection user) {
+			var name = @"$(user.forename) $(user.surname)".strip();
+			return name.length > 0 ? name : user.username;
+		}
+
+		/**
+		 * Re-validates the held `auth` slot against the user store:
+		 * returns the live, enabled user for {@link AuthPrivate}.`user_id`,
+		 * or `null` when no slot is held, the account is missing or
+		 * disabled, or the store could not be reached (fail closed, with a
+		 * warning).
+		 */
+		private static async UserProjection? revalidate(StatumRequest request, UserService users) {
+			var me = current(request);
+			if (me.is_anonymous) {
+				return null;
+			}
+			try {
+				var user = yield users.get_user(me.user_id);
+				if (user == null || !user.enabled) {
+					return null;
+				}
+				return user;
+			} catch (Error e) {
+				warning(@"[Spry] could not re-validate the auth slot for user $(me.user_id): $(e.message)");
+				return null;
+			}
+		}
+
+	}
+
+}

+ 0 - 30
src/Authentication/AuthenticationModule.vala

@@ -1,30 +0,0 @@
-using InvercargillSqlInversion;
-using Inversion;
-
-namespace Spry.Authentication {
-
-    public class AuthenticationModule : Object, Module {
-
-        public void register_components (Inversion.Container container) throws Error {
-            // Sql table setup
-            var sql = container.configure_with<DatabaseConfigurator>();
-            sql.add_migration<Migrations.M0001_Initial>();
-            sql.add_entity<UserEntity>(UserEntity.entity_mapping);
-            sql.add_entity<UserPermissionEntity>(UserPermissionEntity.entity_mapping);
-            sql.add_projection<UserProjection> (UserProjection.projection_mapping);
-
-            // Service setup
-            container.register_scoped<UserService>();
-            container.register_scoped<UserIdentityProvider>()
-                .as<Authorisation.IdentityProvider>();
-
-            // Component setup
-            container.register_transient<LoginComponent>();
-            container.register_transient<UserComponent>();
-            container.register_transient<UserEditComponent>();
-            container.register_transient<UserManagementComponent>();
-        }
-
-    }
-
-}

+ 0 - 70
src/Authentication/Components/LoginComponent.vala

@@ -1,70 +0,0 @@
-using Astralis;
-using Inversion;
-
-namespace Spry.Authentication {
-
-    public class LoginComponent : Component {
-
-        public string redirect_url { get; set; default = "/"; }
-        public string error_message { get; set; }
-        public string username_prefill { get; set; }
-
-        public override string markup { get { return """
-        <spry-context property="redirect_url" />
-        <form
-          spry-action=":authenticate"
-          spry-method="post"
-          hx-disabled-elt="find input, find button"
-          hx-indicator="find button"
-          hx-swap="outerHTML"
-          style="display: grid; grid-template-columns: max-content auto; column-gap: 3em; row-gap: 1em; align-items: center">
-            <label for="username">Username</label>
-            <input type="text" placeholder="Enter Username" name="username" value-expr="this.username_prefill" required>
-
-            <label for="password">Password</label>
-            <input type="password" placeholder="Enter Password" name="password" required>
-            
-            <label style="grid-column: 2;">
-            <input type="checkbox" checked="checked" name="remember"> Remember me
-            </label>
-
-            <span 
-              spry-if="this.error_message.length > 0"
-              style="grid-column: span 2;"
-              class="error-text"
-              content-expr="this.error_message">
-            </span>
-
-            <button style="grid-column: span 2;" type="submit">Authenticate</button>
-        </form>
-        """; }}
-
-        private HttpContext http_context = inject<HttpContext>();
-        private UserService user_service = inject<UserService>();
-
-        public async override void handle_action (string action) throws Error {
-            if(action == "authenticate") {
-                yield authenticate();
-            }
-        }
-
-        private async void authenticate() throws Error {
-            // Extract the form 
-            var form = yield Astralis.FormDataParser.parse (http_context.request.request_body, http_context.request.content_type);
-            var username = form.get_field("username");
-            var password = form.get_field("password");
-
-            var token = yield user_service.authenticate_user(username, password);
-            if(token == null) {
-                error_message = "Invalid username or password";
-                username_prefill = username;
-                return;
-            }
-
-            response.set_authorisation_token (token);
-            response.redirect(redirect_url, RedirectType.CLIENT_SIDE);
-        }
-        
-    }
-
-}

+ 0 - 105
src/Authentication/Components/UserComponent.vala

@@ -1,105 +0,0 @@
-using Astralis;
-using Inversion;
-using InvercargillSql.Orm;
-using Invercargill.Expressions;
-
-namespace Spry.Authentication {
-
-    public class UserComponent : Component {
-
-        public int user_id { get; set; }
-        public bool edit { get; set; }
-        public UserProjection user { get; set; }
-        public bool expanded { get; set; }
-
-        public override string markup { get { return """
-        <spry-context property="user_id" />
-        <details sid="details" open-expr="this.expanded">
-            <summary>
-                <span content-expr="this.user.forename"></span>
-                <span content-expr="this.user.surname"></span>
-                <em content-expr='format("({{this.user.username}})")'></span>
-            </summary>
-            <div spry-if="!this.edit" style="display: grid; grid-template-columns: max-content auto; column-gap: 3em; row-gap: 0.25em;">
-                <strong>Username:</strong>
-                <span content-expr="this.user.username"></span>
-
-                <strong>Forename:</strong>
-                <span content-expr="this.user.forename"></span>
-
-                <strong>Surname:</strong>
-                <span content-expr="this.user.surname"></span>
-
-                <strong>Email Address:</strong>
-                <span content-expr="this.user.email"></span>
-
-                <strong>Date of Birth:</strong>
-                <span content-expr='this.user.date_of_birth.format("%d/%m/%Y")'></span>
-
-                <strong>Permissions:</strong>
-                <div style="display: flex; gap: 1em;">
-                    <code spry-per-permission="this.user.permissions" content-expr="permission"></code>
-                </div>
-
-                <div style="grid-column: 2; display: flex; gap: 1em;">
-                    <button 
-                      style="flex: 1"
-                      spry-target="details"
-                      hx-swap="outerHTML"
-                      spry-action=":edit">
-                        Edit User
-                    </button>
-                    <button 
-                      style="flex: 1"
-                      spry-if="this.user.enabled"
-                      hx-swap="outerHTML"
-                      spry-target="details"
-                      spry-action=":disable">
-                        Disable User
-                    </button>
-
-                    <button
-                      style="flex: 1"
-                      spry-else
-                      hx-swap="outerHTML"
-                      spry-target="details"
-                      spry-action=":enable">
-                        Enable User
-                    </button>
-                </div>
-            </div>
-            <spry-outlet sid="editor">
-        </details>
-        """; }}
-
-        private UserService user_service = inject<UserService>();
-        private ComponentFactory component_factory = inject<ComponentFactory>();
-        private OrmSession orm_session = inject<OrmSession>();
-
-        public async override void handle_action (string action) throws Error {
-            expanded = true;
-
-            if(action == "disable") {
-                yield user_service.set_user_enabled (user_id, false);
-            }
-            if(action == "enable") {
-                yield user_service.set_user_enabled (user_id, true);
-            }
-
-            user = yield orm_session.query<UserProjection>()
-                .where(expr("id == $0", elem<int64?>(user_id)))
-                .first_async();
-
-            if(action == "edit") {
-                edit = true;
-                var edit_component = component_factory.create<UserEditComponent>();
-                edit_component.user_id = user_id;
-                edit_component.user = user;
-                edit_component.username = user.username;
-
-                set_outlet_child ("editor", edit_component);
-            }
-        }
-    }
-
-}

+ 0 - 63
src/Authentication/Components/UserEditComponent.vala

@@ -1,63 +0,0 @@
-using Astralis;
-using Inversion;
-
-namespace Spry.Authentication {
-
-    public class UserEditComponent : Component {
-
-        public int user_id { get; set; }
-        public string username { get; set; }
-        public UserProjection user { get; set; }
-
-        public override string markup { get { return """
-        <spry-context property="user_id" />
-        <spry-context property="username" />
-        <form
-          spry-action=":save"
-          spry-method="post"
-          hx-disabled-elt="find input, find button"
-          hx-indicator="find button"
-          hx-swap="outerHTML"
-          style="display: grid; grid-template-columns: max-content auto; column-gap: 3em; row-gap: 1em;">
-            <label for="username">Username</label>
-            <input type="text" name="username" value-expr="this.user.username" disabled>
-
-            <label for="forename">Forename</label>
-            <input type="text" name="forename" value-expr="this.user.forename" required>
-
-            <label for="surname">Surname</label>
-            <input type="text" name="surname" value-expr="this.user.surname" required>
-
-            <label for="email">Email Address</label>
-            <input type="text" name="email" value-expr="this.user.email" required>
-
-            <label for="date_of_birth">Date of Birth</label>
-            <input type="date" name="date_of_birth" value-expr='this.user.date_of_birth.format("%Y-%m-%d")' required>
-
-            <label for="new_password">Password</label>
-            <input type="password" name="new_password" placeholder="Leave blank to keep unchanged">
-
-            <button style="grid-column: span 2;" type="submit">Save</button>
-        </form>
-        """; }}        
-
-        private UserService user_service = inject<UserService>();
-        private HttpContext http_context = inject<HttpContext>();
-
-        public async override void handle_action (string action) throws Error {
-            var form = yield Astralis.FormDataParser.parse (http_context.request.request_body, http_context.request.content_type);
-            var dob_strs = form.get_field ("date_of_birth").split("-");
-            var dob = new DateTime(new TimeZone.utc (), int.parse(dob_strs[0]), int.parse(dob_strs[1]), int.parse(dob_strs[2]), 0, 0, 0);
-            yield user_service.alter_user (user_id, username, form.get_field ("email"), form.get_field ("forename"), form.get_field ("surname"), dob, true);
-            
-            var new_password = form.get_field ("new_password");
-            if(new_password != null && new_password != "") {
-                yield user_service.set_password (user_id, new_password);
-            }
-
-            response.set_header ("HX-Refresh", "true");
-            response.skip_content ();
-        }
-    }
-
-}

+ 0 - 132
src/Authentication/Components/UserManagementComponent.vala

@@ -1,132 +0,0 @@
-using Astralis;
-using Inversion;
-using Spry.Authorisation;
-
-namespace Spry.Authentication {
-
-    public class UserManagementComponent : Component {
-        public int page_number { get; set; default = 0; }
-        public string authorisation_permission { get; set; default = "spry.admin"; }
-        public bool authorised { get; set; }
-        public const int64 users_per_page = 20;
-        public string? error_message { get; set; }
-        public string? success_message { get; set; }
-
-        public override string markup { get { return """
-        <spry-context property="page_number" />
-        <spry-context property="authorisation_permission" />
-        <spry-context property="error_message" />
-        <spry-context property="success_message" />
-        <div spry-if="!this.authorised">
-            <strong>You must have the permission <code content-expr="this.authorisation_permission"></code> to access this content.</strong>
-        </div>
-        <div spry-else sid="container" style="gap: 1em; padding: 1em;">
-            <spry-outlet sid="outlet" />
-            <details>
-                <summary><strong>Create New User</strong></summary>
-                <form spry-action=":create" spry-target="container" spry-method="post" hx-disabled-elt="find input, find button" hx-indicator="find button" hx-swap="outerHTML">
-                    <div style="display: grid; grid-template-columns: max-content auto; column-gap: 3em; row-gap: 1em;">
-                        <label for="username">Username:</label>
-                        <input type="text" id="username" name="username" required />
-                        <label for="email">Email:</label>
-                        <input type="email" id="email" name="email" required />
-                        <label for="forename">Forename:</label>
-                        <input type="text" id="forename" name="forename" required />
-                        <label for="surname">Surname:</label>
-                        <input type="text" id="surname" name="surname" required />
-                        <label for="date_of_birth">Date of Birth:</label>
-                        <input type="date" id="date_of_birth" name="date_of_birth" required />
-                        <label for="password">Password:</label>
-                        <input type="password" id="password" name="password" required />
-                        <div></div>
-                        <button type="submit">Create User</button>
-                    </div>
-                </form>
-            </details>
-            <div spry-if="this.error_message.length > 0" style="color: red; margin-top: 1em;">
-                <strong content-expr="this.error_message"></strong>
-            </div>
-            <div spry-if="this.error_message.length > 0" style="color: green; margin-top: 1em;">
-                <strong content-expr="this.success_message"></strong>
-            </div>
-            <div style="margin-top: 1em; display: flex; gap: 0.75em; align-items: center">
-                <button spry-action=":previous" spry-target="container" hx-swap="outerHTML">Previous</button>
-                <span>Page <strong content-expr="stringify(this.page_number + 1)"></strong></span>
-                <button spry-action=":next" spry-target="container" hx-swap="outerHTML">Next</button>
-            </div>
-        </div>
-        """; }}
-
-        private UserService user_service = inject<UserService>();
-        private AuthorisationContext authorisation_context = inject<AuthorisationContext>();
-        private ComponentFactory component_factory = inject<ComponentFactory>();
-        private HttpContext http_context = inject<HttpContext>();
-
-        public async override void prepare () throws Error {
-            if(authorisation_context.is_anonymous() || !authorisation_context.has_permission (authorisation_permission)) {
-                authorised = false;
-                return;
-            }
-
-            authorised = true;
-            var users = yield user_service.list_users (page_number * users_per_page, page_number * users_per_page + users_per_page);
-            foreach (var user in users) {
-                var component = component_factory.create<UserComponent>();
-                component.user_id = (int)user.id;
-                component.user = user;
-                add_outlet_child ("outlet", component);
-            }
-        }
-
-        public async override void handle_action(string action) {
-            if(action == "previous") {
-                page_number --;
-                if(page_number < 0) {
-                    page_number = 0;
-                }
-            }
-            if(action == "next") {
-                page_number ++;
-            }
-            if(action == "create") {
-                try {
-                    var form = yield Astralis.FormDataParser.parse(http_context.request.request_body, http_context.request.content_type);
-                    
-                    var username = form.get_field("username");
-                    var email = form.get_field("email");
-                    var forename = form.get_field("forename");
-                    var surname = form.get_field("surname");
-                    var date_of_birth_str = form.get_field("date_of_birth");
-                    var password = form.get_field("password");
-                    
-                    if (username == null || email == null || forename == null || surname == null || date_of_birth_str == null || password == null) {
-                        error_message = "All fields are required.";
-                        return;
-                    }
-                    
-                    var date_parts = date_of_birth_str.split("-");
-                    if (date_parts.length != 3) {
-                        error_message = "Invalid date format. Use YYYY-MM-DD.";
-                        return;
-                    }
-                    
-                    var year = int.parse(date_parts[0]);
-                    var month = int.parse(date_parts[1]);
-                    var day = int.parse(date_parts[2]);
-                    
-                    var date_of_birth = new DateTime.utc(year, month, day, 0, 0, 0);
-                    
-                    yield user_service.register_user(username, email, forename, surname, date_of_birth, password);
-                    
-                    success_message = "User created successfully.";
-                    error_message = null;
-                } catch (Error e) {
-                    error_message = "Failed to create user: %s".printf(e.message);
-                    success_message = null;
-                }
-            }
-        }
-        
-    }
-
-}

+ 31 - 27
src/Authentication/UserEntity.vala

@@ -1,35 +1,39 @@
 using InvercargillSql.Orm;
-using Spry.Authorisation;
+using Inversion;
 
 namespace Spry.Authentication {
 
-    public class UserEntity : Object {
+	/**
+	 * Persistent user account row (`spry_users`). Passwords are stored as
+	 * libsodium hashes via {@link UserService}.
+	 */
+	public class UserEntity : Object {
 
-        public int64 id { get; set; }
-        public string username { get; set; }
-        public string email { get; set; }
-        public string forename { get; set; }
-        public string surname { get; set; }
-        public string password_hash { get; set; }
-        public DateTime date_of_birth { get; set; }
-        public DateTime created { get; set; }
-        public DateTime modified { get; set; }
-        public bool enabled { get; set; }
+		public int64 id { get; set; }
+		public string username { get; set; }
+		public string email { get; set; }
+		public string forename { get; set; }
+		public string surname { get; set; }
+		public string password_hash { get; set; }
+		public DateTime date_of_birth { get; set; }
+		public DateTime created { get; set; }
+		public DateTime modified { get; set; }
+		public bool enabled { get; set; }
 
-        public static void entity_mapping(EntityMapperBuilder<UserEntity> cfg) {
-            cfg.table("spry_users")
-                .column<int64?>("id", o => o.id, (o, v) => o.id = v)
-                .column<string>("username", o => o.username, (o, v) => o.username = v)
-                .column<string>("email", o => o.email, (o, v) => o.email = v)
-                .column<string>("forename", o => o.forename, (o, v) => o.forename = v)
-                .column<string>("surname", o => o.surname, (o, v) => o.surname = v)
-                .column<string>("password_hash", o => o.password_hash, (o, v) => o.password_hash = v)
-                .column<DateTime>("date_of_birth", o => o.date_of_birth, (o, v) => o.date_of_birth = v)
-                .column<DateTime>("created", o => o.created, (o, v) => o.created = v)
-                .column<DateTime>("modified", o => o.modified, (o, v) => o.modified = v)
-                .column<bool>("enabled", o => o.enabled, (o, v) => o.enabled = v);
-        }
+		public static void entity_mapping(EntityMapperBuilder<UserEntity> cfg) {
+			cfg.table("spry_users")
+				.column<int64?>("id", o => o.id, (o, v) => o.id = v)
+				.column<string>("username", o => o.username, (o, v) => o.username = v)
+				.column<string>("email", o => o.email, (o, v) => o.email = v)
+				.column<string>("forename", o => o.forename, (o, v) => o.forename = v)
+				.column<string>("surname", o => o.surname, (o, v) => o.surname = v)
+				.column<string>("password_hash", o => o.password_hash, (o, v) => o.password_hash = v)
+				.column<DateTime>("date_of_birth", o => o.date_of_birth, (o, v) => o.date_of_birth = v)
+				.column<DateTime>("created", o => o.created, (o, v) => o.created = v)
+				.column<DateTime>("modified", o => o.modified, (o, v) => o.modified = v)
+				.column<bool>("enabled", o => o.enabled, (o, v) => o.enabled = v);
+		}
 
-    }
+	}
 
-}
+}

+ 0 - 26
src/Authentication/UserIdentityProvider.vala

@@ -1,26 +0,0 @@
-using Spry.Authorisation;
-using InvercargillSql.Orm;
-using Invercargill;
-using Invercargill.Expressions;
-using Inversion;
-
-namespace Spry.Authentication {
-
-    public class UserIdentityProvider : Object, IdentityProvider {
-
-        private OrmSession db = inject<OrmSession>();
-
-        public async Authorisation.Identity? get_identity_by_identifier (Element id) throws Error {
-            return yield db.query<UserProjection>()
-                .where(expr("id == $0", id))
-                .first_async();
-        }
-        public async Authorisation.Identity? get_identity_by_username (string username) throws Error {
-            return yield db.query<UserProjection>()
-                .where(expr("username == $0", elem<string>(username)))
-                .first_async();
-        }
-        
-    }
-
-}

+ 1 - 1
src/Authentication/UserPermissionEntity.vala

@@ -2,7 +2,7 @@ using InvercargillSql.Orm;
 
 namespace Spry.Authentication {
 
-    class UserPermissionEntity {
+    public class UserPermissionEntity : Object {
 
         public int64 id { get; set; }
         public int64 user_id { get; set; }

+ 49 - 49
src/Authentication/UserProjection.vala

@@ -1,56 +1,56 @@
 using InvercargillSql.Orm.Projections;
 using Invercargill.DataStructures;
-using Spry.Authorisation;
 using Invercargill;
 using Invercargill.Expressions;
 
 namespace Spry.Authentication {
 
-    public class UserProjection : Object, Identity {
-
-        public Element identifier { owned get { return new NativeElement<int64?>(id); } }
-        public string username { get { return _username; } }
-        public ImmutableLot<string> permissions { owned get { return _permissions.to_immutable_buffer(); } }
-        public Invercargill.Properties data { owned get {
-            var props = new DataStructures.PropertyDictionary();
-            props.set_native<string>("email", email);
-            props.set_native<string>("forename", forename);
-            props.set_native<string>("surname", surname);
-            props.set_native<DateTime>("date_of_birth", date_of_birth);
-            props.set_native<DateTime>("created", created);
-            props.set_native<DateTime>("modified", modified);
-            return props;
-        }}
-
-        public int64 id { get; set; }
-        public string email { get; set; }
-        public string forename { get; set; }
-        public string surname { get; set; }
-        public string password_hash { get; set; }
-        public DateTime date_of_birth { get; set; }
-        public DateTime created { get; set; }
-        public DateTime modified { get; set; }
-        public bool enabled { get; set; }
-
-        private string _username;
-        private ImmutableBuffer<string> _permissions;
-
-        public static void projection_mapping(ProjectionBuilder<UserProjection> cfg) throws Error {
-            cfg.source<UserEntity>("u")
-                .select<int64?>("id", expr("u.id"), (o, v) => o.id = v)
-                .select<string>("username", expr("u.username"), (o, v) => o._username = v)
-                .select<string>("email", expr("u.email"), (o, v) => o.email = v)
-                .select<string>("forename", expr("u.forename"), (o, v) => o.forename = v)
-                .select<string>("surname", expr("u.surname"), (o, v) => o.surname = v)
-                .select<string>("password_hash", expr("u.password_hash"), (o, v) => o.password_hash = v)
-                .select<DateTime>("date_of_birth", expr("u.date_of_birth"), (o, v) => o.date_of_birth = v)
-                .select<DateTime>("created", expr("u.created"), (o, v) => o.created = v)
-                .select<DateTime>("modified", expr("u.modified"), (o, v) => o.modified = v)
-                .select<bool>("enabled", expr("u.enabled"), (o, v) => o.enabled = v)
-                .join<UserPermissionEntity>("p", expr("p.user_id == u.id"))
-                .select_many<string>("permissions", expr("p.permission"), (o, v) => o._permissions = v.to_immutable_buffer());
-        }
-
-    }
-
-}
+	/**
+	 * Read model over `spry_users` joined with the user's
+	 * `spry_user_permissions` rows. {@link permissions} carries the user's
+	 * permission patterns; {@link Spry.SpryAuth.login} copies them into the
+	 * auth slot's public data.
+	 */
+	public class UserProjection : Object {
+
+		public string username { get { return _username; } }
+		public ImmutableLot<string> permissions { owned get { return _permissions.to_immutable_buffer(); } }
+
+		public int64 id { get; set; }
+		public string email { get; set; }
+		public string forename { get; set; }
+		public string surname { get; set; }
+		public string password_hash { get; set; }
+		public DateTime date_of_birth { get; set; }
+		public DateTime created { get; set; }
+		public DateTime modified { get; set; }
+		public bool enabled { get; set; }
+
+	private string _username;
+
+	/**
+	 * Starts empty (not null): a user with no joined permission rows
+	 * never triggers {@link permissions}, so without this initialiser the
+	 * getter would hand callers a null collection.
+	 */
+	private ImmutableBuffer<string> _permissions = new ImmutableBuffer<string>(new Series<string>());
+
+		public static void projection_mapping(ProjectionBuilder<UserProjection> cfg) throws Error {
+			cfg.source<UserEntity>("u")
+				.select<int64?>("id", expr("u.id"), (o, v) => o.id = v)
+				.select<string>("username", expr("u.username"), (o, v) => o._username = v)
+				.select<string>("email", expr("u.email"), (o, v) => o.email = v)
+				.select<string>("forename", expr("u.forename"), (o, v) => o.forename = v)
+				.select<string>("surname", expr("u.surname"), (o, v) => o.surname = v)
+				.select<string>("password_hash", expr("u.password_hash"), (o, v) => o.password_hash = v)
+				.select<DateTime>("date_of_birth", expr("u.date_of_birth"), (o, v) => o.date_of_birth = v)
+				.select<DateTime>("created", expr("u.created"), (o, v) => o.created = v)
+				.select<DateTime>("modified", expr("u.modified"), (o, v) => o.modified = v)
+				.select<bool>("enabled", expr("u.enabled"), (o, v) => o.enabled = v)
+				.join<UserPermissionEntity>("p", expr("p.user_id == u.id"))
+				.select_many<string>("permissions", expr("p.permission"), (o, v) => o._permissions = v.to_immutable_buffer());
+		}
+
+	}
+
+}

+ 211 - 121
src/Authentication/UserService.vala

@@ -1,5 +1,4 @@
 using InvercargillSql.Orm;
-using Spry.Authorisation;
 using Invercargill.Expressions;
 using Invercargill;
 using Invercargill.DataStructures;
@@ -7,123 +6,214 @@ using Inversion;
 
 namespace Spry.Authentication {
 
-    public class UserService : Object {
-
-        private OrmSession db = inject<OrmSession>();
-        private AuthorisationService authorisation_service = inject<AuthorisationService>();
-
-
-        public async AuthorisationToken? authenticate_user(string username, string password) throws Error {
-            var user = yield db.query<UserProjection>()
-                .where(expr("username == $0", elem(username)))
-                .first_async();
-
-            if(!Sodium.PasswordHashing.check(user.password_hash, password)){
-                return null;
-            }
-
-            return authorisation_service.authorise_identity(user);
-        }
-
-        public async UserEntity register_user(string username, string email, string forename, string surname, DateTime date_of_birth, string password, bool enabled = true) throws Error {
-            var user = new UserEntity() {
-                username = username,
-                email = email,
-                forename = forename,
-                surname = surname,
-                password_hash = Sodium.PasswordHashing.hash(password),
-                date_of_birth = date_of_birth,
-                created = new DateTime.now_utc(),
-                modified = new DateTime.now_utc(),
-                enabled = enabled,
-            };
-
-            yield db.insert_async<UserEntity>(user);
-            return user;
-        }
-
-        public async void set_password(int64 user_id, string password) throws Error {
-            var user = yield db.query<UserEntity>()
-                .where(expr("id == $0", elem<int64?>(user_id)))
-                .first_async();
-
-            user.password_hash = Sodium.PasswordHashing.hash(password);
-            user.modified = new DateTime.now_utc();
-            yield yield db.update_async<UserEntity>(user);
-        }
-
-        public async UserEntity alter_user(int64 user_id, string username, string email, string forename, string surname, DateTime date_of_birth, bool enabled) throws Error {
-            var user = yield db.query<UserEntity>()
-                .where(expr("id == $0", elem<int64?>(user_id)))
-                .first_async();
-
-            user.username = username;
-            user.email = email;
-            user.forename = forename;
-            user.surname = surname;
-            user.date_of_birth = date_of_birth;
-            user.modified = new DateTime.now_utc();
-            user.enabled = enabled;
-
-            yield db.update_async<UserEntity>(user);
-            return user;
-        }
-
-        public async void set_user_enabled(int64 user_id, bool enabled) throws Error {
-            var user = yield db.query<UserEntity>()
-                .where(expr("id == $0", elem<int64?>(user_id)))
-                .first_async();
-
-            user.modified = new DateTime.now_utc();
-            user.enabled = enabled;
-
-            yield db.update_async<UserEntity>(user);
-        }
-
-        public async ImmutableLot<UserProjection> list_users(int64 offset = 0, int64 limit = 100) throws Error {
-            return yield db.query<UserProjection>()
-                .offset(offset)
-                .limit(limit)
-                .materialise_async();
-        }
-
-        public async void delete_user(int64 user_id) throws Error {
-            var user = yield db.query<UserEntity>()
-                .where(expr("id == $0", elem<int64?>(user_id)))
-                .first_async();
-            db.delete<UserEntity>(user);
-        }
-
-        public async void set_user_permission(int64 user_id, string permission) throws Error {
-            var user_permission = new UserPermissionEntity() {
-                user_id = user_id,
-                permission = permission
-            };
-            yield db.insert_async<UserPermissionEntity>(user_permission);
-        }
-
-        public async void clear_user_permissions(int64 user_id) throws Error {
-            var permissions = yield db.query<UserPermissionEntity>()
-                .where(expr("user_id == $0", elem<int64?>(user_id)))
-                .materialise_async();
-
-            foreach (var permission in permissions) {
-                db.delete<UserPermissionEntity>(permission);
-            }
-        }
-
-        public async ImmutableLot<string> get_user_permissions(int64 user_id) throws Error {
-            var permissions = yield db.query<UserPermissionEntity>()
-                .where(expr("user_id == $0", elem<int64?>(user_id)))
-                .materialise_async();
-
-            var result = new Vector<string>();
-            foreach (var permission in permissions) {
-                result.add(permission.permission);
-            }
-            return result.to_immutable_buffer();
-        }
-
-    }
-
-}
+	/**
+	 * Store-level failures raised by {@link UserService}.
+	 */
+	public errordomain UserServiceError {
+		/** No `spry_users` row exists for the requested id */
+		USER_NOT_FOUND,
+	}
+
+	/**
+	 * User management over the `spry_users` store: credential verification,
+	 * registration, profile/permission administration. Register via
+	 * {@link Spry.SpryModule}; inject per-request.
+	 */
+	public class UserService : Object {
+
+		/**
+		 * Argon2 hash of a throwaway password, verified (and deliberately
+		 * failed) when a username is unknown, so unknown-username and
+		 * wrong-password logins take comparable time (see {@link
+		 * authenticate_user}).
+		 */
+		private const string DUMMY_PASSWORD_HASH = "$argon2id$v=19$m=262144,t=3,p=1$BJRNHzAq5K1sJMZfNZZFWA$915y7WkAuE67mZ9QLS402OnnDwpSZsqE+ZipbdJIIuw";
+
+		private OrmSession db = inject<OrmSession>();
+
+
+		/**
+		 * Verifies `password` against the stored hash for `username`,
+		 * returning the matching user or `null` when the username is
+		 * unknown, the password does not match or the account is disabled.
+		 *
+		 * Disabled accounts answer the same `null` as bad credentials (no
+		 * account-state side channel), and unknown usernames burn a dummy
+		 * hash check first so both failure paths take comparable time.
+		 */
+		public async UserProjection? authenticate_user(string username, string password) throws Error {
+			var user = yield get_user_by_username(username);
+
+			if (user == null) {
+				Sodium.PasswordHashing.check(DUMMY_PASSWORD_HASH, password);
+				return null;
+			}
+			if (!Sodium.PasswordHashing.check(user.password_hash, password) || !user.enabled) {
+				return null;
+			}
+
+			return user;
+		}
+
+		/**
+		 * Loads the user identified by `user_id` together with their
+		 * permission patterns, or `null` when no such account exists.
+		 */
+		public async UserProjection? get_user(int64 user_id) throws Error {
+			return yield db.query<UserProjection>()
+				.where(expr("id == $0", elem<int64?>(user_id)))
+				.first_async();
+		}
+
+		/**
+		 * Loads the user identified by `username` together with their
+		 * permission patterns, or `null` when no such account exists.
+		 */
+		public async UserProjection? get_user_by_username(string username) throws Error {
+			return yield db.query<UserProjection>()
+				.where(expr("username == $0", elem(username)))
+				.first_async();
+		}
+
+		public async UserEntity register_user(string username, string email, string forename, string surname, DateTime date_of_birth, string password, bool enabled = true) throws Error {
+			var user = new UserEntity() {
+				username = username,
+				email = email,
+				forename = forename,
+				surname = surname,
+				password_hash = Sodium.PasswordHashing.hash(password),
+				date_of_birth = date_of_birth,
+				created = new DateTime.now_utc(),
+				modified = new DateTime.now_utc(),
+				enabled = enabled,
+			};
+
+			yield db.insert_async<UserEntity>(user);
+			return user;
+		}
+
+		public async void set_password(int64 user_id, string password) throws Error {
+			var user = yield load_user(user_id);
+
+			user.password_hash = Sodium.PasswordHashing.hash(password);
+			user.modified = new DateTime.now_utc();
+			yield db.update_async<UserEntity>(user);
+		}
+
+		public async UserEntity alter_user(int64 user_id, string username, string email, string forename, string surname, DateTime date_of_birth, bool enabled) throws Error {
+			var user = yield load_user(user_id);
+
+			user.username = username;
+			user.email = email;
+			user.forename = forename;
+			user.surname = surname;
+			user.date_of_birth = date_of_birth;
+			user.modified = new DateTime.now_utc();
+			user.enabled = enabled;
+
+			yield db.update_async<UserEntity>(user);
+			return user;
+		}
+
+		public async void set_user_enabled(int64 user_id, bool enabled) throws Error {
+			var user = yield load_user(user_id);
+
+			user.modified = new DateTime.now_utc();
+			user.enabled = enabled;
+
+			yield db.update_async<UserEntity>(user);
+		}
+
+		public async ImmutableLot<UserProjection> list_users(int64 offset = 0, int64 limit = 100) throws Error {
+			return yield db.query<UserProjection>()
+				.offset(offset)
+				.limit(limit)
+				.materialise_async();
+		}
+
+		/**
+		 * Deletes the user's permission rows and then the user
+		 * themselves, so no orphaned permissions survive the delete.
+		 */
+		public async void delete_user(int64 user_id) throws Error {
+			var user = yield load_user(user_id);
+			yield clear_user_permissions(user_id);
+			db.delete<UserEntity>(user);
+		}
+
+		/**
+		 * Grants `permission` to the user, inserting nothing when the
+		 * permission is already held (the store carries no uniqueness
+		 * constraint on the pair, so callers may retry freely).
+		 */
+		public async void set_user_permission(int64 user_id, string permission) throws Error {
+			foreach (var held in yield get_user_permissions(user_id)) {
+				if (held == permission) {
+					return;
+				}
+			}
+
+			var user_permission = new UserPermissionEntity() {
+				user_id = user_id,
+				permission = permission
+			};
+			yield db.insert_async<UserPermissionEntity>(user_permission);
+		}
+
+		/**
+		 * Removes `permission` from the user with a single targeted delete
+		 * of the matching rows; the user's other permissions are untouched
+		 * (unlike {@link clear_user_permissions}).
+		 */
+		public async void remove_user_permission(int64 user_id, string permission) throws Error {
+			var rows = yield db.query<UserPermissionEntity>()
+				.where(expr("user_id == $0", elem<int64?>(user_id)))
+				.where(expr("permission == $0", elem(permission)))
+				.materialise_async();
+
+			foreach (var row in rows) {
+				db.delete<UserPermissionEntity>(row);
+			}
+		}
+
+		public async void clear_user_permissions(int64 user_id) throws Error {
+			var permissions = yield db.query<UserPermissionEntity>()
+				.where(expr("user_id == $0", elem<int64?>(user_id)))
+				.materialise_async();
+
+			foreach (var permission in permissions) {
+				db.delete<UserPermissionEntity>(permission);
+			}
+		}
+
+		public async ImmutableLot<string> get_user_permissions(int64 user_id) throws Error {
+			var permissions = yield db.query<UserPermissionEntity>()
+				.where(expr("user_id == $0", elem<int64?>(user_id)))
+				.materialise_async();
+
+			var result = new Vector<string>();
+			foreach (var permission in permissions) {
+				result.add(permission.permission);
+			}
+			return result.to_immutable_buffer();
+		}
+
+		/**
+		 * Loads the `spry_users` row for `user_id`, throwing {@link
+		 * UserServiceError.USER_NOT_FOUND} when the row is missing so
+		 * callers surface a catchable failure instead of dereferencing a
+		 * stale id.
+		 */
+		private async UserEntity load_user(int64 user_id) throws Error {
+			var user = yield db.query<UserEntity>()
+				.where(expr("id == $0", elem<int64?>(user_id)))
+				.first_async();
+			if (user == null) {
+				throw new UserServiceError.USER_NOT_FOUND(@"No user exists with id $(user_id)");
+			}
+			return user;
+		}
+
+	}
+
+}

+ 0 - 25
src/Authorisation/AuthorisationContext.vala

@@ -1,25 +0,0 @@
-
-namespace Spry.Authorisation {
-
-    public class AuthorisationContext : Object {
-
-        public AuthorisationToken? token { get; private set; }
-
-        public AuthorisationContext(AuthorisationToken? token = null) {
-            this.token = token;
-        }
-
-        public bool has_permission(string permission = "*") {
-            if(token == null){
-                return false;
-            }
-            return token.permissions.any(p => PermissionMatcher.matches(permission, p));
-        }
-
-        public bool is_anonymous() {
-            return token == null;
-        }
-
-    }
-
-}

+ 0 - 35
src/Authorisation/AuthorisationError.vala

@@ -1,35 +0,0 @@
-namespace Spry.Authorisation {
-
-    /**
-     * Error domain for authorisation-related errors.
-     * 
-     * These errors are thrown by the Authorisation system when
-     * authorisation checks fail or tokens are invalid.
-     */
-    public errordomain AuthorisationError {
-        /**
-         * The request is not authorised (no valid token present).
-         */
-        NOT_AUTHORISED,
-
-        /**
-         * The authorised identity does not have the required permission.
-         */
-        PERMISSION_DENIED,
-
-        /**
-         * The token is invalid (malformed, bad signature, etc.).
-         */
-        INVALID_TOKEN,
-
-        /**
-         * The token has expired.
-         */
-        TOKEN_EXPIRED,
-
-        /**
-         * The identity referenced by the token was not found.
-         */
-        IDENTITY_NOT_FOUND
-    }
-}

+ 0 - 40
src/Authorisation/AuthorisationPipelineComponent.vala

@@ -1,40 +0,0 @@
-using Astralis;
-using Inversion;
-
-namespace Spry.Authorisation {
-
-    public class AuthorisationPipelineComponent : Object, PipelineComponent {
-
-        private Scope scope = inject<Scope>();
-        private AuthorisationService authorisation_service = inject<AuthorisationService>();
-
-        public async Astralis.HttpResult process_request (Astralis.HttpContext http_context, Astralis.PipelineContext pipeline_context) throws Error {
-
-            var header = http_context.request.headers.get_any_or_default("Authorization");
-            AuthorisationToken token = null;
-            if(header != null && header.down().has_prefix ("bearer")) {
-                try {
-                    token = authorisation_service.read_token (header.substring(7).chug().chomp());
-                }
-                catch (Error e) {
-                    warning("Encountered error while reading bearer token: " + e.message);
-                }
-            }
-
-            if(token == null && http_context.request.cookies.has(COOKIE_NAME)) {
-                var token_string = http_context.request.cookies.get_any(COOKIE_NAME);
-                try {
-                    token = authorisation_service.read_token(token_string);
-                }
-                catch (Error e) {
-                    warning("Encountered error while reading cookie token: " + e.message);
-                }
-            }
-
-            scope.register_local_scoped<AuthorisationContext>(() => new AuthorisationContext (token));
-            return yield pipeline_context.next ();
-        }
-
-    }
-
-}

+ 0 - 44
src/Authorisation/AuthorisationService.vala

@@ -1,44 +0,0 @@
-using Inversion;
-using InvercargillJson;
-using Invercargill;
-using Astralis;
-
-namespace Spry.Authorisation {
-
-    public const string CRYPTOGRAPHY_NAMESPACE = "spry-authorisation";
-    public const string COOKIE_NAME = "_spry-authorisation";
-
-    public class AuthorisationService : Object {
-
-        private CryptographyProvider crypto_provider = inject<CryptographyProvider>();
-
-        public AuthorisationToken read_token(string token_string) throws Error {
-            var json_string = crypto_provider.read(CRYPTOGRAPHY_NAMESPACE, Base64.decode(token_string));
-            var json_object = new JsonElement.from_string(json_string).as<JsonObject>();
-            var token = AuthorisationToken.get_mapper().materialise(json_object);
-            token.cryptographic_token = Wrap.base64_string(token_string).to_byte_buffer();
-            return token;
-        }
-
-        public AuthorisationToken authorise_identity(Identity identity, TimeSpan? duration = null) throws Error {
-            var token = new AuthorisationToken(identity, duration);
-            var properties = AuthorisationToken.get_mapper().map_from(token);
-            var json_object = new JsonElement.from_properties(properties);
-            var json_string = json_object.stringify();
-            token.cryptographic_token = Wrap.byte_array(crypto_provider.author(CRYPTOGRAPHY_NAMESPACE, json_string)).to_byte_buffer();
-            return token;
-        }
-
-        public static string get_bearer_token(AuthorisationToken token) {
-            return token.cryptographic_token.to_base64();
-        }
-
-        public static void set_authorisation_cookie(AuthorisationToken token, HttpResult result) {
-            var token_str = token.cryptographic_token.to_base64();
-            result.headers.add("Set-Cookie", @"$COOKIE_NAME=$token_str; Secure");
-        }
-
-
-    }
-
-}

+ 0 - 82
src/Authorisation/AuthorisationToken.vala

@@ -1,82 +0,0 @@
-using Invercargill;
-using Invercargill.Mapping;
-using Invercargill.DataStructures;
-using InvercargillJson;
-
-namespace Spry.Authorisation {
-
-    /**
-     * Data structure embedded in authorisation tokens.
-     * 
-     * Token contents (JSON, encrypted and signed):
-     * - id: Identity unique identifier
-     * - username: Human-readable name
-     * - permissions: Array of permission strings
-     * - data: Additional variant data
-     * - issued_at: Token issuance timestamp
-     * - expires_at: Token expiry timestamp
-     */
-    public class AuthorisationToken {
-
-        // Identity fields
-        public Element user_identifier { get; private set; }
-        public string username { get; private set; }
-        public ImmutableLot<string> permissions { get; private set; }
-        public DateTime issued_at { get; private set; }
-        public DateTime expires_at { get; private set; }
-        public string token_id { get; private set; }
-        public Properties data { get; private set; }
-        public ByteBuffer cryptographic_token { get; internal set; }
-
-        /**
-         * Creates a token from an Identity.
-         * 
-         * @param identity The identity to create a token for
-         * @param duration Optional token duration (defaults to 24 hours)
-         */
-        internal AuthorisationToken(Identity identity, TimeSpan? duration = null) {
-            this.user_identifier = identity.identifier;
-            this.username = identity.username;
-            this.permissions = identity.permissions;
-            this.data = identity.data;
-            this.issued_at = new DateTime.now_utc();
-            this.expires_at = new DateTime.now_utc().add(duration ?? TimeSpan.HOUR * 24);
-            this.token_id = Uuid.string_random();
-        }
-
-        /**
-         * Checks if the token has expired.
-         * 
-         * @return true if the token has expired, false otherwise
-         */
-        public bool has_expired() {
-            return expires_at.compare(new DateTime.now_utc()) <= 0;
-        }
-
-        // Blank constructor for mapper below
-        private AuthorisationToken.blank() {
-            
-        }
-
-        /**
-         * Gets the property mapper for AuthorisationToken serialization.
-         * 
-         * Uses the PropertyMapper system from Invercargill.Mapping for
-         * consistent serialization with the rest of the framework.
-         */
-        public static PropertyMapper<AuthorisationToken> get_mapper() {
-            return PropertyMapper.build_for<AuthorisationToken>(cfg => {
-                cfg.map<Element>("uid", o => o.user_identifier, (o, v) => o.user_identifier = v);
-                cfg.map<string>("unm", o => o.username, (o, v) => o.username = v);
-                cfg.map_many<string>("prm", o => o.permissions, (o, v) => o.permissions = v.to_immutable_buffer())
-                    .when_null(o => o.permissions = Iterate.nothing<string>().to_immutable_buffer());
-                cfg.map<Properties>("dat", o => o.data, (o, v) => o.data = v);
-                cfg.map<string>("iat", o => o.issued_at.format_iso8601(), (o, v) => o.issued_at = new DateTime.from_iso8601(v, new TimeZone.utc()));
-                cfg.map<string?>("eat", 
-                    o => o.expires_at != null ? ((!)o.expires_at).format_iso8601() : null,
-                    (o, v) => o.expires_at = v != null ? new DateTime.from_iso8601((!)v, new TimeZone.utc()) : null);
-                cfg.set_constructor(() => new AuthorisationToken.blank());
-            });
-        }
-    }
-}

+ 0 - 41
src/Authorisation/Identity.vala

@@ -1,41 +0,0 @@
-using Invercargill.DataStructures;
-using Invercargill;
-
-namespace Spry.Authorisation {
-
-    /**
-     * Interface representing an authenticated identity.
-     * 
-     * Implementations provide identity data that gets embedded in tokens
-     * and can be retrieved on subsequent requests.
-     * 
-     * Built-in implementation: Spry.Authentication.User (via UserIdentityProvider)
-     * Custom implementations: OAuth providers, certificate auth, etc.
-     */
-    public interface Identity : GLib.Object {
-
-        /**
-         * Unique identifier for this identity.
-         * Used to look up the full identity object.
-         */
-        public abstract Element identifier { owned get; }
-
-        /**
-         * Human-readable name for this identity.
-         * Typically username or email.
-         */
-        public abstract string username { get; }
-
-        /**
-         * Permissions granted to this identity.
-         * Returns an immutable lot of strings for serialization.
-         */
-        public abstract ImmutableLot<string> permissions { owned get; }
-
-        /**
-         * Additional data to embed in the token.
-         * Implementation-specific data (e.g., roles, preferences).
-         */
-        public abstract Properties data { owned get; }
-    }
-}

+ 0 - 32
src/Authorisation/IdentityProvider.vala

@@ -1,32 +0,0 @@
-using Invercargill;
-namespace Spry.Authorisation {
-
-    /**
-     * Interface for retrieving Identity objects by ID or username.
-     * 
-     * The AuthorisationContext uses this to get_current_identity_async().
-     * Applications register their implementation during startup.
-     * 
-     * Built-in implementation: Spry.Authentication.UserIdentityProvider
-     */
-    public interface IdentityProvider : GLib.Object {
-
-        /**
-         * Retrieves an Identity by its unique ID.
-         * 
-         * @param id The identity ID from the token
-         * @return The Identity, or null if not found/inactive
-         * @throws Error on retrieval failure
-         */
-        public abstract async Identity? get_identity_by_identifier(Element identifier) throws Error;
-
-        /**
-         * Retrieves an Identity by its username.
-         * 
-         * @param username The username to look up
-         * @return The Identity, or null if not found/inactive
-         * @throws Error on retrieval failure
-         */
-        public abstract async Identity? get_identity_by_username(string username) throws Error;
-    }
-}

+ 0 - 64
src/Authorisation/PermissionMatcher.vala

@@ -1,64 +0,0 @@
-using Invercargill;
-
-namespace Spry.Authorisation {
-
-    /**
-     * Permission wildcard matching utility.
-     * 
-     * Supports wildcard patterns where `*` matches any suffix:
-     * - `users.*` matches `users.read`, `users.write`, `users.delete`
-     * - `admin.*` matches `admin.users.read`, `admin.settings.edit`
-     * - `*` matches everything
-     * - `admin` is a super-user permission that matches everything
-     * 
-     * This is a static utility class with no state.
-     */
-    public class PermissionMatcher : GLib.Object {
-
-        /**
-         * Checks if a permission pattern matches a specific permission.
-         * 
-         * Wildcard matching rules:
-         * - "admin" matches everything (super-user)
-         * - "*" matches everything
-         * - "prefix*" matches any permission starting with "prefix"
-         * - Without wildcard, requires exact match
-         * 
-         * Examples:
-         * - matches("admin", "anything") → true
-         * - matches("*", "anything") → true
-         * - matches("users.*", "users.read") → true
-         * - matches("users.*", "users.write") → true
-         * - matches("users.*", "admin") → false
-         * - matches("users.read", "users.read") → true
-         * - matches("users.read", "users.write") → false
-         * 
-         * @param pattern The pattern to match against (may contain wildcard)
-         * @param permission The permission to check
-         * @return true if the pattern matches the permission
-         */
-        public static bool matches(string pattern, string permission) {
-            // "admin" is the super-user permission - matches everything
-            if (pattern == "admin") {
-                return true;
-            }
-
-            // "*" matches everything
-            if (pattern == "*") {
-                return true;
-            }
-
-            // Check for trailing wildcard
-            if (pattern.has_suffix("*")) {
-                // Get the prefix before the wildcard
-                string prefix = pattern.substring(0, pattern.length - 1);
-
-                // Check if permission starts with the prefix
-                return permission.has_prefix(prefix);
-            }
-
-            // No wildcard - exact match required
-            return pattern == permission;
-        }
-    }
-}

+ 0 - 664
src/Component.vala

@@ -1,664 +0,0 @@
-using Invercargill;
-using Invercargill.DataStructures;
-using Invercargill.Expressions;
-using Inversion;
-using Astralis;
-
-namespace Spry {
-
-    public errordomain ComponentError {
-        INVALID_TYPE,
-        ELEMENT_NOT_FOUND,
-        TYPE_NOT_FOUND,
-        CONFLICTING_ATTRIBUTES,
-        INVALID_TEMPLATE,
-        INVALID_CONTEXT;
-    }
-
-    public abstract class Component : Object, Renderable {
-
-        private static Dictionary<Type, ComponentTemplate> templates;
-        private static Mutex templates_lock = Mutex();
-        public string context_key { get; internal set; default = Uuid.string_random(); }
-        
-        // Response state for action handlers
-        private ResponseState _response_state = new ResponseState();
-        
-        /**
-         * The response state for this component.
-         * Modify during handle_action to influence the HTTP response.
-         *
-         * Example:
-         * {{{
-         * public override async void handle_action(string action) throws Error {
-         *     if (action == "login") {
-         *         response.set_cookie("session", token, 86400);
-         *         response.redirect("/dashboard");
-         *     }
-         * }
-         * }}}
-         */
-        public ResponseState response { get { return _response_state; } }
-        
-        public abstract string markup { get; }
-        public virtual StatusCode get_status() {
-            return StatusCode.OK;
-        }
-        public virtual async void prepare() throws Error {
-            // No-op default
-        }
-        public virtual async void prepare_once() throws Error {
-            // No-op default
-        }
-        public virtual async void handle_action(string action) throws Error {
-            // No-op default
-        }
-        public virtual async void continuation(ContinuationContext continuation_context) throws Error {
-            // No-op default
-        }
-        public virtual async void continuation_canceled() throws Error {
-            // No-op default
-        }
-        
-        private PathProvider _path_provider = inject<PathProvider>();
-        private ContinuationProvider _continuation_provider = inject<ContinuationProvider>();
-        private ComponentFactory _component_factory = inject<ComponentFactory>();
-        private ComponentContextService _context_service = inject<ComponentContextService>();
-        private Catalogue<string, Renderable> _children = new Catalogue<string, Renderable>();
-        private Dictionary<string, Component> _child_components = new Dictionary<string, Component>();
-        private HashSet<Component> _global_sources = new HashSet<Component>();
-        private HashSet<string> _context_properties = new HashSet<string>();
-        private MarkupDocument _instance;
-        private bool _prepare_once_called;
-
-        private MarkupDocument instance { get {
-            if(_instance == null) {
-                try {
-                    lock(_instance) {
-                        if(_instance == null) {
-                            templates_lock.lock ();
-                            if(templates == null) {
-                                templates = new Dictionary<Type, ComponentTemplate>();
-                            }
-                            var type = this.get_type();
-                            ComponentTemplate template;
-                            if(!templates.try_get(type, out template)) {
-                                template = new ComponentTemplate(markup);
-                                templates[type] = template;
-                            }
-                            templates_lock.unlock();
-                            _instance = template.new_instance();
-                        }
-                    }
-                }
-                catch (Error e) {
-                    error(e.message);
-                }
-            }
-            return _instance;
-        }}
-
-        protected Enumerable<MarkupNode> get_elements_by_class_name(string class_name) {
-            return instance.get_elements_by_class_name(class_name);
-        }
-
-        protected Enumerable<MarkupNode> get_elements_by_tag_name(string tag_name) {
-            return instance.get_elements_by_tag_name(tag_name);
-        }
-
-        protected new Enumerable<MarkupNode> query(string xpath) {
-            return instance.select(xpath);
-        }
-
-        protected MarkupNode? query_one(string xpath) {
-            return instance.select_one(xpath);
-        }
-
-        protected MarkupNode get_element_by_global_id(string global_id) {
-            return instance.get_element_by_id(global_id);
-        }
-
-        protected new MarkupNode? @get(string spry_id) {
-            return instance.select_one(@"//*[@sid='$(spry_id)']");
-        }
-
-        protected void add_outlet_child(string outlet_id, Renderable renderable) {
-            _children.add(outlet_id, renderable);
-        }
-
-        protected void add_outlet_children(string outlet_id, Enumerable<Renderable> renderables) {
-            _children.add_all(outlet_id, renderables);
-        }
-
-        protected void set_outlet_children(string outlet_id, Enumerable<Renderable> renderables) {
-            _children[outlet_id] = renderables;
-        }
-
-        protected void set_outlet_child(string outlet_id, Renderable renderable) {
-            _children[outlet_id] = Iterate.single(renderable);
-        }
-
-        protected void clear_outlet_children(string outlet_id) {
-            _children.clear_key(outlet_id);
-        }
-
-        protected void add_globals_from(Component component) {
-            _global_sources.add(component);
-        }
-
-        protected T get_component_child<T>(string sid) throws Error {
-            var node = query_one(@"//spry-component[@sid='$sid']");
-            if(node == null) {
-                throw new ComponentError.ELEMENT_NOT_FOUND(@"No spry-component element with sid '$sid' found.");
-            }
-
-            var component = get_component_instance_from_component_node(node);
-            if(!component.get_type().is_a(typeof(T))) {
-                throw new ComponentError.INVALID_TYPE(@"Component type $(component.get_type().name()) is not a $(typeof(T).name())");
-            }
-            return component;
-        }
-
-        public async MarkupDocument to_document() throws Error {
-            if(!_prepare_once_called) {
-                yield prepare_once();
-                _prepare_once_called = true;
-            }
-            yield prepare();
-
-            if(response._skip_content) {
-                return new MarkupDocument();
-            }
-            var final_instance = instance.copy();
-            yield transform_document(final_instance);
-            return final_instance;
-        }
-
-        internal async MarkupDocument get_dynamic_section(string name) throws Error {
-            if(!_prepare_once_called) {
-                yield prepare_once();
-                _prepare_once_called = true;
-            }
-            yield prepare();
-
-            if(response._skip_content) {
-                return new MarkupDocument();
-            }
-
-            // Extract the dynamic fragment
-            var final_instance = instance.copy();
-            var template_fragment = final_instance.select_one(@"//*[@spry-dynamic='$name']")?.outer_html;
-            if(template_fragment == null) {
-                throw new ComponentError.ELEMENT_NOT_FOUND(@"Could not find spry-dynamic section '$name'.");
-            }
-            final_instance.body.inner_html = template_fragment;
-
-            // Do regular transform
-            yield transform_document(final_instance, true);
-            return final_instance;
-        }
-
-        public async MarkupDocument get_globals_document() throws Error {
-            if(!_prepare_once_called) {
-                yield prepare_once();
-                _prepare_once_called = true;
-            }
-            yield prepare();
-
-            if(response._skip_content) {
-                return new MarkupDocument();
-            }
-
-            var final_instance = instance.copy();
-            yield transform_document(final_instance);
-
-            // Extract out globals
-            var globals = final_instance.select("//*[@spry-global]");
-            var globals_document = new MarkupDocument();
-            globals_document.body.append_nodes(globals);
-            return globals_document;
-        }
-
-
-        public async HttpResult to_result() throws Error {
-            var document = yield to_document();
-            var result = document.to_result(get_status());
-            
-            // Apply accumulated response state (headers, cookies, redirects)
-            _response_state.apply_headers(result);
-            
-            // Reset state for next request
-            _response_state.reset();
-            
-            return result;
-        }
-
-        private class ComponentTemplate : MarkupTemplate {
-            private string _markup;
-            protected override string markup { get { return _markup; } }
-
-            public ComponentTemplate(string markup) {
-                this._markup = markup;
-            }
-        }
-
-        private Component get_component_instance_from_component_node(MarkupNode node) throws Error {
-            Component component;
-            // If no SID, create one to keep track of the instance
-            var sid = node.get_attribute("sid");
-            if(sid == null) {
-                sid = Uuid.string_random();
-                node.set_attribute("sid", sid);
-            }
-
-            if(!_child_components.try_get(sid, out component)) {
-                component = _component_factory.create_by_name(node.get_attribute("name"));
-                _child_components[sid] = component;
-            }
-
-            var attributes = node.get_attributes()
-                .where(a => a.key.has_prefix("prop-"))
-                .to_immutable_buffer();
-
-            foreach (var attribute in attributes) {
-                component.set_property(attribute.key.substring(5), attribute.value);
-            }
-
-            return component;
-        }
-
-        private async void transform_document(MarkupDocument doc, bool is_rendering_dynamic = false) throws Error {
-            transform_unique_attributes(doc); // Done first so as to ensure the tracking numbers don't change
-            transform_if_attributes(doc); // Outputs spry-hidden attributes
-            remove_hidden_blocks(doc); // Removes tags with spry-hidden attributes
-            yield transform_per_attributes(doc); // Executes spry-per-* loops, which handles nested expression attributes
-            yield transform_expression_attributes(doc); // Evaluares *-expr attributes
-            yield transform_outlets(doc);
-            transform_context_nodes(doc);
-            transform_action_nodes(doc);
-            transform_target_nodes(doc);
-            transform_global_nodes(doc);
-            transform_resource_nodes(doc);
-            transform_dynamic_attributes(doc, is_rendering_dynamic);
-            transform_continuation_nodes(doc);
-            remove_internal_sids(doc);
-            yield transform_components(doc);
-            yield append_globals(doc);
-        }
-
-        private async void transform_outlets(MarkupDocument doc) throws Error {
-            var outlets = doc.select("//spry-outlet");
-            foreach (var outlet in outlets) {
-                var nodes = new Series<MarkupNode>();
-                if(!outlet.has_attribute("sid")) {
-                    throw new ComponentError.INVALID_TEMPLATE("Tag spry-outlet must either define a content-expr or an sid");
-                }
-                foreach(var renderable in _children.get_or_empty(outlet.get_attribute("sid"))) {
-                    var document = yield renderable.to_document();
-                    nodes.add_all(document.body.children);
-                }
-                outlet.replace_with_nodes(nodes);
-            }
-        }
-
-        private void remove_hidden_blocks(MarkupDocument doc) {
-            doc.select("//*[@spry-hidden]")
-                .iterate(n => n.remove());
-        }
-
-        private void transform_action_nodes(MarkupDocument doc) throws Error {
-            var action_nodes = doc.select("//*[@spry-action]");
-            foreach(var node in action_nodes) {
-                var action = node.get_attribute("spry-action").split(":", 2);
-                var component_name = action[0].replace(".", "");
-                if(component_name == "") {
-                    component_name = this.get_type().name();
-                }
-                var component_action = action[1];
-
-                node.remove_attribute("spry-action");
-                var attribute = "hx-get";
-                if(node.has_attribute("spry-method")) {
-                    attribute = @"hx-$(node.get_attribute("spry-method"))";
-                }
-
-                if(component_name == this.get_type().name() && _context_properties.length > 0) {
-                    var data = new PropertyDictionary();
-                    var root = new PropertyDictionary();
-                    root["this"] = new NativeElement<Component>(this);
-                    var evaluation_context = new EvaluationContext(root);
-                    foreach(var prop_name in _context_properties) {
-                        data[prop_name] = ExpressionParser.parse(@"this.$(prop_name)").evaluate(evaluation_context);
-                    }
-                    var context = new ComponentContext() {
-                        type_name = this.get_type().name(),
-                        timestamp = new DateTime.now_utc(),
-                        context_key = context_key,
-                        data = data
-                    };
-                    var context_blob = _context_service.author_context_blob(context);
-                    node.set_attribute(attribute, _path_provider.get_action_path_with_context(component_name, component_action, context_blob));
-                }
-                else {
-                    node.set_attribute(attribute, _path_provider.get_action_path(component_name, component_action));
-                }
-            }
-        }
-
-        private void transform_target_nodes(MarkupDocument doc) {
-            var target_nodes = doc.select("//*[@spry-target]");
-            foreach(var node in target_nodes) {
-                var target_node = doc.select_one(@"//*[@sid='$(node.get_attribute("spry-target"))']");
-                if(target_node.id == null) {
-                    target_node.id = "_spry-target-" + Uuid.string_random();
-                }
-
-                node.set_attribute("hx-target", @"#$(target_node.id)");
-                node.remove_attribute("spry-target");
-            }
-        }
-
-        private void transform_global_nodes(MarkupDocument doc) {
-            var global_nodes = doc.select("//*[@spry-global]");
-            foreach(var node in global_nodes) {
-                var key = node.get_attribute("spry-global");
-                node.set_attribute("hx-swap-oob", @"[spry-global=\"$key\"]");
-            }
-        }
-
-        private void transform_resource_nodes(MarkupDocument doc) {
-            var script_nodes = doc.select("//*[@spry-res]");
-            foreach(var node in script_nodes) {
-                var res = node.get_attribute("spry-res");
-                if(res == null) {
-                    throw new ComponentError.INVALID_TEMPLATE("Attribute spry-res must have a value");
-                }
-
-                node.remove_attribute("spry-res");
-                var path = "/_spry/res/" + res;
-                if(node.tag_name == "script" || node.tag_name == "img") {
-                    node.set_attribute("src", path);
-                    continue;
-                }
-
-                if(node.tag_name == "link") {
-                    node.set_attribute("href", path);
-                    continue;
-                }
-            }
-        }
-
-        private void transform_continuation_nodes(MarkupDocument doc) {
-            var continuation_nodes = doc.select("//*[@spry-continuation]");
-            foreach(var node in continuation_nodes) {
-                var path = _continuation_provider.get_continuation_path(this);
-                node.set_attribute("hx-ext", "sse");
-                node.set_attribute("sse-connect", path);
-                node.set_attribute("sse-close", "_spry-close");
-                node.remove_attribute("spry-continuation");
-            }
-        }
-
-        private void remove_internal_sids(MarkupDocument doc) {
-            doc.select("//*[@sid]")
-                .iterate(n => n.remove_attribute("sid"));
-        }
-
-        private async void append_globals(MarkupDocument doc) throws Error {
-            foreach(var source in _global_sources) {
-                var globals = yield source.get_globals_document();
-                doc.body.append_nodes(globals.body.children);
-            }
-        }
-
-        private async void transform_components(MarkupDocument doc) throws Error {
-            var components = doc.select("//spry-component");
-            foreach (var component_node in components) {
-                var component = get_component_instance_from_component_node(component_node);
-                var document = yield component.to_document();
-                var content_nodes = document.select("//spry-content");
-                foreach(var content_node in content_nodes) {
-                    content_node.replace_with_nodes(component_node.children);
-                }
-                component_node.replace_with_nodes(document.body.children);
-            }
-        }
-
-        private void transform_dynamic_attributes(MarkupDocument doc, bool is_rendering_dynamic) throws Error {
-            var nodes = doc.select("//*[@spry-dynamic]");
-            foreach (var node in nodes) {
-                var name = node.get_attribute("spry-dynamic");
-                
-                if(!is_rendering_dynamic && !has_any_parent_where(node, n => n.has_attribute("spry-continuation"))) {
-                    throw new ComponentError.INVALID_TEMPLATE("A tag with a spry-dynamic attribute must be the child of a tag with a spry-continuation attribute");
-                }
-
-                node.set_attribute("sse-swap", @"_spry-dynamic-$name");
-                node.set_attribute("hx-swap", "outerHTML");
-                if(!node.has_attribute("id")) {
-                    node.set_attribute("id", @"_spry-dynamic-$name-$context_key");
-                    node.set_attribute("id", @"_spry-dynamic-$name-$context_key");
-                }
-                node.remove_attribute("spry-dynamic");
-            }
-        }
-
-        private void transform_unique_attributes(MarkupDocument doc) throws Error {
-            var nodes = doc.select("//*[@spry-unique]");
-            var counter = 1000;
-            foreach (var node in nodes) {
-                if(node.has_attribute("id")) {
-                    throw new ComponentError.INVALID_TEMPLATE("Cannot specify id attribute for an element with a spry-unique attribute");
-                }
-                if(node.get_attributes().keys.any(a => a.has_prefix("spry-per-")) || has_any_parent_where(node, n => n.get_attributes().keys.any(a => a.has_prefix("spry-per-")))) {
-                    throw new ComponentError.INVALID_TEMPLATE("The spry-unique attribute is not valid on any element or child of any element with a spry-per attribute");
-                }
-                node.set_attribute("id", @"_spry-unique-$counter-$context_key");
-                node.set_attribute("id", @"_spry-unique-$counter-$context_key");
-                counter++;
-            }
-        }
-
-        private void transform_if_attributes(MarkupDocument doc, EvaluationContext? context = null) throws Error {
-            var root = new PropertyDictionary();
-            root["this"] = new NativeElement<Component>(this);
-            var evaluation_context = context ?? new EvaluationContext(root);
-
-            MarkupNode node;
-            // Select one by one, so we don't have problems with nesting
-            while((node = doc.select_one("//*[@spry-if or @spry-else-if or @spry-else]")) != null) {
-                if (context == null && has_any_parent_where(node, n => n.get_attributes().keys.any(a => a.has_prefix("spry-per-")))) {
-                    // Don't process, or remove if an explicit context was not passed and the attribute is inside spry-per-* blocks
-                    // transform_per_attributes will call back later with more context information.
-                    break;
-                }
-
-                var expression_string = node.get_attribute("spry-if") ?? node.get_attribute("spry-else-if");
-                node.remove_attribute("spry-if");
-                node.remove_attribute("spry-else-if");
-                node.remove_attribute("spry-else");
-                if(expression_string == null) {
-                    continue;
-                }
-
-                var result = evaluate_if_expression(evaluation_context, expression_string, node);
-                print(@"Result $(result)\n");
-                if(result) {
-                    // Hide any chained nodes
-                    MarkupNode chained_node;
-                    while((chained_node = node.next_element_sibling) != null) {
-                        if(chained_node.has_attribute("spry-else") || chained_node.get_attribute("spry-else-if") != null) {
-                            chained_node.remove();
-                        }
-                        else {
-                            // If a sibling has no spry-else or spry-else-if it breaks the chain
-                            break;
-                        }
-                    }
-                }
-                else {
-                    // Mark this node for removal when condition is false
-                    node.remove();
-                }
-            }
-        }
-
-        private bool evaluate_if_expression(EvaluationContext context, string expression_string, MarkupNode node) throws Error {
-            var expression = ExpressionParser.parse(expression_string);
-            var result = expression.evaluate(context);
-
-            bool boolean_result;
-            if(result.is<bool>()) {
-                boolean_result = result.as<bool>();
-            }
-            else if(result.is<int>()) {
-                boolean_result = result.as<int>() != 0;
-            }
-            else {
-                boolean_result = !result.is_null();
-            }
-
-            return boolean_result;
-        }
-
-        private async void transform_per_attributes(MarkupDocument doc, EvaluationContext? context = null) throws Error {
-            MarkupNode node;
-            // Select one by one, so we don't have problems with nesting
-            while((node = doc.nodes.first_or_default(n => n.get_attributes().any(a => a.key.has_prefix("spry-per-")))) != null) {
-                var attribute = node.get_attributes().first(s => s.key.has_prefix("spry-per-"));
-
-                var root = new PropertyDictionary();
-                root["this"] = new NativeElement<Component>(this);
-                var evaluation_context = context ?? new EvaluationContext(root);
-                var expression = ExpressionParser.parse(attribute.value);
-                var result = expression.evaluate(evaluation_context);
-
-                if(!result.assignable_to<Enumerable>()) {
-                    throw new ComponentError.INVALID_TYPE(@"The spry-per attribute must refer to a value of type Invercargill.Enumerable, '$(attribute.value)' evaluates to a $(result.type_name())");
-                }
-
-                node.remove_attribute(attribute.key);
-                var values = result.as<Enumerable>().to_elements();
-                var output_nodes = new Series<MarkupNode>();
-                foreach(var value in values) {
-                    evaluation_context.root_values[attribute.key[9:]] = value;
-                    var fragment = new MarkupDocument();
-                    fragment.body.append_node(node);
-                    
-                    // Basic transform pipeline for fragment, the rest will get processed as part
-                    // of the wider component document later.
-                    transform_if_attributes(fragment, evaluation_context);
-                    remove_hidden_blocks(fragment);
-                    yield transform_per_attributes(fragment, evaluation_context);
-                    yield transform_expression_attributes(fragment, evaluation_context);
-                    
-                    output_nodes.add_all(fragment.body.children);
-                }
-                node.replace_with_nodes(output_nodes);
-            }
-        }
-
-        private void transform_context_nodes(MarkupDocument doc) throws Error {
-
-            var nodes = doc.select("//spry-context"); // Can't check for suffixes with xpath so iterate all nodes with attributes
-            foreach (var node in nodes) {
-                var property_name = node.get_attribute("property");
-                if(property_name == null) {
-                    throw new ComponentError.INVALID_TEMPLATE("Tag spry-context must have a property attribute");
-                }
-                _context_properties.add(property_name);
-                node.remove();
-            }
-        }
-
-        private async void transform_expression_attributes(MarkupDocument doc, EvaluationContext? context = null) throws Error {
-            var nodes = doc.select("//*[@*]"); // Can't check for suffixes with xpath so iterate all nodes with attributes
-            foreach (var node in nodes) {
-                var attributes = node.get_attributes();
-                foreach (var attribute in attributes) {
-                    if(!attribute.key.has_suffix("-expr")) {
-                        continue;
-                    }
-
-                    var real_attribute = attribute.key.substring(0, attribute.key.length - 5);
-                    var root = new PropertyDictionary();
-                    root["this"] = new NativeElement<Component>(this);
-                    var evaluation_context = context ?? new EvaluationContext(root);
-                    var expression = ExpressionParser.parse(attribute.value);
-                    var result = expression.evaluate(evaluation_context);
-
-                    node.remove_attribute(attribute.key);
-                    
-                    // class.* can be boolean
-                    if(result.type().is_a(typeof(bool)) && real_attribute.has_prefix("class-")) {
-                        var class_name = real_attribute.split("-", 2)[1];
-                        if(result.as<bool>()) {
-                            if(!node.has_class(class_name)) {
-                                node.add_class(class_name);
-                            }
-                        }
-                        else {
-                            node.remove_class(class_name);
-                        }
-                        continue;
-                    }
-
-                    if(real_attribute == "content" && result.type().is_a(typeof(Renderable))) {
-                        var renderable = result.as<Renderable>();
-                        var document = yield renderable.to_document();
-                        if(node.tag_name == "spry-outlet") {
-                            if(node.get_attribute("sid") != null) {
-                                throw new ComponentError.CONFLICTING_ATTRIBUTES("Tag 'spry-outlet' cannot have both a 'content-expr' and 'sid' attribute");
-                            }
-                            node.replace_with_nodes(document.body.children);
-                        }
-                        else {
-                            node.clear_children();
-                            node.append_nodes(document.body.children);
-                        }
-                        continue;
-                    }
-
-                    // if the expression is a boolean, toggle the attribute on or off
-                    if(result.type().is_a(typeof(bool))) {
-                        if(result.as<bool>()) {
-                            node.set_attribute(real_attribute, "");
-                        }
-                        else {
-                            node.remove_attribute(real_attribute);
-                        }
-                        continue;
-                    }
-
-                    // everything else read as string
-                    var str_value = result.as<string>();
-
-                    if(real_attribute == "content") {
-                        node.text_content = str_value;
-                        continue;
-                    }
-
-                    if(real_attribute.has_prefix("style-")) {
-                        var style_name = real_attribute.split("-", 2)[1];
-                        node.set_style(style_name, str_value);
-                        continue;
-                    }
-
-                    node.set_attribute(real_attribute, str_value);
-                }
-            }
-        }
-
-        private bool has_any_parent_where(MarkupNode node, PredicateDelegate<MarkupNode> predicate) {
-            var current = node;
-            while((current = current.parent) != null) {
-                if(predicate(current)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-    }
-
-}

+ 0 - 115
src/ComponentContextService.vala

@@ -1,115 +0,0 @@
-using Invercargill;
-using Invercargill.Mapping;
-using Invercargill.DataStructures;
-using InvercargillJson;
-using Inversion;
-
-namespace Spry {
-
-    /**
-     * Service for managing component context blobs.
-     * 
-     * Component context is used to preserve component state across HTTP requests.
-     * When a component action is triggered, the context properties are serialized,
-     * signed, and encrypted into a blob that is included in the action URL.
-     * 
-     * This service handles:
-     * - Serialization/deserialization of ComponentContext to/from JSON
-     * - Signing and encryption via CryptographyProvider
-     * - URL-safe Base64 encoding for transport
-     */
-    public class ComponentContextService : Object {
-
-        private const string NAMESPACE = "component-context";
-
-        private CryptographyProvider _crypto = inject<CryptographyProvider>();
-
-        /**
-         * Authors a component context blob.
-         * 
-         * Serializes the context to JSON, signs and encrypts it using
-         * the CryptographyProvider, and returns a URL-safe Base64 string.
-         * 
-         * @param context The component context to author
-         * @return A URL-safe Base64 encoded blob string
-         * @throws Error on serialization or encryption failure
-         */
-        public string author_context_blob(ComponentContext context) throws Error {
-            var mapper = ComponentContext.get_mapper();
-            var properties = mapper.map_from(context);
-            var json = new JsonElement.from_properties(properties);
-            var json_string = json.stringify();
-            
-            var blob = _crypto.author(NAMESPACE, json_string);
-            return Base64.encode(blob).replace("+", "-").replace("/", "_");
-        }
-
-        /**
-         * Reads a component context blob.
-         * 
-         * Decodes the URL-safe Base64, decrypts and verifies using
-         * the CryptographyProvider, and deserializes to a ComponentContext.
-         * 
-         * @param blob The URL-safe Base64 encoded blob string
-         * @return The deserialized ComponentContext
-         * @throws Error on decryption, signature, or deserialization failure
-         */
-        public ComponentContext read_context_blob(string blob) throws Error {
-            var decoded = Base64.decode(blob.replace("-", "+").replace("_", "/"));
-            var json_string = _crypto.read(NAMESPACE, decoded);
-            
-            if (json_string == null) {
-                throw new ComponentError.INVALID_CONTEXT("Could not decrypt context blob");
-            }
-            
-            var mapper = ComponentContext.get_mapper();
-            var json = new JsonElement.from_string((!)json_string);
-            return mapper.materialise(json.as<JsonObject>());
-        }
-    }
-
-    /**
-     * Component context data preserved across HTTP requests.
-     * 
-     * Contains the component type, unique context key, timestamp,
-     * and serialized property data.
-     */
-    public class ComponentContext : Object {
-
-        /**
-         * The type name of the component.
-         */
-        public string type_name { get; set; }
-
-        /**
-         * Unique key for this context instance.
-         */
-        public string context_key { get; set; }
-
-        /**
-         * Timestamp when the context was created.
-         */
-        public DateTime timestamp { get; set; }
-
-        /**
-         * Serialized property data from the component.
-         */
-        public Properties data { get; set; }
-
-        /**
-         * Gets the property mapper for ComponentContext serialization.
-         * 
-         * Uses compact property names to minimize blob size.
-         */
-        public static PropertyMapper<ComponentContext> get_mapper() {
-            return PropertyMapper.build_for<ComponentContext>(cfg => {
-                cfg.map<string>("c", o => o.type_name, (o, v) => o.type_name = v);
-                cfg.map<string>("k", o => o.context_key, (o, v) => o.context_key = v);
-                cfg.map<string>("t", o => o.timestamp.format_iso8601(), (o, v) => o.timestamp = new DateTime.from_iso8601(v, new TimeZone.utc()));
-                cfg.map<Properties>("d", o => o.data, (o, v) => o.data = v);
-                cfg.set_constructor(() => new ComponentContext());
-            });
-        }
-    }
-
-}

+ 0 - 60
src/ComponentEndpoint.vala

@@ -1,60 +0,0 @@
-
-using Invercargill;
-using Invercargill.DataStructures;
-using Inversion;
-using Astralis;
-
-namespace Spry {
-
-    public class ComponentEndpoint : Object, Endpoint {
-
-        private PathProvider component_uri_provider = inject<PathProvider>();
-        private ComponentContextService context_service = inject<ComponentContextService>();
-        private Scope scope = inject<Scope>();
-
-        public async Astralis.HttpResult handle_request (HttpContext http_context, RouteContext route_context) throws Error {
-            var component_id = route_context.mapped_parameters.get_or_default ("component-id");
-            var action_name = route_context.mapped_parameters.get_or_default ("action");
-            var context_blob = route_context.mapped_parameters.get_or_default ("context");
-            if(component_id == null) {
-                return new HttpStringResult ("Missing component ID", StatusCode.BAD_REQUEST);
-            }
-            if(component_id == null) {
-                return new HttpStringResult ("Missing action", StatusCode.BAD_REQUEST);
-            }
-            var component = component_uri_provider.get_component_instance(component_id, scope);
-            if(component == null) {
-                return new HttpStringResult ("Invalid component ID", StatusCode.NOT_FOUND);
-            }
-            if(context_blob != null) {
-                ComponentContext context;
-                try {
-                    context = context_service.read_context_blob(context_blob);
-                }
-                catch(Error e) {
-                    warning(@"Invalid component context: $(e.message)");
-                    return new HttpStringResult ("Invalid component context", StatusCode.BAD_REQUEST);
-                }
-                if(context.type_name != component.get_type().name()) {
-                    return new HttpStringResult ("Context mismatch", StatusCode.BAD_REQUEST);
-                }
-
-                component.context_key = context.context_key;
-                
-                foreach(var prop in context.data) {
-                    unowned var component_class = component.get_class ();
-                    var prop_spec = component_class.find_property (prop.key);
-                    if(prop_spec == null) {
-                        return new HttpStringResult (@"Invalid context property '$(prop.key)'", StatusCode.BAD_REQUEST);
-                    }
-                    component.set_property (prop.key, prop.value.to_value (prop_spec.value_type));
-                }
-            }
-            
-            yield component.handle_action(action_name);
-            return yield component.to_result();
-        }
-        
-    }
-
-}

+ 0 - 39
src/ComponentFactory.vala

@@ -1,39 +0,0 @@
-using Inversion;
-namespace Spry {
-
-    public class ComponentFactory : Object {
-
-        private Scope scope = inject<Scope>();
-        
-        public Component create_type(Type component_type) throws Error {
-            if(!component_type.is_a(typeof(Component))) {
-                throw new ContainerError.INCOMPATIBLE_TYPE(@"Type $(component_type.name()) is not a Component");
-            }
-            var component_registration = scope.get_registration(component_type);
-            if(component_registration.lifecycle != Lifecycle.TRANSIENT) {
-                throw new ContainerError.ILLEGAL_LIFECYCLE_COMBINATION("Spry.ComponentFactory can only create new instances of components that are registered in the container as transient.");
-            }
-
-            return (Component)scope.resolve_registration(component_registration);
-        }
-
-        public T create<T>() throws Error {
-            return (T)create_type(typeof(T));
-        } 
-
-        public Component create_by_name(string name) throws Error {
-            var type_name = name.replace(".", "");
-            var registration = scope.get_all_registrations()
-                .where(r => r.implementation_type.is_a(typeof(Component)))
-                .first_or_default(r => r.implementation_type.name() == type_name);
-
-            if(registration == null) {
-                throw new ComponentError.TYPE_NOT_FOUND(@"Could not find type $type_name");
-            }
-
-            return (Component)scope.resolve_registration(registration);
-        }
-
-    }
-
-}

+ 0 - 12
src/Context.vala

@@ -1,12 +0,0 @@
-using Astralis;
-using Invercargill.DataStructures;
-namespace Spry {
-
-    //  public class SpryContext {
-
-    //      public MarkupDocument document { get; private set; }
-    //      public bool is_fragment { get; private set; }
-
-    //  }
-
-}

+ 0 - 49
src/ContinuationContext.vala

@@ -1,49 +0,0 @@
-using Astralis;
-
-namespace Spry {
-
-    public class ContinuationContext : Object {
-
-        public SseStream sse_stream { get; private set;}
-        private Component component;
-
-        public ContinuationContext(Component component, SseStream stream) {
-            this.sse_stream = stream;
-            this.component = component;
-        }
-
-        public async void send_dynamic(string dynamic_name) throws Error {
-            var fragment = yield this.component.get_dynamic_section(dynamic_name);
-            yield sse_stream.send_event(new SseEvent.with_type(@"_spry-dynamic-$dynamic_name", fragment.body.inner_html));
-        }
-
-        public async void send_json(string event_type, Json.Node node) throws Error {
-            var json = Json.to_string(node, false);
-            yield sse_stream.send_event(new SseEvent.with_type(event_type, json));
-        }
-
-        public async void send_string(string event_type, string data) throws Error {
-            yield sse_stream.send_event(new SseEvent.with_type(event_type, data));
-        }
-
-        public async void send_full_update(string event_type) throws Error {
-            var doc = yield component.to_document();
-            string data;
-            if(component.get_type().is_a(typeof(PageComponent))) {
-                data = doc.to_html();
-            }
-            else {
-                data = doc.body.inner_html;
-            }
-            yield sse_stream.send_event(new SseEvent.with_type(event_type, data));
-        }
-
-        public async void send_event(SseEvent event) throws Error {
-            yield sse_stream.send_event(event);
-        }
-
-        
-
-    }
-
-}

+ 0 - 66
src/ContinuationProvider.vala

@@ -1,66 +0,0 @@
-using Astralis;
-using Invercargill.DataStructures;
-using Inversion;
-namespace Spry {
-
-    public class ContinuationProvider : SseEndpoint {
-
-        private Dictionary<string, Component> pending_components = new Dictionary<string, Component>();
-
-        public override uint retry_interval { get { return 500; } }
-
-        public async override void new_connection(HttpContext http_context, RouteContext route_context, SseStream stream) {
-            var continuation_id = route_context.mapped_parameters.get_or_default("token");
-            Component component = null;
-            pending_components.remove(continuation_id, out component);
-
-            try {
-                if(component == null) {
-                    yield stream.send_event(new SseEvent.with_type("_spry-close", "404"));
-                    return;
-                }
-
-                try {
-                    var context = new ContinuationContext(component, stream);
-                    yield component.continuation(context);
-                }
-                catch(Error e) {
-                    warning(@"Component $(component.get_type().name()) threw exception in follow up: $(e.message)");
-                    yield stream.send_event(new SseEvent.with_type("_spry-close", "500"));
-                }
-                yield stream.send_event(new SseEvent.with_type("_spry-close", "200"));
-            }
-            catch(Error e) {
-                warning("Failed to send '_spry-close' event: " + e.message);
-            }
-
-        }
-        
-        public string get_continuation_path(Component component) {
-            var id = Uuid.string_random();
-            pending_components[id] = component;
-
-            // Remove component after 30 seconds if no connection has been made
-            Timeout.add_seconds(30, () => {
-                clean.begin(id);
-                return false; // Don't repeat
-            });
-            return @"/_spry/cnu/$id";
-        }
-
-        private async void clean(string id) {
-            Component component;
-            if(pending_components.remove(id, out component)) {
-                warning(@"Canceling continuation for component $(component.get_type().name()) due to timeout.");
-                try {
-                    yield component.continuation_canceled();
-                }
-                catch(Error e) {
-                    warning(@"Component $(component.get_type().name()) threw exception while handling a canceled continuation: $(e.message)");
-                }
-            }
-        }
-
-    }
-
-}

+ 0 - 103
src/CryptographyProvider.vala

@@ -1,103 +0,0 @@
-using Invercargill;
-
-namespace Spry {
-
-    /**
-     * CryptographyProvider provides low-level cryptographic operations.
-     * 
-     * This service handles signing and encryption using libsodium:
-     * - Ed25519 for digital signatures
-     * - X25519 for public-key encryption (sealing)
-     * 
-     * All data is signed then sealed (encrypt-then-MAC pattern).
-     * Namespaces are used to prevent cross-protocol attacks.
-     */
-    public class CryptographyProvider : Object {
-
-        private uint8[] signing_secret_key;
-        private uint8[] signing_public_key;
-        private uint8[] sealing_secret_key;
-        private uint8[] sealing_public_key;
-
-        construct {
-            signing_secret_key = new uint8[Sodium.Asymmetric.Signing.SECRET_KEY_BYTES];
-            signing_public_key = new uint8[Sodium.Asymmetric.Signing.PUBLIC_KEY_BYTES];
-            Sodium.Asymmetric.Signing.generate_keypair(signing_public_key, signing_secret_key);
-
-            sealing_secret_key = new uint8[Sodium.Asymmetric.Sealing.SECRET_KEY_BYTES];
-            sealing_public_key = new uint8[Sodium.Asymmetric.Sealing.PUBLIC_KEY_BYTES];
-            Sodium.Asymmetric.Sealing.generate_keypair(sealing_public_key, sealing_secret_key);
-        }
-
-        /**
-         * Authors (signs and encrypts) data with a namespace.
-         * 
-         * The namespace is prepended to the data before signing to prevent
-         * cross-protocol attacks. The resulting blob contains:
-         * - The namespace (for verification during read)
-         * - The original data
-         * 
-         * The data is first signed with Ed25519, then encrypted with X25519-Seal.
-         * 
-         * @param namespace A unique identifier for the type of data being authored
-         * @param data The plaintext data to sign and encrypt
-         * @return The encrypted blob as binary data
-         */
-        public uint8[] author(string namespace, string data) throws Error {
-            // Prepend namespace to data
-            var namespaced_data = @"$namespace:$data";
-            
-            // Sign then seal
-            var signed = Sodium.Asymmetric.Signing.sign(namespaced_data.data, signing_secret_key);
-            var @sealed = Sodium.Asymmetric.Sealing.seal(signed, sealing_public_key);
-            
-            return @sealed;
-        }
-
-        /**
-         * Reads (decrypts and verifies) data with namespace validation.
-         * 
-         * The blob is decrypted and the signature verified. If the namespace
-         * in the blob doesn't match the expected namespace, an error is thrown.
-         * 
-         * @param namespace The expected namespace for this data
-         * @param data The encrypted blob to decrypt and verify
-         * @return The original plaintext data (without namespace prefix), or null if validation fails
-         * @throws Error if decryption, signature verification, or namespace validation fails
-         */
-        public string? read(string namespace, uint8[] data) throws Error {
-            // Unseal the data
-            var signed = Sodium.Asymmetric.Sealing.unseal(data, sealing_public_key, sealing_secret_key);
-            if (signed == null) {
-                return null;
-            }
-            
-            // Verify the signature
-            var cleartext = Sodium.Asymmetric.Signing.verify(signed, signing_public_key);
-            if (cleartext == null) {
-                return null;
-            }
-            
-            // Convert to string
-            var namespaced_data = Wrap.byte_array(cleartext).to_raw_string();
-            
-            // Validate and strip namespace prefix
-            var expected_prefix = @"$namespace:";
-            if (!namespaced_data.has_prefix(expected_prefix)) {
-                throw new CryptoError.NAMESPACE_MISMATCH(@"Expected namespace '$namespace' but found different namespace");
-            }
-            
-            return namespaced_data.substring(expected_prefix.length);
-        }
-    }
-
-    /**
-     * Error domain for cryptographic operations.
-     */
-    public errordomain CryptoError {
-        NAMESPACE_MISMATCH,
-        DECRYPTION_FAILED,
-        SIGNATURE_INVALID
-    }
-
-}

+ 0 - 64
src/PageComponent.vala

@@ -1,64 +0,0 @@
-using Astralis;
-using Inversion;
-using Invercargill;
-using Invercargill.DataStructures;
-
-namespace Spry {
-
-    public abstract class PageComponent : Component, Endpoint {
-
-        private Scope scope = inject<Scope>();
-
-        public abstract string title { get; }
-
-        public async Astralis.HttpResult handle_request (HttpContext http_context, RouteContext route_context) throws Error {
-            // Register a context for anything that gets instansiated after this
-            scope.register_local_scoped<PageContext>(() => new PageContext(this));
-
-            // Get templates as renderables in order of lowest to highest "rank"
-            var renderables = scope.get_registrations(typeof(PageTemplate))
-                .select_many<Pair<Registration, TemplateRoutePrefix>>(r => r.get_metadata<TemplateRoutePrefix>().select_pairs<Registration, TemplateRoutePrefix>(p => r, p => p))
-                .where(p => p.value2.matches_route(route_context))
-                .order_by<uint>(p => p.value2.rank)
-                .attempt_select<Object>(p => scope.resolve_registration (p.value1))
-                .cast<Renderable>()
-                .to_series();
-
-            // Finally, add this page
-            renderables.add(this);
-
-            MarkupDocument result = null;
-            foreach (var renderable in renderables) {
-                var document = yield renderable.to_document();
-                if(result == null){
-                    result = document;
-                    continue;
-                }
-
-                var content_added = false;
-                foreach(var outlet in result.select("//spry-content")) {
-                    outlet.replace_with_nodes(document.body.children);
-                    content_added = true;
-                }
-                if(content_added && document.head != null) {
-                    result.head.append_nodes(document.head.children);
-                }
-            }
-
-            return result.to_result(get_status());
-        }
-
-    }
-
-    public class PageContext : Object {
-
-        public PageComponent component { get; private set; }
-        public Type page_type { get { return component.get_type(); }}
-        public string title { get { return component.title; }}
-
-        public PageContext(PageComponent component) {
-            this.component = component;
-        }
-    }
-
-}

+ 0 - 32
src/PageTemplate.vala

@@ -1,32 +0,0 @@
-using Astralis;
-using Inversion;
-using Invercargill;
-using Invercargill.DataStructures;
-
-namespace Spry {
-
-    public abstract class PageTemplate : Component {
-
-    }
-
-    public class TemplateRoutePrefix : Object {
-
-        public uint rank { get; private set; }
-        public string prefix { get; private set; }
-        public ReadOnlyAddressable<string> prefix_segments { get; private set; }
-
-        public TemplateRoutePrefix(string prefix) {
-            this.prefix = prefix;
-            prefix_segments = Wrap.array<string>(prefix.split("/")).where(s => s.length != 0).to_immutable_buffer();
-            rank = prefix_segments.length;
-        }
-
-        public bool matches_route(RouteContext context) {
-            return context.matched_route.route_segments
-                .pair_up<string>(prefix_segments)
-                .all(p => !p.value2_is_set || (p.value1_is_set && p.value1 == p.value2));
-        }
-
-    }
-
-}

+ 0 - 50
src/PathProvider.vala

@@ -1,50 +0,0 @@
-using Invercargill.DataStructures;
-using Invercargill;
-using Inversion;
-
-namespace Spry {
-    public class PathProvider : Object {
-
-        private Dictionary<string, Type> type_mapping = new Dictionary<string, Type>();
-        private Dictionary<string, string> name_mapping = new Dictionary<string, string>();
-        private Container container = inject<Container>();
-
-        public Component? get_component_instance(string id, Scope scope) throws Error {
-            Type type;
-            if(type_mapping.try_get(id, out type)) {
-                return (Component)scope.resolve_type(type);
-            }
-            return null;
-        }
-
-        public string get_action_path(string type_name, string action_name) throws Error {
-            var component_id = upsert(type_name);
-            return @"/_spry/com/$(component_id)/$action_name";
-        }
-
-        public string get_action_path_with_context(string type_name, string action_name, string context_blob) throws Error {
-            var component_id = upsert(type_name);
-            return @"/_spry/com/$(component_id)/$action_name/$context_blob";
-        }
-
-        private string upsert(string type_name) throws Error {
-            if(name_mapping.has(type_name)) {
-                return name_mapping[type_name];
-            }
-
-            var registration = container.get_all_registrations()
-                .where(r => r.implementation_type.is_a(typeof(Component)))
-                .first_or_default(r => r.implementation_type.name() == type_name);
-
-            if(registration == null) {
-                throw new ContainerError.NOT_REGISTERED(@"Could not find registered component with name $(type_name)");
-            }
-
-            var uuid = Uuid.string_random();
-            type_mapping[uuid] = registration.implementation_type;
-            name_mapping[type_name] = uuid;
-            return uuid;
-        }
-
-    }
-}

+ 0 - 10
src/Renderable.vala

@@ -1,10 +0,0 @@
-using Astralis;
-namespace Spry {
-
-    public interface Renderable : Object {
-
-        public abstract async MarkupDocument to_document() throws Error;
-
-    }
-
-}

+ 0 - 213
src/ResponseState.vala

@@ -1,213 +0,0 @@
-using Invercargill;
-using Invercargill.DataStructures;
-using Astralis;
-
-namespace Spry {
-
-    /**
-     * Redirect type for component responses.
-     */
-    public enum RedirectType {
-        /** Client-side redirect using HX-Redirect header - default for HTMX */
-        CLIENT_SIDE,
-        /** HTTP 302 temporary redirect using Location header */
-        TEMPORARY,
-        /** HTTP 301 permanent redirect using Location header */
-        PERMANENT
-    }
-
-    /**
-     * Holds response state that will be applied to the final HttpResult.
-     * 
-     * Components can modify this during action handling to influence
-     * the HTTP response without needing to return an HttpResult directly.
-     * 
-     * This is particularly useful for async void action handlers that need
-     * to set cookies, headers, or redirects on the response.
-     * 
-     * Example usage:
-     * {{{
-     * public override async void handle_action(string action) throws Error {
-     *     if (action == "login") {
-     *         // Set a cookie
-     *         response.set_cookie("session", token, 86400);
-     *         
-     *         // Redirect after login
-     *         response.redirect("/dashboard");
-     *     }
-     * }
-     * }}}
-     */
-    public class ResponseState : GLib.Object {
-        
-        // Headers to add to the response (name -> value)
-        private HashTable<string, string> _headers;
-        
-        // Cookies to set (each as a complete Set-Cookie header value)
-        private List<string> _cookies;
-        
-        // HTTP status code override
-        private StatusCode? _status_code = null;
-        
-        // Redirect configuration
-        private string? _redirect_url = null;
-        private RedirectType _redirect_type = RedirectType.CLIENT_SIDE;
-
-        internal bool _skip_content = false;
-
-        public void skip_content() {
-            _skip_content = true;
-        }
-        
-        public ResponseState() {
-            _headers = new HashTable<string, string>(str_hash, str_equal);
-            _cookies = new List<string>();
-        }
-        
-        /**
-         * Sets a header on the response.
-         * If a header with this name already exists, it will be replaced.
-         */
-        public void set_header(string name, string value) {
-            _headers.insert(name, value);
-        }
-        
-        /**
-         * Adds a header to the response.
-         * Multiple headers with the same name can be added.
-         * Use this for headers like Set-Cookie that can appear multiple times.
-         */
-        public void add_header(string name, string value) {
-            // For Set-Cookie, we store in the cookies list
-            // For other headers, we just replace (since HttpResult doesn't support true multi-headers)
-            if (name == "Set-Cookie") {
-                _cookies.append(value);
-            } else {
-                _headers.insert(name, value);
-            }
-        }
-        
-        /**
-         * Sets the HTTP status code for the response.
-         */
-        public void set_status(StatusCode status) {
-            _status_code = status;
-        }
-
-        public void set_authorisation_token(Authorisation.AuthorisationToken token) {
-            var token_str = token.cryptographic_token.to_base64();
-            add_header("Set-Cookie", @"$(Authorisation.COOKIE_NAME)=$token_str; Path=/; Secure; HttpOnly; SameSite=Strict");
-        }
-        
-        /**
-         * Sets up a redirect.
-         * Default type is CLIENT_SIDE which uses HX-Redirect header for HTMX.
-         * 
-         * @param url The URL to redirect to
-         * @param type The type of redirect (default: CLIENT_SIDE for HTMX)
-         */
-        public void redirect(string url, RedirectType type = RedirectType.CLIENT_SIDE) {
-            _redirect_url = url;
-            _redirect_type = type;
-        }
-        
-        /**
-         * Convenience method to set a session cookie.
-         * 
-         * @param name Cookie name
-         * @param value Cookie value
-         * @param max_age Max age in seconds (-1 for session cookie)
-         * @param path Cookie path (default: "/")
-         * @param http_only Whether to set HttpOnly flag (default: true)
-         * @param secure Whether to set Secure flag (default: true)
-         * @param same_site SameSite value (default: "Strict")
-         */
-        public void set_cookie(
-            string name, 
-            string value, 
-            int max_age = -1,
-            string path = "/",
-            bool http_only = true,
-            bool secure = true,
-            string same_site = "Strict"
-        ) {
-            var cookie_parts = new StringBuilder();
-            cookie_parts.append_printf("%s=%s", name, value);
-            
-            if (path != null && path.length > 0) {
-                cookie_parts.append_printf("; Path=%s", path);
-            }
-            
-            if (max_age >= 0) {
-                cookie_parts.append_printf("; Max-Age=%d", max_age);
-            }
-            
-            if (http_only) {
-                cookie_parts.append("; HttpOnly");
-            }
-            
-            if (secure) {
-                cookie_parts.append("; Secure");
-            }
-            
-            if (same_site != null && same_site.length > 0) {
-                cookie_parts.append_printf("; SameSite=%s", same_site);
-            }
-            
-            _cookies.append(cookie_parts.str);
-        }
-        
-        /**
-         * Checks if any modifications have been made.
-         */
-        public bool has_modifications() {
-            uint headers_count = 0;
-            _headers.foreach((k, v) => { headers_count++; });
-            return headers_count > 0 ||
-                   _cookies.length() > 0 ||
-                   _status_code != null ||
-                   _redirect_url != null;
-        }
-        
-        /**
-         * Gets the status code if one was set.
-         */
-        public StatusCode? get_status_code() {
-            return _status_code;
-        }
-        
-        /**
-         * Applies all accumulated headers to an HttpResult.
-         * Note: This only applies headers. Status code and redirect handling
-         * should be done by creating an appropriate HttpResult subclass.
-         */
-        internal void apply_headers(HttpResult result) {
-            // Apply single-value headers
-            _headers.foreach((key, value) => {
-                result.set_header(key, value);
-            });
-            
-            // Apply cookies as Set-Cookie headers
-            foreach (var cookie in _cookies) {
-                result.set_header("Set-Cookie", cookie);
-            }
-            
-            // Apply redirect header for HTMX
-            if (_redirect_url != null && _redirect_type == RedirectType.CLIENT_SIDE) {
-                result.set_header("HX-Redirect", _redirect_url);
-            }
-        }
-        
-        /**
-         * Clears all accumulated state.
-         * Called after to_result() to prepare for next request.
-         */
-        internal void reset() {
-            _headers.remove_all();
-            _cookies = new List<string>();
-            _status_code = null;
-            _redirect_url = null;
-            _redirect_type = RedirectType.CLIENT_SIDE;
-        }
-    }
-}

+ 0 - 66
src/Spry.vala

@@ -1,66 +0,0 @@
-using Inversion;
-using Astralis;
-
-namespace Spry {
-
-    public class SpryModule : Object, Module {
-        public void register_components (Container container) throws Error {
-            container.register_singleton<PathProvider>();
-            container.register_startup<CryptographyProvider>();
-            container.register_startup<ComponentContextService>();
-            container.register_scoped<ComponentFactory>();
-
-            container.register_scoped<Authorisation.AuthorisationService>();
-            container.register_scoped<Authorisation.AuthorisationPipelineComponent>()
-                .as<PipelineComponent>();
-
-            container.register_startup<ContinuationProvider>()
-                .as<Endpoint>()
-                .with_metadata<EndpointRoute>(new EndpointRoute("/_spry/cnu/{token}"));
-
-            container.register_startup<StaticResourceProvider>()
-                .as<Endpoint>()
-                .with_metadata<EndpointRoute>(new EndpointRoute("/_spry/res/{resource}"));
-
-            container.register_scoped<ComponentEndpoint>()
-                .as<Endpoint>()
-                .with_metadata<EndpointRoute>(new EndpointRoute("/_spry/com/{component-id}/{action}"))
-                .with_metadata<EndpointRoute>(new EndpointRoute("/_spry/com/{component-id}/{action}/{context}"));
-
-            container.register_startup<Static.HtmxResource>()
-                .as<Spry.StaticResource>();
-            container.register_startup<Static.HtmxSseResource>()
-                .as<Spry.StaticResource>();
-        }
-
-    }
-
-    public class SpryConfigurator : Object {
-
-        private Container container = inject<Container>();
-
-        public void add_template<T>(string prefix) {
-            container.register_transient<T>()
-                .as<PageTemplate> ()
-                .with_metadata<TemplateRoutePrefix>(new TemplateRoutePrefix(prefix));
-        }
-
-        public void add_page<T>(EndpointRoute route) {
-            container.register_scoped<T>()
-                .as<Endpoint>()
-                .with_metadata<EndpointRoute>(route);
-        }
-
-        public void add_resource<T>() {
-            container.register_startup<T>()
-                .as<Spry.StaticResource>();
-        }
-
-        public void add_component<T>() {
-            container.register_transient<T>();
-        }
-
-
-    }
-
-}

+ 32 - 0
src/SpryModule.vala

@@ -0,0 +1,32 @@
+using InvercargillSqlInversion;
+using Inversion;
+
+namespace Spry {
+
+	/**
+	 * Inversion module that registers Spry's user store: the `spry_users` and
+	 * `spry_user_permissions` schema (M0001 migration), the entity/projection
+	 * mappings, and the scoped {@link Spry.Authentication.UserService}.
+	 *
+	 * Register this module with the application container alongside
+	 * `StatumModule`; it registers no endpoints. Ready-made actions are bound
+	 * separately via {@link SpryAuth.register_actions} or
+	 * `StatumConfigurator.action`.
+	 */
+	public class SpryModule : Object, Module {
+
+		public void register_components(Container container) throws Error {
+			// Sql table setup
+			var sql = container.configure_with<DatabaseConfigurator>();
+			sql.add_migration<Authentication.Migrations.M0001_Initial>();
+			sql.add_entity<Authentication.UserEntity>(Authentication.UserEntity.entity_mapping);
+			sql.add_entity<Authentication.UserPermissionEntity>(Authentication.UserPermissionEntity.entity_mapping);
+			sql.add_projection<Authentication.UserProjection>(Authentication.UserProjection.projection_mapping);
+
+			// Service setup
+			container.register_scoped<Authentication.UserService>();
+		}
+
+	}
+
+}

+ 0 - 32
src/Static/ConstantStaticResource.vala

@@ -1,32 +0,0 @@
-using Inversion;
-using Astralis;
-using Invercargill;
-
-namespace Spry {
-
-    public abstract class ConstantStaticResource : Object, StaticResource {
-
-
-        public abstract string name { get; }
-        public abstract string file_hash { get; }
-        public abstract string content_type { get; }
-
-        public abstract string get_best_encoding (Set<string> supported);
-        public abstract unowned uint8[] get_encoding(string encoding);
-
-        public string get_etag_for (string encoding) {
-            return @"\"$encoding-$file_hash\"";
-        }
-
-        public HttpResult to_result(string encoding, StatusCode status = StatusCode.OK) throws Error {
-            var result = new HttpDataResult(Wrap.byte_array (get_encoding(encoding)));
-
-            result.set_header("Content-Type", content_type);
-            result.set_header("Content-Encoding", encoding);
-            result.set_header("ETag", get_etag_for(encoding));
-            return result;
-        }
-
-
-    }
-}

+ 0 - 126
src/Static/FileStaticResource.vala

@@ -1,126 +0,0 @@
-using Inversion;
-using Astralis;
-using Invercargill;
-using Invercargill.DataStructures;
-
-namespace Spry {
-
-    public class FileStaticResource : Object, StaticResource {
-
-        private string _name;
-        private string _content_type;
-        private string _e_tag;
-        private ImmutableBuffer<EncodingHeader> _encodings;
-        private Dictionary<string, EncodingHeader> _encoding_mapping;
-
-        public string file_path { get; private set; }
-        public uint64 header_length { get; private set; }
-
-        public FileStaticResource(string path) throws Error {
-            this.file_path = path;
-            var stream = new DataInputStream(File.new_for_path(path).read());
-            read_header(stream);
-            stream.close();
-        }
-
-        public string get_best_encoding (Set<string> supported) {
-            return _encodings.first_or_default(e => supported.has(e.type))?.type ?? "identity";
-        }
-
-        public HttpResult to_result(string encoding, StatusCode status = StatusCode.OK) throws Error {
-            return new StreamingResult(this, _encoding_mapping[encoding], status);
-        }
-
-        public string name { get { return _name; } }
-        public string content_type { get { return _content_type; } }
-        
-        public string get_etag_for (string encoding) {
-            return @"\"$encoding-$_e_tag\"";
-        }
-
-        private void read_header(DataInputStream stream) throws Error {
-            var magic = new uint8[8];
-            stream.read(magic);
-
-            if(!Wrap.array(magic).equals(Iterate.these<uint8>('s', 'p', 'r', 'y', '-', 's', 'r', 0))) {
-                throw new IOError.INVALID_DATA("Incorrect magic number on Spry Static Resource file.");
-            }
-
-            _name = read_string_field(stream);
-            _content_type = read_string_field(stream);
-            
-            var hash_len = (size_t)64;
-            var hash_composition = new ByteComposition();
-            while(hash_composition.read_in (stream.read_bytes(hash_len), ref hash_len));
-            _e_tag = hash_composition.to_base64();
-
-            var encodings = new Buffer<EncodingHeader>(stream.read_byte());
-            for(var i = 0; i < encodings.length; i++) {
-                encodings[i] = new EncodingHeader(stream);
-            }
-
-            _encodings = encodings
-                .order_by<uint64?>(e => e.size)
-                .to_immutable_buffer();
-
-            _encoding_mapping = encodings
-                .to_dictionary<string>(e => e.type);
-
-            header_length = stream.tell();
-
-            if(!_encoding_mapping.has("identity")) {
-                throw new IOError.INVALID_DATA("Spry Static Resource file does not contain required \'identity\' encoding.");
-            }
-        }
-
-        private static string read_string_field(DataInputStream stream) throws Error {
-            var len = (size_t)stream.read_byte();
-            var composition = new ByteComposition();
-            while(composition.read_in (stream.read_bytes(len), ref len));
-            return composition.to_raw_string();
-        }
-
-        private class EncodingHeader {
-            public string type;
-            public uint64 offset;
-            public uint64 size;
-
-            public EncodingHeader(DataInputStream stream) throws Error {
-                type = read_string_field(stream);
-                offset = stream.read_uint64();
-                size = stream.read_uint64();
-            }
-        }
-
-        private class StreamingResult : HttpResult {
-
-                private FileStaticResource resource;
-                private EncodingHeader encoding;
-
-                public StreamingResult(FileStaticResource resource, EncodingHeader encoding, StatusCode status) {
-                    base(status);
-                    this.resource = resource;
-                    this.encoding = encoding;
-                    set_header("Content-Type", resource.content_type);
-                    set_header("Content-Encoding", encoding.type);
-                    set_header("Content-Length", encoding.size.to_string());
-                    set_header("ETag", resource.get_etag_for(encoding.type));
-                }
-
-                public async override void send_body(Astralis.AsyncOutput output) throws Error {
-                    var stream = yield File.new_for_path(resource.file_path).read_async();
-                    var data_len = encoding.size;
-                    stream.seek((int64)resource.header_length, SeekType.SET);
-                    
-                    while(data_len > 0) {
-                        var to_read = (size_t)uint64.min(data_len, 1024 * 1024 * 4);
-                        var bytes = yield stream.read_bytes_async(to_read);
-                        data_len -= bytes.length;
-                        yield output.write(Wrap.bytes(bytes));
-                    }
-                }
-
-        }
-
-    }
-}

Разница между файлами не показана из-за своего большого размера
+ 0 - 7
src/Static/Htmx.vala


+ 0 - 6221
src/Static/HtmxResource.vala

@@ -1,6221 +0,0 @@
-using Spry;
-using Invercargill;
-
-namespace Spry.Static {
-
-    // Generated by spry-mkssr
-    public class HtmxResource : ConstantStaticResource {
-
-        public override string name { get { return "htmx.js"; } }
-        public override string file_hash { get { return "0865c59c336fe6ae3c72215e23258571f661a985b4b120623cef876433b75cb33ea7cc6385ecf3e420b1b645d50ca7c26ef17e89485e97bc68792a75f68ef1ee"; } }
-        public override string content_type { get { return "text/javascript"; } }
-
-        public override string get_best_encoding(Set<string> supported) {
-            if (supported.has("br")) return "br";
-            if (supported.has("zstd")) return "zstd";
-            if (supported.has("gzip")) return "gzip";
-            return "identity";
-        }
-
-        public override unowned uint8[] get_encoding(string encoding) {
-            switch (encoding) {
-                case "identity": return IDENTITY_DATA;
-                case "gzip": return GZIP_DATA;
-                case "zstd": return ZSTD_DATA;
-                case "br": return BR_DATA;
-                default: return IDENTITY_DATA;
-            }
-        }
-
-        private const uint8[] IDENTITY_DATA = {
-            0x76, 0x61, 0x72, 0x20, 0x68, 0x74, 0x6d, 0x78, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x28, 0x29, 0x7b, 0x22, 0x75, 0x73, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x22,
-            0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x51, 0x3d, 0x7b, 0x6f, 0x6e, 0x4c, 0x6f, 0x61, 0x64,
-            0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x6e, 0x75,
-            0x6c, 0x6c, 0x2c, 0x6f, 0x6e, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6f, 0x66, 0x66, 0x3a, 0x6e,
-            0x75, 0x6c, 0x6c, 0x2c, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x3a, 0x6e, 0x75, 0x6c, 0x6c,
-            0x2c, 0x61, 0x6a, 0x61, 0x78, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x66, 0x69, 0x6e, 0x64, 0x3a,
-            0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x66, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x3a, 0x6e, 0x75, 0x6c,
-            0x6c, 0x2c, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x76,
-            0x61, 0x6c, 0x75, 0x65, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65,
-            0x2c, 0x74, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x64, 0x6e, 0x28, 0x65,
-            0x2c, 0x74, 0x7c, 0x7c, 0x22, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x7d, 0x2c, 0x72, 0x65, 0x6d,
-            0x6f, 0x76, 0x65, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x61, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73,
-            0x73, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61,
-            0x73, 0x73, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x43, 0x6c,
-            0x61, 0x73, 0x73, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x74, 0x61, 0x6b, 0x65, 0x43, 0x6c, 0x61,
-            0x73, 0x73, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x73, 0x77, 0x61, 0x70, 0x3a, 0x6e, 0x75, 0x6c,
-            0x6c, 0x2c, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
-            0x6e, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x45, 0x78, 0x74,
-            0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6c, 0x6f, 0x67, 0x41,
-            0x6c, 0x6c, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6c, 0x6f, 0x67, 0x4e, 0x6f, 0x6e, 0x65, 0x3a,
-            0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x72, 0x3a, 0x6e, 0x75, 0x6c, 0x6c,
-            0x2c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x7b, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
-            0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x68, 0x69, 0x73,
-            0x74, 0x6f, 0x72, 0x79, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x30,
-            0x2c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4f, 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72,
-            0x79, 0x4d, 0x69, 0x73, 0x73, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x64, 0x65, 0x66, 0x61,
-            0x75, 0x6c, 0x74, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x3a, 0x22, 0x69, 0x6e,
-            0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x22, 0x2c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
-            0x53, 0x77, 0x61, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x3a, 0x30, 0x2c, 0x64, 0x65, 0x66, 0x61,
-            0x75, 0x6c, 0x74, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x3a, 0x32,
-            0x30, 0x2c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74,
-            0x6f, 0x72, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x69, 0x6e,
-            0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3a, 0x22, 0x68, 0x74,
-            0x6d, 0x78, 0x2d, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x2c, 0x72, 0x65,
-            0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3a, 0x22, 0x68, 0x74, 0x6d, 0x78,
-            0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2c, 0x61, 0x64, 0x64, 0x65, 0x64, 0x43,
-            0x6c, 0x61, 0x73, 0x73, 0x3a, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x2d, 0x61, 0x64, 0x64, 0x65, 0x64,
-            0x22, 0x2c, 0x73, 0x65, 0x74, 0x74, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3a,
-            0x22, 0x68, 0x74, 0x6d, 0x78, 0x2d, 0x73, 0x65, 0x74, 0x74, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x2c,
-            0x73, 0x77, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3a, 0x22, 0x68,
-            0x74, 0x6d, 0x78, 0x2d, 0x73, 0x77, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x22, 0x2c, 0x61, 0x6c,
-            0x6c, 0x6f, 0x77, 0x45, 0x76, 0x61, 0x6c, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x61, 0x6c, 0x6c,
-            0x6f, 0x77, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x54, 0x61, 0x67, 0x73, 0x3a, 0x74, 0x72, 0x75,
-            0x65, 0x2c, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4e, 0x6f,
-            0x6e, 0x63, 0x65, 0x3a, 0x22, 0x22, 0x2c, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x79,
-            0x6c, 0x65, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x3a, 0x22, 0x22, 0x2c, 0x61, 0x74, 0x74, 0x72, 0x69,
-            0x62, 0x75, 0x74, 0x65, 0x73, 0x54, 0x6f, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x3a, 0x5b, 0x22,
-            0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x22, 0x2c, 0x22,
-            0x77, 0x69, 0x64, 0x74, 0x68, 0x22, 0x2c, 0x22, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x5d,
-            0x2c, 0x77, 0x69, 0x74, 0x68, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
-            0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x3a, 0x30,
-            0x2c, 0x77, 0x73, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x44, 0x65, 0x6c, 0x61,
-            0x79, 0x3a, 0x22, 0x66, 0x75, 0x6c, 0x6c, 0x2d, 0x6a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x22, 0x2c,
-            0x77, 0x73, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x62, 0x6c,
-            0x6f, 0x62, 0x22, 0x2c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63,
-            0x74, 0x6f, 0x72, 0x3a, 0x22, 0x5b, 0x68, 0x78, 0x2d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
-            0x5d, 0x2c, 0x20, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x64, 0x69, 0x73, 0x61,
-            0x62, 0x6c, 0x65, 0x5d, 0x22, 0x2c, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x42, 0x65, 0x68, 0x61,
-            0x76, 0x69, 0x6f, 0x72, 0x3a, 0x22, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x22, 0x2c, 0x64,
-            0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x53, 0x63, 0x72, 0x6f, 0x6c,
-            0x6c, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x67, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65,
-            0x42, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x3a, 0x66, 0x61, 0x6c, 0x73,
-            0x65, 0x2c, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x54, 0x72, 0x61, 0x6e,
-            0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x6d, 0x65,
-            0x74, 0x68, 0x6f, 0x64, 0x73, 0x54, 0x68, 0x61, 0x74, 0x55, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x50,
-            0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x5b, 0x22, 0x67, 0x65, 0x74, 0x22, 0x2c, 0x22, 0x64, 0x65,
-            0x6c, 0x65, 0x74, 0x65, 0x22, 0x5d, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65,
-            0x73, 0x74, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x69, 0x67, 0x6e,
-            0x6f, 0x72, 0x65, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x73,
-            0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x6f, 0x56, 0x69, 0x65, 0x77, 0x4f, 0x6e, 0x42,
-            0x6f, 0x6f, 0x73, 0x74, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
-            0x72, 0x53, 0x70, 0x65, 0x63, 0x73, 0x43, 0x61, 0x63, 0x68, 0x65, 0x3a, 0x6e, 0x75, 0x6c, 0x6c,
-            0x2c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x61,
-            0x6e, 0x63, 0x65, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-            0x73, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x3a, 0x5b, 0x7b, 0x63, 0x6f, 0x64,
-            0x65, 0x3a, 0x22, 0x32, 0x30, 0x34, 0x22, 0x2c, 0x73, 0x77, 0x61, 0x70, 0x3a, 0x66, 0x61, 0x6c,
-            0x73, 0x65, 0x7d, 0x2c, 0x7b, 0x63, 0x6f, 0x64, 0x65, 0x3a, 0x22, 0x5b, 0x32, 0x33, 0x5d, 0x2e,
-            0x2e, 0x22, 0x2c, 0x73, 0x77, 0x61, 0x70, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x2c, 0x7b, 0x63,
-            0x6f, 0x64, 0x65, 0x3a, 0x22, 0x5b, 0x34, 0x35, 0x5d, 0x2e, 0x2e, 0x22, 0x2c, 0x73, 0x77, 0x61,
-            0x70, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x74, 0x72,
-            0x75, 0x65, 0x7d, 0x5d, 0x2c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64,
-            0x4f, 0x6f, 0x62, 0x53, 0x77, 0x61, 0x70, 0x73, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x68, 0x69,
-            0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x41, 0x73, 0x48, 0x78,
-            0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x72, 0x65, 0x70,
-            0x6f, 0x72, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x69, 0x74, 0x79, 0x4f, 0x66, 0x46, 0x6f, 0x72,
-            0x6d, 0x73, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x2c, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49,
-            0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6c, 0x6f, 0x63,
-            0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x5f,
-            0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x22, 0x32,
-            0x2e, 0x30, 0x2e, 0x38, 0x22, 0x7d, 0x3b, 0x51, 0x2e, 0x6f, 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x3d,
-            0x56, 0x3b, 0x51, 0x2e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x3d, 0x46, 0x74, 0x3b, 0x51,
-            0x2e, 0x6f, 0x6e, 0x3d, 0x78, 0x65, 0x3b, 0x51, 0x2e, 0x6f, 0x66, 0x66, 0x3d, 0x62, 0x65, 0x3b,
-            0x51, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x3d, 0x61, 0x65, 0x3b, 0x51, 0x2e, 0x61,
-            0x6a, 0x61, 0x78, 0x3d, 0x4c, 0x6e, 0x3b, 0x51, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x3d, 0x66, 0x3b,
-            0x51, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x3d, 0x78, 0x3b, 0x51, 0x2e, 0x63, 0x6c,
-            0x6f, 0x73, 0x65, 0x73, 0x74, 0x3d, 0x67, 0x3b, 0x51, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65,
-            0x3d, 0x5f, 0x3b, 0x51, 0x2e, 0x61, 0x64, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x4b, 0x3b,
-            0x51, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x47, 0x3b,
-            0x51, 0x2e, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x57, 0x3b,
-            0x51, 0x2e, 0x74, 0x61, 0x6b, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x5a, 0x3b, 0x51, 0x2e,
-            0x73, 0x77, 0x61, 0x70, 0x3d, 0x7a, 0x65, 0x3b, 0x51, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65,
-            0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x5f, 0x6e, 0x3b, 0x51, 0x2e, 0x72,
-            0x65, 0x6d, 0x6f, 0x76, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x7a,
-            0x6e, 0x3b, 0x51, 0x2e, 0x6c, 0x6f, 0x67, 0x41, 0x6c, 0x6c, 0x3d, 0x6a, 0x3b, 0x51, 0x2e, 0x6c,
-            0x6f, 0x67, 0x4e, 0x6f, 0x6e, 0x65, 0x3d, 0x24, 0x3b, 0x51, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65,
-            0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x3d, 0x64, 0x3b, 0x51, 0x2e, 0x5f, 0x3d, 0x65,
-            0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x7b, 0x61, 0x64, 0x64, 0x54, 0x72, 0x69,
-            0x67, 0x67, 0x65, 0x72, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x3a, 0x53, 0x74, 0x2c, 0x62,
-            0x6f, 0x64, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x3a, 0x73, 0x65, 0x2c, 0x63,
-            0x61, 0x6e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x74, 0x6f,
-            0x72, 0x61, 0x67, 0x65, 0x3a, 0x58, 0x2c, 0x66, 0x69, 0x6e, 0x64, 0x54, 0x68, 0x69, 0x73, 0x45,
-            0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x53, 0x65, 0x2c, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
-            0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x3a, 0x79, 0x6e, 0x2c, 0x73, 0x77, 0x61, 0x70, 0x3a, 0x7a,
-            0x65, 0x2c, 0x68, 0x61, 0x73, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x3a, 0x73,
-            0x2c, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c,
-            0x75, 0x65, 0x3a, 0x61, 0x2c, 0x67, 0x65, 0x74, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x41,
-            0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x6e, 0x65,
-            0x2c, 0x67, 0x65, 0x74, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68,
-            0x3a, 0x71, 0x2c, 0x67, 0x65, 0x74, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
-            0x56, 0x61, 0x72, 0x73, 0x3a, 0x52, 0x6e, 0x2c, 0x67, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65,
-            0x72, 0x73, 0x3a, 0x6d, 0x6e, 0x2c, 0x67, 0x65, 0x74, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x56, 0x61,
-            0x6c, 0x75, 0x65, 0x73, 0x3a, 0x64, 0x6e, 0x2c, 0x67, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72,
-            0x6e, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x3a, 0x6f, 0x65, 0x2c, 0x67, 0x65, 0x74, 0x53, 0x77,
-            0x61, 0x70, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
-            0x62, 0x6e, 0x2c, 0x67, 0x65, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x70, 0x65,
-            0x63, 0x73, 0x3a, 0x73, 0x74, 0x2c, 0x67, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a,
-            0x45, 0x65, 0x2c, 0x6d, 0x61, 0x6b, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x3a,
-            0x44, 0x2c, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x3a, 0x6c,
-            0x65, 0x2c, 0x6d, 0x61, 0x6b, 0x65, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f,
-            0x3a, 0x53, 0x6e, 0x2c, 0x6f, 0x6f, 0x62, 0x53, 0x77, 0x61, 0x70, 0x3a, 0x54, 0x65, 0x2c, 0x71,
-            0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x3a,
-            0x75, 0x65, 0x2c, 0x73, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x49, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61,
-            0x74, 0x65, 0x6c, 0x79, 0x3a, 0x59, 0x74, 0x2c, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x43, 0x61,
-            0x6e, 0x63, 0x65, 0x6c, 0x3a, 0x68, 0x74, 0x2c, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45,
-            0x76, 0x65, 0x6e, 0x74, 0x3a, 0x61, 0x65, 0x2c, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45,
-            0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x3a, 0x66, 0x65, 0x2c, 0x77, 0x69, 0x74,
-            0x68, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x56, 0x74, 0x7d, 0x3b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x64, 0x65, 0x3d, 0x5b, 0x22, 0x67, 0x65, 0x74, 0x22, 0x2c,
-            0x22, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x2c, 0x22, 0x70, 0x75, 0x74, 0x22, 0x2c, 0x22, 0x64, 0x65,
-            0x6c, 0x65, 0x74, 0x65, 0x22, 0x2c, 0x22, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0x5d, 0x3b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x52, 0x3d, 0x64, 0x65, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x22, 0x5b, 0x68, 0x78, 0x2d, 0x22, 0x2b, 0x65, 0x2b, 0x22, 0x5d, 0x2c, 0x20, 0x5b, 0x64, 0x61,
-            0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x22, 0x2b, 0x65, 0x2b, 0x22, 0x5d, 0x22, 0x7d, 0x29, 0x2e,
-            0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x29, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x64, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x3d, 0x3d, 0x75,
-            0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x7d, 0x6c, 0x65, 0x74, 0x20, 0x74,
-            0x3d, 0x4e, 0x61, 0x4e, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28,
-            0x2d, 0x32, 0x29, 0x3d, 0x3d, 0x22, 0x6d, 0x73, 0x22, 0x29, 0x7b, 0x74, 0x3d, 0x70, 0x61, 0x72,
-            0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x65, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28,
-            0x30, 0x2c, 0x2d, 0x32, 0x29, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x65,
-            0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x2d, 0x31, 0x29, 0x3d, 0x3d, 0x22, 0x73, 0x22, 0x29,
-            0x7b, 0x74, 0x3d, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x65, 0x2e,
-            0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2c, 0x2d, 0x31, 0x29, 0x29, 0x2a, 0x31, 0x65, 0x33,
-            0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65,
-            0x28, 0x2d, 0x31, 0x29, 0x3d, 0x3d, 0x22, 0x6d, 0x22, 0x29, 0x7b, 0x74, 0x3d, 0x70, 0x61, 0x72,
-            0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x65, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28,
-            0x30, 0x2c, 0x2d, 0x31, 0x29, 0x29, 0x2a, 0x31, 0x65, 0x33, 0x2a, 0x36, 0x30, 0x7d, 0x65, 0x6c,
-            0x73, 0x65, 0x7b, 0x74, 0x3d, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28,
-            0x65, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28,
-            0x74, 0x29, 0x3f, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x3a, 0x74, 0x7d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x65, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
-            0x65, 0x6f, 0x66, 0x20, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x26, 0x26, 0x65, 0x2e, 0x67,
-            0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x74, 0x29, 0x7d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, 0x21, 0x65, 0x2e, 0x68, 0x61, 0x73, 0x41, 0x74, 0x74, 0x72,
-            0x69, 0x62, 0x75, 0x74, 0x65, 0x26, 0x26, 0x28, 0x65, 0x2e, 0x68, 0x61, 0x73, 0x41, 0x74, 0x74,
-            0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x74, 0x29, 0x7c, 0x7c, 0x65, 0x2e, 0x68, 0x61, 0x73,
-            0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x64, 0x61, 0x74, 0x61, 0x2d,
-            0x22, 0x2b, 0x74, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
-            0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x65, 0x28,
-            0x65, 0x2c, 0x74, 0x29, 0x7c, 0x7c, 0x65, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x64, 0x61, 0x74, 0x61,
-            0x2d, 0x22, 0x2b, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75,
-            0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x65, 0x2e, 0x70, 0x61,
-            0x72, 0x65, 0x6e, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x21,
-            0x74, 0x26, 0x26, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x20,
-            0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x53, 0x68, 0x61, 0x64, 0x6f,
-            0x77, 0x52, 0x6f, 0x6f, 0x74, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x70,
-            0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x65, 0x28, 0x29,
-            0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
-            0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x79, 0x28, 0x65, 0x2c, 0x74, 0x29,
-            0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x6f, 0x6f,
-            0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3f, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x4e,
-            0x6f, 0x64, 0x65, 0x28, 0x7b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x3a, 0x74, 0x7d,
-            0x29, 0x3a, 0x74, 0x65, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-            0x71, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x65, 0x26, 0x26,
-            0x21, 0x74, 0x28, 0x65, 0x29, 0x29, 0x7b, 0x65, 0x3d, 0x75, 0x28, 0x65, 0x29, 0x7d, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7c, 0x7c, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x61, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x3b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x61, 0x28, 0x74, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x64, 0x69,
-            0x73, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x22, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x69,
-            0x3d, 0x61, 0x28, 0x74, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74,
-            0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x21, 0x3d, 0x3d, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
-            0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x69, 0x26, 0x26, 0x28, 0x69, 0x3d, 0x3d, 0x3d, 0x22, 0x2a, 0x22, 0x7c, 0x7c, 0x69, 0x2e, 0x73,
-            0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, 0x20, 0x22, 0x29, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f,
-            0x66, 0x28, 0x6e, 0x29, 0x3e, 0x3d, 0x30, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x72, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e,
-            0x75, 0x6c, 0x6c, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x6f, 0x26, 0x26, 0x28, 0x6f, 0x3d, 0x3d, 0x3d,
-            0x22, 0x2a, 0x22, 0x7c, 0x7c, 0x6f, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, 0x20, 0x22,
-            0x29, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x6e, 0x29, 0x3e, 0x3d, 0x30, 0x29,
-            0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x75, 0x6e, 0x73, 0x65, 0x74, 0x22, 0x7d,
-            0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x72,
-            0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x71, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, 0x21, 0x28, 0x72,
-            0x3d, 0x6f, 0x28, 0x74, 0x2c, 0x63, 0x65, 0x28, 0x65, 0x29, 0x2c, 0x6e, 0x29, 0x29, 0x7d, 0x29,
-            0x3b, 0x69, 0x66, 0x28, 0x72, 0x21, 0x3d, 0x3d, 0x22, 0x75, 0x6e, 0x73, 0x65, 0x74, 0x22, 0x29,
-            0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x68, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x45,
-            0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x26, 0x26, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65,
-            0x73, 0x28, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x28,
-            0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x2f, 0x3c, 0x28, 0x5b, 0x61,
-            0x2d, 0x7a, 0x5d, 0x5b, 0x5e, 0x5c, 0x2f, 0x5c, 0x30, 0x3e, 0x5c, 0x78, 0x32, 0x30, 0x5c, 0x74,
-            0x5c, 0x72, 0x5c, 0x6e, 0x5c, 0x66, 0x5d, 0x2a, 0x29, 0x2f, 0x69, 0x3b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x6e, 0x3d, 0x74, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x5b, 0x31, 0x5d, 0x2e,
-            0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x43, 0x61, 0x73, 0x65, 0x28, 0x29, 0x7d, 0x65, 0x6c,
-            0x73, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x22, 0x7d, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4c, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x22, 0x70,
-            0x61, 0x72, 0x73, 0x65, 0x48, 0x54, 0x4d, 0x4c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x22, 0x69,
-            0x6e, 0x20, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x73,
-            0x65, 0x48, 0x54, 0x4d, 0x4c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x28, 0x65, 0x29, 0x7d, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x4f, 0x4d, 0x50, 0x61,
-            0x72, 0x73, 0x65, 0x72, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x70, 0x61,
-            0x72, 0x73, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x65, 0x2c,
-            0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x29, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x77, 0x68, 0x69,
-            0x6c, 0x65, 0x28, 0x74, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x2e,
-            0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x29, 0x7b, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x65,
-            0x6e, 0x64, 0x28, 0x74, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x5b,
-            0x30, 0x5d, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28,
-            0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x74, 0x65, 0x28, 0x29, 0x2e,
-            0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x73,
-            0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x65, 0x2e, 0x61, 0x74, 0x74,
-            0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x28, 0x65, 0x29, 0x7b, 0x74, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
-            0x74, 0x65, 0x28, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75,
-            0x65, 0x29, 0x7d, 0x29, 0x3b, 0x74, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65,
-            0x6e, 0x74, 0x3d, 0x65, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-            0x3b, 0x74, 0x2e, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x69,
-            0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x69, 0x6e, 0x6c, 0x69, 0x6e,
-            0x65, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x29, 0x7b, 0x74, 0x2e,
-            0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x3d, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x69,
-            0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65,
-            0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x69, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65,
-            0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x22, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
-            0x22, 0x29, 0x26, 0x26, 0x28, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x74,
-            0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x7c,
-            0x7c, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x6d, 0x6f, 0x64, 0x75, 0x6c,
-            0x65, 0x22, 0x7c, 0x7c, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x22, 0x29,
-            0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x28, 0x65, 0x29, 0x7b, 0x41,
-            0x72, 0x72, 0x61, 0x79, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x28, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72,
-            0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x22, 0x73, 0x63,
-            0x72, 0x69, 0x70, 0x74, 0x22, 0x29, 0x29, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28,
-            0x65, 0x3d, 0x3e, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x28, 0x65, 0x29, 0x29, 0x7b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x74, 0x3d, 0x72, 0x28, 0x65, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x6e, 0x3d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3b, 0x74,
-            0x72, 0x79, 0x7b, 0x6e, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72,
-            0x65, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x7b,
-            0x48, 0x28, 0x65, 0x29, 0x7d, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x7b, 0x65, 0x2e, 0x72,
-            0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x7d, 0x7d, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x74, 0x3d, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x3c, 0x68, 0x65,
-            0x61, 0x64, 0x28, 0x5c, 0x73, 0x5b, 0x5e, 0x3e, 0x5d, 0x2a, 0x29, 0x3f, 0x3e, 0x5b, 0x5c, 0x73,
-            0x5c, 0x53, 0x5d, 0x2a, 0x3f, 0x3c, 0x5c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x2f, 0x69, 0x2c,
-            0x22, 0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x41, 0x28, 0x74, 0x29,
-            0x3b, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x3d, 0x3d, 0x3d, 0x22, 0x68,
-            0x74, 0x6d, 0x6c, 0x22, 0x29, 0x7b, 0x72, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x6f, 0x63, 0x75,
-            0x6d, 0x65, 0x6e, 0x74, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x3b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x69, 0x3d, 0x4c, 0x28, 0x65, 0x29, 0x3b, 0x4e, 0x28, 0x72, 0x2c, 0x69, 0x2e,
-            0x62, 0x6f, 0x64, 0x79, 0x29, 0x3b, 0x72, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x69, 0x2e,
-            0x74, 0x69, 0x74, 0x6c, 0x65, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x6e, 0x3d,
-            0x3d, 0x3d, 0x22, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x29, 0x7b, 0x72, 0x3d, 0x6e, 0x65, 0x77, 0x20,
-            0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74,
-            0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x4c, 0x28, 0x74, 0x29, 0x3b, 0x4e, 0x28,
-            0x72, 0x2c, 0x69, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x29, 0x3b, 0x72, 0x2e, 0x74, 0x69, 0x74, 0x6c,
-            0x65, 0x3d, 0x69, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x4c, 0x28, 0x27, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e,
-            0x3c, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d,
-            0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2d, 0x68, 0x74, 0x6d, 0x78, 0x2d, 0x77,
-            0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x22, 0x3e, 0x27, 0x2b, 0x74, 0x2b, 0x22, 0x3c, 0x2f, 0x74,
-            0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x22,
-            0x29, 0x3b, 0x72, 0x3d, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63,
-            0x74, 0x6f, 0x72, 0x28, 0x22, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x29, 0x2e,
-            0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3b, 0x72, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d,
-            0x69, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x72, 0x2e,
-            0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x28, 0x22, 0x74,
-            0x69, 0x74, 0x6c, 0x65, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6f, 0x26, 0x26, 0x6f, 0x2e, 0x70,
-            0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3d, 0x3d, 0x3d, 0x72, 0x29, 0x7b, 0x6f,
-            0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x3b, 0x72, 0x2e, 0x74, 0x69, 0x74, 0x6c,
-            0x65, 0x3d, 0x6f, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x65, 0x78, 0x74, 0x7d, 0x7d, 0x69,
-            0x66, 0x28, 0x72, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-            0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x54, 0x61, 0x67, 0x73,
-            0x29, 0x7b, 0x49, 0x28, 0x72, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x2e, 0x71, 0x75,
-            0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x22,
-            0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x29, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68,
-            0x28, 0x65, 0x3d, 0x3e, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x29, 0x7d,
-            0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x72, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x29, 0x7b, 0x65,
-            0x28, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x65,
-            0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4f, 0x62, 0x6a, 0x65, 0x63,
-            0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x74, 0x6f, 0x53, 0x74,
-            0x72, 0x69, 0x6e, 0x67, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x65, 0x29, 0x3d, 0x3d, 0x3d, 0x22,
-            0x5b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x22, 0x2b, 0x74, 0x2b, 0x22, 0x5d, 0x22, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x65, 0x3d, 0x3d, 0x3d,
-            0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x6b, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x74, 0x28, 0x65, 0x2c, 0x22, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x29, 0x7d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x74, 0x3d, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x72,
-            0x6e, 0x61, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x3d,
-            0x65, 0x5b, 0x74, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x6e, 0x29, 0x7b, 0x6e, 0x3d, 0x65, 0x5b,
-            0x74, 0x5d, 0x3d, 0x7b, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4d, 0x28, 0x74, 0x29, 0x7b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x6e, 0x3d, 0x5b, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x66, 0x6f,
-            0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65, 0x3c, 0x74, 0x2e, 0x6c, 0x65,
-            0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68,
-            0x28, 0x74, 0x5b, 0x65, 0x5d, 0x29, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e,
-            0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x65, 0x28, 0x74, 0x2c, 0x6e,
-            0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20,
-            0x65, 0x3d, 0x30, 0x3b, 0x65, 0x3c, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65,
-            0x2b, 0x2b, 0x29, 0x7b, 0x6e, 0x28, 0x74, 0x5b, 0x65, 0x5d, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x74, 0x3d, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e,
-            0x67, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x74, 0x28, 0x29, 0x3b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x74, 0x2e, 0x74, 0x6f, 0x70, 0x3b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x72, 0x3d, 0x74, 0x2e, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3c, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x69, 0x6e, 0x6e,
-            0x65, 0x72, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x26, 0x26, 0x72, 0x3e, 0x3d, 0x30, 0x7d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x4e, 0x6f,
-            0x64, 0x65, 0x28, 0x7b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x3a, 0x74, 0x72, 0x75,
-            0x65, 0x7d, 0x29, 0x3d, 0x3d, 0x3d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x7d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x2e, 0x73, 0x70, 0x6c,
-            0x69, 0x74, 0x28, 0x2f, 0x5c, 0x73, 0x2b, 0x2f, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x6c, 0x65, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x74, 0x2e, 0x68, 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79,
-            0x28, 0x6e, 0x29, 0x29, 0x7b, 0x65, 0x5b, 0x6e, 0x5d, 0x3d, 0x74, 0x5b, 0x6e, 0x5d, 0x7d, 0x7d,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x76, 0x28, 0x65, 0x29, 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x28, 0x65, 0x29, 0x7d,
-            0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x7b, 0x48, 0x28, 0x65, 0x29, 0x3b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x58, 0x28, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d,
-            0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x6f,
-            0x72, 0x61, 0x67, 0x65, 0x54, 0x65, 0x73, 0x74, 0x22, 0x3b, 0x74, 0x72, 0x79, 0x7b, 0x73, 0x65,
-            0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x73, 0x65, 0x74,
-            0x49, 0x74, 0x65, 0x6d, 0x28, 0x65, 0x2c, 0x65, 0x29, 0x3b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
-            0x6e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49,
-            0x74, 0x65, 0x6d, 0x28, 0x65, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72,
-            0x75, 0x65, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x55, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d,
-            0x6e, 0x65, 0x77, 0x20, 0x55, 0x52, 0x4c, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a,
-            0x2f, 0x2f, 0x78, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x65, 0x3d, 0x74, 0x2e,
-            0x70, 0x61, 0x74, 0x68, 0x6e, 0x61, 0x6d, 0x65, 0x2b, 0x74, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63,
-            0x68, 0x7d, 0x69, 0x66, 0x28, 0x65, 0x21, 0x3d, 0x22, 0x2f, 0x22, 0x29, 0x7b, 0x65, 0x3d, 0x65,
-            0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x5c, 0x2f, 0x2b, 0x24, 0x2f, 0x2c,
-            0x22, 0x22, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x4f, 0x6e, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x65, 0x76, 0x61, 0x6c, 0x28, 0x65, 0x29, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x56, 0x28, 0x74, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65,
-            0x3d, 0x51, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x6c, 0x6f, 0x61, 0x64,
-            0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x74, 0x28,
-            0x65, 0x2e, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x2e, 0x65, 0x6c, 0x74, 0x29, 0x7d, 0x29, 0x3b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x6a, 0x28, 0x29, 0x7b, 0x51, 0x2e, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x72, 0x3d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x69,
-            0x66, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
-            0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x6e, 0x29, 0x7d, 0x7d, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x24, 0x28, 0x29, 0x7b, 0x51, 0x2e, 0x6c,
-            0x6f, 0x67, 0x67, 0x65, 0x72, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x66, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x79,
-            0x70, 0x65, 0x6f, 0x66, 0x20, 0x65, 0x21, 0x3d, 0x3d, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
-            0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72,
-            0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x28, 0x74, 0x29, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2c,
-            0x65, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x78, 0x28, 0x65,
-            0x2c, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x65, 0x21,
-            0x3d, 0x3d, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74,
-            0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x74, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x78, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2c, 0x65, 0x29, 0x7d, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x65, 0x3d, 0x77, 0x28, 0x65,
-            0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x62, 0x28, 0x29, 0x2e, 0x73, 0x65, 0x74, 0x54,
-            0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x29, 0x7b, 0x5f, 0x28, 0x65, 0x29, 0x3b, 0x65, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x2c, 0x74,
-            0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x75, 0x28, 0x65, 0x29, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
-            0x76, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x65, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x45,
-            0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3f, 0x65, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7a, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20,
-            0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3f, 0x65, 0x3a, 0x6e, 0x75,
-            0x6c, 0x6c, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4a, 0x28, 0x65, 0x29,
-            0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x65,
-            0x3d, 0x3d, 0x3d, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3f, 0x65, 0x3a, 0x6e, 0x75,
-            0x6c, 0x6c, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x28, 0x65, 0x29,
-            0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
-            0x63, 0x65, 0x6f, 0x66, 0x20, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x7c, 0x7c, 0x65, 0x20,
-            0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x44, 0x6f, 0x63, 0x75, 0x6d,
-            0x65, 0x6e, 0x74, 0x7c, 0x7c, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f,
-            0x66, 0x20, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65,
-            0x6e, 0x74, 0x3f, 0x65, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x4b, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x65, 0x3d, 0x63, 0x65,
-            0x28, 0x77, 0x28, 0x65, 0x29, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x65, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x7d, 0x69, 0x66, 0x28, 0x6e, 0x29, 0x7b, 0x62, 0x28, 0x29, 0x2e, 0x73,
-            0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x4b, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x3b, 0x65, 0x3d, 0x6e, 0x75,
-            0x6c, 0x6c, 0x7d, 0x2c, 0x6e, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x65, 0x2e, 0x63, 0x6c,
-            0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x26, 0x26, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73,
-            0x4c, 0x69, 0x73, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x74, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x47, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x6c,
-            0x65, 0x74, 0x20, 0x72, 0x3d, 0x63, 0x65, 0x28, 0x77, 0x28, 0x65, 0x29, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x21, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x69, 0x66, 0x28, 0x6e,
-            0x29, 0x7b, 0x62, 0x28, 0x29, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
-            0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x47, 0x28, 0x72, 0x2c,
-            0x74, 0x29, 0x3b, 0x72, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x2c, 0x6e, 0x29, 0x7d, 0x65, 0x6c,
-            0x73, 0x65, 0x7b, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73,
-            0x74, 0x29, 0x7b, 0x72, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72,
-            0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x63, 0x6c,
-            0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3d, 0x3d,
-            0x3d, 0x30, 0x29, 0x7b, 0x72, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74, 0x74, 0x72,
-            0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x29, 0x7d, 0x7d,
-            0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x57, 0x28, 0x65, 0x2c, 0x74,
-            0x29, 0x7b, 0x65, 0x3d, 0x77, 0x28, 0x65, 0x29, 0x3b, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73,
-            0x4c, 0x69, 0x73, 0x74, 0x2e, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x28, 0x74, 0x29, 0x7d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5a, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x65,
-            0x3d, 0x77, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e,
-            0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65,
-            0x6e, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x47, 0x28,
-            0x65, 0x2c, 0x74, 0x29, 0x7d, 0x29, 0x3b, 0x4b, 0x28, 0x63, 0x65, 0x28, 0x65, 0x29, 0x2c, 0x74,
-            0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x28, 0x65, 0x2c, 0x74,
-            0x29, 0x7b, 0x65, 0x3d, 0x63, 0x65, 0x28, 0x77, 0x28, 0x65, 0x29, 0x29, 0x3b, 0x69, 0x66, 0x28,
-            0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x73,
-            0x65, 0x73, 0x74, 0x28, 0x74, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75,
-            0x6c, 0x6c, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x28, 0x65, 0x2c,
-            0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x73, 0x75, 0x62, 0x73,
-            0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x2c, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
-            0x29, 0x3d, 0x3d, 0x3d, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x59,
-            0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x73,
-            0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74,
-            0x68, 0x2d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3d, 0x3d, 0x3d, 0x74, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x65, 0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x3b,
-            0x69, 0x66, 0x28, 0x6c, 0x28, 0x74, 0x2c, 0x22, 0x3c, 0x22, 0x29, 0x26, 0x26, 0x59, 0x28, 0x74,
-            0x2c, 0x22, 0x2f, 0x3e, 0x22, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74,
-            0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x31, 0x2c, 0x74, 0x2e, 0x6c,
-            0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x32, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x6d, 0x28, 0x74, 0x2c, 0x72, 0x2c, 0x6e, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x69,
-            0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x22,
-            0x29, 0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x28,
-            0x74, 0x2c, 0x72, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x37, 0x29, 0x2c, 0x74, 0x72, 0x75,
-            0x65, 0x29, 0x7d, 0x74, 0x3d, 0x77, 0x28, 0x74, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x6f, 0x3d, 0x5b, 0x5d, 0x3b, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x3d, 0x30, 0x3b, 0x6c, 0x65,
-            0x74, 0x20, 0x6e, 0x3d, 0x30, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d,
-            0x30, 0x3b, 0x65, 0x3c, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6c, 0x3d, 0x72, 0x5b, 0x65, 0x5d, 0x3b, 0x69,
-            0x66, 0x28, 0x6c, 0x3d, 0x3d, 0x3d, 0x22, 0x2c, 0x22, 0x26, 0x26, 0x74, 0x3d, 0x3d, 0x3d, 0x30,
-            0x29, 0x7b, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74,
-            0x72, 0x69, 0x6e, 0x67, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x29, 0x3b, 0x6e, 0x3d, 0x65, 0x2b, 0x31,
-            0x3b, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x7d, 0x69, 0x66, 0x28, 0x6c, 0x3d, 0x3d,
-            0x3d, 0x22, 0x3c, 0x22, 0x29, 0x7b, 0x74, 0x2b, 0x2b, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69,
-            0x66, 0x28, 0x6c, 0x3d, 0x3d, 0x3d, 0x22, 0x2f, 0x22, 0x26, 0x26, 0x65, 0x3c, 0x72, 0x2e, 0x6c,
-            0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x26, 0x26, 0x72, 0x5b, 0x65, 0x2b, 0x31, 0x5d, 0x3d,
-            0x3d, 0x3d, 0x22, 0x3e, 0x22, 0x29, 0x7b, 0x74, 0x2d, 0x2d, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x6e,
-            0x3c, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x6f, 0x2e, 0x70, 0x75, 0x73,
-            0x68, 0x28, 0x72, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x6e, 0x29,
-            0x29, 0x7d, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x5b, 0x5d, 0x3b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x73, 0x3d, 0x5b, 0x5d, 0x3b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x6f,
-            0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x72, 0x3d, 0x70, 0x65, 0x28, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x29,
-            0x3b, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x69, 0x6e, 0x64, 0x65,
-            0x78, 0x4f, 0x66, 0x28, 0x22, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x20, 0x22, 0x29, 0x3d,
-            0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x65, 0x3d, 0x67, 0x28, 0x63, 0x65, 0x28, 0x74, 0x29, 0x2c, 0x70,
-            0x65, 0x28, 0x72, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x38, 0x29, 0x29, 0x29, 0x7d, 0x65,
-            0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66,
-            0x28, 0x22, 0x66, 0x69, 0x6e, 0x64, 0x20, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x65,
-            0x3d, 0x66, 0x28, 0x70, 0x28, 0x74, 0x29, 0x2c, 0x70, 0x65, 0x28, 0x72, 0x2e, 0x73, 0x6c, 0x69,
-            0x63, 0x65, 0x28, 0x35, 0x29, 0x29, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28,
-            0x72, 0x3d, 0x3d, 0x3d, 0x22, 0x6e, 0x65, 0x78, 0x74, 0x22, 0x7c, 0x7c, 0x72, 0x3d, 0x3d, 0x3d,
-            0x22, 0x6e, 0x65, 0x78, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x62, 0x6c,
-            0x69, 0x6e, 0x67, 0x22, 0x29, 0x7b, 0x65, 0x3d, 0x63, 0x65, 0x28, 0x74, 0x29, 0x2e, 0x6e, 0x65,
-            0x78, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67,
-            0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78,
-            0x4f, 0x66, 0x28, 0x22, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x30, 0x29,
-            0x7b, 0x65, 0x3d, 0x67, 0x65, 0x28, 0x74, 0x2c, 0x70, 0x65, 0x28, 0x72, 0x2e, 0x73, 0x6c, 0x69,
-            0x63, 0x65, 0x28, 0x35, 0x29, 0x29, 0x2c, 0x21, 0x21, 0x6e, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65,
-            0x20, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x3d, 0x3d, 0x22, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75,
-            0x73, 0x22, 0x7c, 0x7c, 0x72, 0x3d, 0x3d, 0x3d, 0x22, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75,
-            0x73, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x22,
-            0x29, 0x7b, 0x65, 0x3d, 0x63, 0x65, 0x28, 0x74, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f,
-            0x75, 0x73, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67,
-            0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78,
-            0x4f, 0x66, 0x28, 0x22, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x22, 0x29, 0x3d,
-            0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x65, 0x3d, 0x6d, 0x65, 0x28, 0x74, 0x2c, 0x70, 0x65, 0x28, 0x72,
-            0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x39, 0x29, 0x29, 0x2c, 0x21, 0x21, 0x6e, 0x29, 0x7d,
-            0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x3d, 0x3d, 0x22, 0x64, 0x6f, 0x63,
-            0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x29, 0x7b, 0x65, 0x3d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65,
-            0x6e, 0x74, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x3d, 0x3d, 0x22,
-            0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 0x29, 0x7b, 0x65, 0x3d, 0x77, 0x69, 0x6e, 0x64, 0x6f,
-            0x77, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x3d, 0x3d, 0x22, 0x62,
-            0x6f, 0x64, 0x79, 0x22, 0x29, 0x7b, 0x65, 0x3d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
-            0x2e, 0x62, 0x6f, 0x64, 0x79, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x72, 0x3d,
-            0x3d, 0x3d, 0x22, 0x72, 0x6f, 0x6f, 0x74, 0x22, 0x29, 0x7b, 0x65, 0x3d, 0x79, 0x28, 0x74, 0x2c,
-            0x21, 0x21, 0x6e, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x3d,
-            0x3d, 0x22, 0x68, 0x6f, 0x73, 0x74, 0x22, 0x29, 0x7b, 0x65, 0x3d, 0x74, 0x2e, 0x67, 0x65, 0x74,
-            0x52, 0x6f, 0x6f, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x2e, 0x68, 0x6f, 0x73, 0x74, 0x7d,
-            0x65, 0x6c, 0x73, 0x65, 0x7b, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x29, 0x7d, 0x69,
-            0x66, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x65, 0x29, 0x7d, 0x7d,
-            0x69, 0x66, 0x28, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d, 0x73, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x2c,
-            0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x3d, 0x70, 0x28, 0x79, 0x28, 0x74,
-            0x2c, 0x21, 0x21, 0x6e, 0x29, 0x29, 0x3b, 0x69, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x2e, 0x2e,
-            0x2e, 0x4d, 0x28, 0x63, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74,
-            0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x65, 0x29, 0x29, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x69, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x67, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x6e, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x72, 0x3d, 0x70, 0x28, 0x79, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x29, 0x2e, 0x71, 0x75, 0x65,
-            0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x65, 0x29,
-            0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65, 0x3c, 0x72,
-            0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x6f, 0x3d, 0x72, 0x5b, 0x65, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x6f, 0x2e, 0x63,
-            0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f,
-            0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x3d, 0x3d, 0x3d, 0x4e, 0x6f, 0x64, 0x65,
-            0x2e, 0x44, 0x4f, 0x43, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49,
-            0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x45, 0x43, 0x45, 0x44, 0x49, 0x4e, 0x47, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x7d, 0x7d, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6d, 0x65,
-            0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x6e, 0x29,
-            0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x70, 0x28, 0x79, 0x28, 0x74, 0x2c, 0x6e,
-            0x29, 0x29, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72,
-            0x41, 0x6c, 0x6c, 0x28, 0x65, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65,
-            0x3d, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x3b, 0x65, 0x3e, 0x3d, 0x30,
-            0x3b, 0x65, 0x2d, 0x2d, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x72, 0x5b,
-            0x65, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x44,
-            0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x74, 0x29, 0x3d, 0x3d, 0x3d, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x44, 0x4f, 0x43, 0x55, 0x4d, 0x45,
-            0x4e, 0x54, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x4f, 0x4c, 0x4c,
-            0x4f, 0x57, 0x49, 0x4e, 0x47, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x7d,
-            0x7d, 0x7d, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x65, 0x28, 0x65,
-            0x2c, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x65, 0x21,
-            0x3d, 0x3d, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x6d, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x5b, 0x30, 0x5d, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2e,
-            0x62, 0x6f, 0x64, 0x79, 0x2c, 0x65, 0x29, 0x5b, 0x30, 0x5d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74,
-            0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e,
-            0x67, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x28, 0x70, 0x28, 0x74,
-            0x29, 0x7c, 0x7c, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x65,
-            0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x7d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x79, 0x65, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x2c,
-            0x72, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x50, 0x28, 0x74, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x7b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62,
-            0x6f, 0x64, 0x79, 0x2c, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3a, 0x4a, 0x28, 0x65, 0x29, 0x2c, 0x6c,
-            0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x3a, 0x74, 0x2c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
-            0x73, 0x3a, 0x6e, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x7b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x77, 0x28, 0x65, 0x29, 0x2c, 0x65, 0x76, 0x65,
-            0x6e, 0x74, 0x3a, 0x4a, 0x28, 0x74, 0x29, 0x2c, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72,
-            0x3a, 0x6e, 0x2c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x72, 0x7d, 0x7d, 0x7d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x78, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72,
-            0x2c, 0x6f, 0x29, 0x7b, 0x47, 0x6e, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d, 0x79, 0x65, 0x28, 0x74, 0x2c, 0x6e,
-            0x2c, 0x72, 0x2c, 0x6f, 0x29, 0x3b, 0x65, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x61,
-            0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28,
-            0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2c, 0x65, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e,
-            0x65, 0x72, 0x2c, 0x65, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x7d, 0x29, 0x3b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d, 0x50, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x65, 0x3f, 0x6e, 0x3a, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x62, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x7b, 0x47, 0x6e, 0x28,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x65, 0x3d, 0x79, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x3b, 0x65, 0x2e, 0x74,
-            0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e,
-            0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e,
-            0x74, 0x2c, 0x65, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x29, 0x7d, 0x29, 0x3b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x50, 0x28, 0x6e, 0x29, 0x3f, 0x6e, 0x3a, 0x72, 0x7d,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x76, 0x65, 0x3d, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x63, 0x72,
-            0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x75, 0x74,
-            0x70, 0x75, 0x74, 0x22, 0x29, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77,
-            0x65, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d, 0x6e,
-            0x65, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x5b, 0x53, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x5d, 0x7d, 0x65, 0x6c, 0x73, 0x65,
-            0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x6d, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x3b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x2f, 0x28, 0x5e, 0x7c, 0x2c, 0x29, 0x28, 0x5c,
-            0x73, 0x2a, 0x29, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x28, 0x5c, 0x73, 0x2a, 0x29, 0x28,
-            0x24, 0x7c, 0x2c, 0x29, 0x2f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x6f, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x63, 0x65, 0x28, 0x71,
-            0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x21, 0x3d, 0x3d, 0x74, 0x26, 0x26, 0x73, 0x28, 0x63,
-            0x65, 0x28, 0x65, 0x29, 0x2c, 0x6e, 0x29, 0x7d, 0x29, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x29,
-            0x7b, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x2e, 0x2e, 0x2e, 0x77, 0x65, 0x28, 0x69, 0x2c,
-            0x6e, 0x29, 0x29, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
-            0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x48, 0x28, 0x27, 0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6c,
-            0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x22, 0x27, 0x2b, 0x65, 0x2b, 0x27, 0x22, 0x20, 0x6f, 0x6e,
-            0x20, 0x27, 0x2b, 0x6e, 0x2b, 0x22, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20,
-            0x6e, 0x6f, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x21, 0x22, 0x29, 0x3b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x5b, 0x76, 0x65, 0x5d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x53, 0x65, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x63, 0x65, 0x28, 0x71, 0x28, 0x65, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x28, 0x63, 0x65,
-            0x28, 0x65, 0x29, 0x2c, 0x74, 0x29, 0x21, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x29, 0x29, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6e, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d,
-            0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x69,
-            0x66, 0x28, 0x74, 0x3d, 0x3d, 0x3d, 0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x53, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x74, 0x61,
-            0x72, 0x67, 0x65, 0x74, 0x22, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x75, 0x65, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65,
-            0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x69,
-            0x66, 0x28, 0x6e, 0x2e, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x29, 0x7b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x7d, 0x65, 0x6c,
-            0x73, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x7d, 0x7d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x61, 0x74, 0x74,
-            0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x54, 0x6f, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x2e,
-            0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x28, 0x65, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4f, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x69, 0x65, 0x28,
-            0x41, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x28, 0x74, 0x2e, 0x61, 0x74, 0x74,
-            0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x6e, 0x2e, 0x68, 0x61, 0x73, 0x41, 0x74,
-            0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x26,
-            0x26, 0x43, 0x65, 0x28, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x29, 0x7b, 0x74, 0x2e, 0x72,
-            0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x65,
-            0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x7d, 0x7d, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x6e, 0x2e, 0x61,
-            0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x43, 0x65, 0x28, 0x65, 0x2e, 0x6e, 0x61,
-            0x6d, 0x65, 0x29, 0x29, 0x7b, 0x74, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62,
-            0x75, 0x74, 0x65, 0x28, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x65, 0x2e, 0x76, 0x61, 0x6c,
-            0x75, 0x65, 0x29, 0x7d, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-            0x48, 0x65, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d,
-            0x4a, 0x6e, 0x28, 0x65, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d,
-            0x30, 0x3b, 0x65, 0x3c, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x6e, 0x5b, 0x65, 0x5d, 0x3b, 0x74,
-            0x72, 0x79, 0x7b, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x69, 0x73, 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65,
-            0x53, 0x77, 0x61, 0x70, 0x28, 0x74, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x74, 0x72, 0x75, 0x65, 0x7d, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x7b, 0x48,
-            0x28, 0x65, 0x29, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x3d, 0x3d, 0x3d,
-            0x22, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x22, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x65, 0x28, 0x65, 0x2c, 0x6f, 0x2c, 0x69, 0x2c, 0x74, 0x29,
-            0x7b, 0x74, 0x3d, 0x74, 0x7c, 0x7c, 0x74, 0x65, 0x28, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x6e,
-            0x3d, 0x22, 0x23, 0x22, 0x2b, 0x43, 0x53, 0x53, 0x2e, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x28,
-            0x65, 0x65, 0x28, 0x6f, 0x2c, 0x22, 0x69, 0x64, 0x22, 0x29, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20,
-            0x73, 0x3d, 0x22, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x22, 0x3b, 0x69, 0x66,
-            0x28, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x29, 0x7b, 0x7d, 0x65, 0x6c,
-            0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28,
-            0x22, 0x3a, 0x22, 0x29, 0x3e, 0x30, 0x29, 0x7b, 0x73, 0x3d, 0x65, 0x2e, 0x73, 0x75, 0x62, 0x73,
-            0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x2c, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f,
-            0x66, 0x28, 0x22, 0x3a, 0x22, 0x29, 0x29, 0x3b, 0x6e, 0x3d, 0x65, 0x2e, 0x73, 0x75, 0x62, 0x73,
-            0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28,
-            0x22, 0x3a, 0x22, 0x29, 0x2b, 0x31, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x73, 0x3d, 0x65,
-            0x7d, 0x6f, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
-            0x74, 0x65, 0x28, 0x22, 0x68, 0x78, 0x2d, 0x73, 0x77, 0x61, 0x70, 0x2d, 0x6f, 0x6f, 0x62, 0x22,
-            0x29, 0x3b, 0x6f, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62,
-            0x75, 0x74, 0x65, 0x28, 0x22, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x73, 0x77, 0x61,
-            0x70, 0x2d, 0x6f, 0x6f, 0x62, 0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d,
-            0x6d, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28,
-            0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x69, 0x65, 0x28, 0x72, 0x2c, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x74,
-            0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x6f, 0x2e, 0x63, 0x6c, 0x6f, 0x6e, 0x65,
-            0x4e, 0x6f, 0x64, 0x65, 0x28, 0x74, 0x72, 0x75, 0x65, 0x29, 0x3b, 0x74, 0x3d, 0x74, 0x65, 0x28,
-            0x29, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
-            0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x3b, 0x74, 0x2e, 0x61, 0x70, 0x70,
-            0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6e, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21,
-            0x48, 0x65, 0x28, 0x73, 0x2c, 0x65, 0x29, 0x29, 0x7b, 0x74, 0x3d, 0x70, 0x28, 0x6e, 0x29, 0x7d,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x7b, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x53,
-            0x77, 0x61, 0x70, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a,
-            0x65, 0x2c, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x74, 0x7d, 0x3b, 0x69, 0x66,
-            0x28, 0x21, 0x61, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x6f, 0x6f, 0x62,
-            0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x53, 0x77, 0x61, 0x70, 0x22, 0x2c, 0x72, 0x29, 0x29, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x65, 0x3d, 0x72, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
-            0x3b, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x53, 0x77, 0x61, 0x70,
-            0x29, 0x7b, 0x71, 0x65, 0x28, 0x74, 0x29, 0x3b, 0x24, 0x65, 0x28, 0x73, 0x2c, 0x65, 0x2c, 0x65,
-            0x2c, 0x74, 0x2c, 0x69, 0x29, 0x3b, 0x52, 0x65, 0x28, 0x29, 0x7d, 0x69, 0x65, 0x28, 0x69, 0x2e,
-            0x65, 0x6c, 0x74, 0x73, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29,
-            0x7b, 0x61, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x6f, 0x6f, 0x62, 0x41,
-            0x66, 0x74, 0x65, 0x72, 0x53, 0x77, 0x61, 0x70, 0x22, 0x2c, 0x72, 0x29, 0x7d, 0x29, 0x7d, 0x29,
-            0x3b, 0x6f, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x72, 0x65,
-            0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6f, 0x29, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x7b, 0x6f, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x72,
-            0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6f, 0x29, 0x3b, 0x66, 0x65,
-            0x28, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78,
-            0x3a, 0x6f, 0x6f, 0x62, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4e, 0x6f, 0x54, 0x61, 0x72, 0x67, 0x65,
-            0x74, 0x22, 0x2c, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x6f, 0x7d, 0x29, 0x7d,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x52, 0x65, 0x28, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d, 0x66,
-            0x28, 0x22, 0x23, 0x2d, 0x2d, 0x68, 0x74, 0x6d, 0x78, 0x2d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72,
-            0x76, 0x65, 0x2d, 0x70, 0x61, 0x6e, 0x74, 0x72, 0x79, 0x2d, 0x2d, 0x22, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x65, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x20,
-            0x6f, 0x66, 0x5b, 0x2e, 0x2e, 0x2e, 0x65, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e,
-            0x5d, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x66, 0x28, 0x22, 0x23, 0x22,
-            0x2b, 0x74, 0x2e, 0x69, 0x64, 0x29, 0x3b, 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e,
-            0x6f, 0x64, 0x65, 0x2e, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x28, 0x74,
-            0x2c, 0x6e, 0x29, 0x3b, 0x6e, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x7d, 0x65,
-            0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x71, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x65, 0x28, 0x78, 0x28, 0x65,
-            0x2c, 0x22, 0x5b, 0x68, 0x78, 0x2d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5d, 0x2c,
-            0x20, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72,
-            0x76, 0x65, 0x5d, 0x22, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x61, 0x28, 0x65, 0x2c, 0x22, 0x69,
-            0x64, 0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x74, 0x65, 0x28, 0x29,
-            0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28,
-            0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x21, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x69,
-            0x66, 0x28, 0x65, 0x2e, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x29, 0x7b,
-            0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x66, 0x28, 0x22, 0x23, 0x2d, 0x2d, 0x68, 0x74, 0x6d, 0x78,
-            0x2d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x2d, 0x70, 0x61, 0x6e, 0x74, 0x72, 0x79,
-            0x2d, 0x2d, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29,
-            0x7b, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72,
-            0x74, 0x41, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x48, 0x54, 0x4d, 0x4c, 0x28, 0x22, 0x61,
-            0x66, 0x74, 0x65, 0x72, 0x65, 0x6e, 0x64, 0x22, 0x2c, 0x22, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69,
-            0x64, 0x3d, 0x27, 0x2d, 0x2d, 0x68, 0x74, 0x6d, 0x78, 0x2d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72,
-            0x76, 0x65, 0x2d, 0x70, 0x61, 0x6e, 0x74, 0x72, 0x79, 0x2d, 0x2d, 0x27, 0x3e, 0x3c, 0x2f, 0x64,
-            0x69, 0x76, 0x3e, 0x22, 0x29, 0x3b, 0x65, 0x3d, 0x66, 0x28, 0x22, 0x23, 0x2d, 0x2d, 0x68, 0x74,
-            0x6d, 0x78, 0x2d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x2d, 0x70, 0x61, 0x6e, 0x74,
-            0x72, 0x79, 0x2d, 0x2d, 0x22, 0x29, 0x7d, 0x65, 0x2e, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x65, 0x66,
-            0x6f, 0x72, 0x65, 0x28, 0x6e, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65,
-            0x7b, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x72, 0x65,
-            0x70, 0x6c, 0x61, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7d,
-            0x7d, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x65, 0x28,
-            0x6c, 0x2c, 0x65, 0x2c, 0x63, 0x29, 0x7b, 0x69, 0x65, 0x28, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72,
-            0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x22, 0x5b, 0x69,
-            0x64, 0x5d, 0x22, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29,
-            0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x65, 0x65, 0x28, 0x74, 0x2c, 0x22, 0x69,
-            0x64, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x26, 0x26, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67,
-            0x74, 0x68, 0x3e, 0x30, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x6e, 0x2e,
-            0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x22, 0x27, 0x22, 0x2c, 0x22, 0x5c, 0x5c, 0x27,
-            0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x74, 0x2e, 0x74, 0x61, 0x67,
-            0x4e, 0x61, 0x6d, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x22, 0x3a, 0x22,
-            0x2c, 0x22, 0x5c, 0x5c, 0x3a, 0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d,
-            0x70, 0x28, 0x6c, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x65, 0x26, 0x26,
-            0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x28,
-            0x6f, 0x2b, 0x22, 0x5b, 0x69, 0x64, 0x3d, 0x27, 0x22, 0x2b, 0x72, 0x2b, 0x22, 0x27, 0x5d, 0x22,
-            0x29, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x26, 0x26, 0x69, 0x21, 0x3d, 0x3d, 0x65, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x73, 0x3d, 0x74, 0x2e, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x4e, 0x6f,
-            0x64, 0x65, 0x28, 0x29, 0x3b, 0x4f, 0x65, 0x28, 0x74, 0x2c, 0x69, 0x29, 0x3b, 0x63, 0x2e, 0x74,
-            0x61, 0x73, 0x6b, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x4f, 0x65, 0x28, 0x74, 0x2c, 0x73, 0x29, 0x7d, 0x29, 0x7d, 0x7d,
-            0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4c, 0x65, 0x28, 0x65,
-            0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x28, 0x29, 0x7b, 0x47, 0x28, 0x65, 0x2c, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-            0x2e, 0x61, 0x64, 0x64, 0x65, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x29, 0x3b, 0x46, 0x74, 0x28,
-            0x63, 0x65, 0x28, 0x65, 0x29, 0x29, 0x3b, 0x4e, 0x65, 0x28, 0x70, 0x28, 0x65, 0x29, 0x29, 0x3b,
-            0x61, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x6c, 0x6f, 0x61, 0x64, 0x22,
-            0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, 0x65, 0x28, 0x65,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x22, 0x5b, 0x61, 0x75, 0x74, 0x6f,
-            0x66, 0x6f, 0x63, 0x75, 0x73, 0x5d, 0x22, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d,
-            0x7a, 0x28, 0x68, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x3f, 0x65, 0x3a, 0x65, 0x2e, 0x71, 0x75, 0x65,
-            0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x28, 0x74, 0x29, 0x29, 0x3b, 0x69,
-            0x66, 0x28, 0x6e, 0x21, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x6e, 0x2e, 0x66, 0x6f, 0x63,
-            0x75, 0x73, 0x28, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63,
-            0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x7b, 0x41, 0x65, 0x28, 0x65, 0x2c, 0x6e,
-            0x2c, 0x72, 0x29, 0x3b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c,
-            0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x29,
-            0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x6e, 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74,
-            0x43, 0x68, 0x69, 0x6c, 0x64, 0x3b, 0x4b, 0x28, 0x63, 0x65, 0x28, 0x6f, 0x29, 0x2c, 0x51, 0x2e,
-            0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x61, 0x64, 0x64, 0x65, 0x64, 0x43, 0x6c, 0x61, 0x73,
-            0x73, 0x29, 0x3b, 0x65, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72,
-            0x65, 0x28, 0x6f, 0x2c, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65,
-            0x54, 0x79, 0x70, 0x65, 0x21, 0x3d, 0x3d, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x54, 0x45, 0x58, 0x54,
-            0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x26, 0x26, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70,
-            0x65, 0x21, 0x3d, 0x3d, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54,
-            0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x29, 0x7b, 0x72, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x70,
-            0x75, 0x73, 0x68, 0x28, 0x4c, 0x65, 0x28, 0x6f, 0x29, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x65, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x6c, 0x65,
-            0x74, 0x20, 0x6e, 0x3d, 0x30, 0x3b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x6e, 0x3c, 0x65, 0x2e,
-            0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x74, 0x3d, 0x28, 0x74, 0x3c, 0x3c, 0x35, 0x29,
-            0x2d, 0x74, 0x2b, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x41, 0x74, 0x28,
-            0x6e, 0x2b, 0x2b, 0x29, 0x7c, 0x30, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x65, 0x28, 0x74, 0x29, 0x7b, 0x6c,
-            0x65, 0x74, 0x20, 0x6e, 0x3d, 0x30, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65,
-            0x3d, 0x30, 0x3b, 0x65, 0x3c, 0x74, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
-            0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x74, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
-            0x65, 0x73, 0x5b, 0x65, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65,
-            0x29, 0x7b, 0x6e, 0x3d, 0x49, 0x65, 0x28, 0x72, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x6e, 0x29,
-            0x3b, 0x6e, 0x3d, 0x49, 0x65, 0x28, 0x72, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x6e, 0x29,
-            0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x50, 0x65, 0x28, 0x74, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x6e, 0x3d, 0x6f, 0x65, 0x28, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x6f, 0x6e, 0x48,
-            0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74,
-            0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65, 0x3c, 0x6e, 0x2e, 0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x6c,
-            0x65, 0x72, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29, 0x7b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x6e, 0x2e, 0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64,
-            0x6c, 0x65, 0x72, 0x73, 0x5b, 0x65, 0x5d, 0x3b, 0x62, 0x65, 0x28, 0x74, 0x2c, 0x72, 0x2e, 0x65,
-            0x76, 0x65, 0x6e, 0x74, 0x2c, 0x72, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x29,
-            0x7d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x6e, 0x2e, 0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64,
-            0x6c, 0x65, 0x72, 0x73, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6b,
-            0x65, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6f, 0x65, 0x28,
-            0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x29,
-            0x7b, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x74, 0x2e,
-            0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x6c, 0x69,
-            0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x29, 0x7b, 0x69, 0x65, 0x28,
-            0x74, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x2c,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65,
-            0x2e, 0x6f, 0x6e, 0x29, 0x7b, 0x62, 0x65, 0x28, 0x65, 0x2e, 0x6f, 0x6e, 0x2c, 0x65, 0x2e, 0x74,
-            0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2c, 0x65, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65,
-            0x72, 0x29, 0x7d, 0x7d, 0x29, 0x7d, 0x50, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x4f,
-            0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x28, 0x74, 0x29, 0x2c, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x21, 0x3d,
-            0x3d, 0x22, 0x66, 0x69, 0x72, 0x73, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
-            0x65, 0x74, 0x65, 0x64, 0x22, 0x29, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x74, 0x5b, 0x65,
-            0x5d, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x28, 0x65,
-            0x29, 0x7b, 0x61, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x62, 0x65, 0x66,
-            0x6f, 0x72, 0x65, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
-            0x74, 0x22, 0x29, 0x3b, 0x6b, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x65, 0x2e, 0x63,
-            0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x28, 0x65, 0x29, 0x7b, 0x53, 0x28, 0x65, 0x29, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x4d, 0x65, 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x6e, 0x29, 0x7b, 0x69, 0x66,
-            0x28, 0x74, 0x2e, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x42, 0x4f,
-            0x44, 0x59, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6a, 0x65, 0x28, 0x74,
-            0x2c, 0x65, 0x2c, 0x6e, 0x29, 0x7d, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x3b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x6f, 0x3d, 0x74, 0x2e, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x53, 0x69,
-            0x62, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x75, 0x28,
-            0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x69, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x7d, 0x63, 0x28, 0x69, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x6e, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6f,
-            0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x72, 0x3d, 0x69, 0x2e, 0x66, 0x69, 0x72, 0x73,
-            0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x3d, 0x6f, 0x2e,
-            0x6e, 0x65, 0x78, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x7d, 0x6e, 0x2e, 0x65, 0x6c,
-            0x74, 0x73, 0x3d, 0x6e, 0x2e, 0x65, 0x6c, 0x74, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
-            0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x65, 0x21, 0x3d, 0x3d, 0x74, 0x7d, 0x29, 0x3b, 0x77, 0x68, 0x69, 0x6c,
-            0x65, 0x28, 0x72, 0x26, 0x26, 0x72, 0x21, 0x3d, 0x3d, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x72,
-            0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x45, 0x6c, 0x65, 0x6d,
-            0x65, 0x6e, 0x74, 0x29, 0x7b, 0x6e, 0x2e, 0x65, 0x6c, 0x74, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68,
-            0x28, 0x72, 0x29, 0x7d, 0x72, 0x3d, 0x72, 0x2e, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x69, 0x62, 0x6c,
-            0x69, 0x6e, 0x67, 0x7d, 0x53, 0x28, 0x74, 0x29, 0x3b, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76,
-            0x65, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x65, 0x28,
-            0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x28,
-            0x65, 0x2c, 0x65, 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x74,
-            0x2c, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x65, 0x28,
-            0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x28,
-            0x75, 0x28, 0x65, 0x29, 0x2c, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x58, 0x65, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x28, 0x65, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x74,
-            0x2c, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x55, 0x65, 0x28,
-            0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x28,
-            0x75, 0x28, 0x65, 0x29, 0x2c, 0x65, 0x2e, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69,
-            0x6e, 0x67, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x56, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x53, 0x28, 0x65, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x74, 0x3d, 0x75, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68,
-            0x69, 0x6c, 0x64, 0x28, 0x65, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x6a, 0x65, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x72, 0x3d, 0x65, 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x3b,
-            0x63, 0x28, 0x65, 0x2c, 0x72, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x72, 0x29,
-            0x7b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x72, 0x2e, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x69, 0x62,
-            0x6c, 0x69, 0x6e, 0x67, 0x29, 0x7b, 0x53, 0x28, 0x72, 0x2e, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x69,
-            0x62, 0x6c, 0x69, 0x6e, 0x67, 0x29, 0x3b, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43,
-            0x68, 0x69, 0x6c, 0x64, 0x28, 0x72, 0x2e, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69,
-            0x6e, 0x67, 0x29, 0x7d, 0x53, 0x28, 0x72, 0x29, 0x3b, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76,
-            0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x72, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x24, 0x65, 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x6e, 0x2c, 0x72, 0x2c, 0x6f,
-            0x29, 0x7b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x28, 0x74, 0x29, 0x7b, 0x63, 0x61, 0x73, 0x65,
-            0x22, 0x6e, 0x6f, 0x6e, 0x65, 0x22, 0x3a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x63, 0x61,
-            0x73, 0x65, 0x22, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x22, 0x3a, 0x4d, 0x65,
-            0x28, 0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x63,
-            0x61, 0x73, 0x65, 0x22, 0x61, 0x66, 0x74, 0x65, 0x72, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x22, 0x3a,
-            0x46, 0x65, 0x28, 0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x3b, 0x63, 0x61, 0x73, 0x65, 0x22, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x62, 0x65, 0x67, 0x69,
-            0x6e, 0x22, 0x3a, 0x42, 0x65, 0x28, 0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x29, 0x3b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x22, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x65,
-            0x6e, 0x64, 0x22, 0x3a, 0x58, 0x65, 0x28, 0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x29, 0x3b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x22, 0x61, 0x66, 0x74, 0x65, 0x72, 0x65,
-            0x6e, 0x64, 0x22, 0x3a, 0x55, 0x65, 0x28, 0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x29, 0x3b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x22, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65,
-            0x22, 0x3a, 0x56, 0x65, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x64,
-            0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x4a, 0x6e, 0x28,
-            0x65, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65,
-            0x3c, 0x69, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x73, 0x3d, 0x69, 0x5b, 0x65, 0x5d, 0x3b, 0x74, 0x72, 0x79, 0x7b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6c, 0x3d, 0x73, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65,
-            0x53, 0x77, 0x61, 0x70, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x6c, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x41, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x69, 0x73, 0x41,
-            0x72, 0x72, 0x61, 0x79, 0x28, 0x6c, 0x29, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74,
-            0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65, 0x3c, 0x6c, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b,
-            0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x3d, 0x6c, 0x5b, 0x65,
-            0x5d, 0x3b, 0x69, 0x66, 0x28, 0x63, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x21,
-            0x3d, 0x3d, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x45,
-            0x26, 0x26, 0x63, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x21, 0x3d, 0x3d, 0x4e,
-            0x6f, 0x64, 0x65, 0x2e, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x45,
-            0x29, 0x7b, 0x6f, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x4c,
-            0x65, 0x28, 0x63, 0x29, 0x29, 0x7d, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x7d,
-            0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x7b, 0x48, 0x28, 0x65, 0x29, 0x7d, 0x7d, 0x69,
-            0x66, 0x28, 0x74, 0x3d, 0x3d, 0x3d, 0x22, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c,
-            0x22, 0x29, 0x7b, 0x6a, 0x65, 0x28, 0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x29, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x7b, 0x24, 0x65, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x64, 0x65,
-            0x66, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x2c, 0x65,
-            0x2c, 0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x5f, 0x65, 0x28, 0x65, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72,
-            0x20, 0x74, 0x3d, 0x78, 0x28, 0x65, 0x2c, 0x22, 0x5b, 0x68, 0x78, 0x2d, 0x73, 0x77, 0x61, 0x70,
-            0x2d, 0x6f, 0x6f, 0x62, 0x5d, 0x2c, 0x20, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d,
-            0x73, 0x77, 0x61, 0x70, 0x2d, 0x6f, 0x6f, 0x62, 0x5d, 0x22, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x74,
-            0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x65,
-            0x73, 0x74, 0x65, 0x64, 0x4f, 0x6f, 0x62, 0x53, 0x77, 0x61, 0x70, 0x73, 0x7c, 0x7c, 0x65, 0x2e,
-            0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3d, 0x3d, 0x3d,
-            0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x61, 0x28,
-            0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x73, 0x77, 0x61, 0x70, 0x2d, 0x6f, 0x6f, 0x62, 0x22, 0x29,
-            0x3b, 0x69, 0x66, 0x28, 0x74, 0x21, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x54, 0x65, 0x28,
-            0x74, 0x2c, 0x65, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x65,
-            0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
-            0x28, 0x22, 0x68, 0x78, 0x2d, 0x73, 0x77, 0x61, 0x70, 0x2d, 0x6f, 0x6f, 0x62, 0x22, 0x29, 0x3b,
-            0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
-            0x65, 0x28, 0x22, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x73, 0x77, 0x61, 0x70, 0x2d,
-            0x6f, 0x6f, 0x62, 0x22, 0x29, 0x7d, 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x7a, 0x65, 0x28, 0x68, 0x2c, 0x64, 0x2c, 0x70, 0x2c, 0x67, 0x29, 0x7b,
-            0x69, 0x66, 0x28, 0x21, 0x67, 0x29, 0x7b, 0x67, 0x3d, 0x7b, 0x7d, 0x7d, 0x6c, 0x65, 0x74, 0x20,
-            0x6d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x3d, 0x6e, 0x75, 0x6c,
-            0x6c, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x28, 0x29, 0x7b, 0x72, 0x65, 0x28, 0x67, 0x2e, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x53, 0x77,
-            0x61, 0x70, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x29, 0x3b, 0x68, 0x3d, 0x77, 0x28,
-            0x68, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x67, 0x2e, 0x63, 0x6f, 0x6e,
-            0x74, 0x65, 0x78, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3f, 0x79, 0x28, 0x67, 0x2e,
-            0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x66,
-            0x61, 0x6c, 0x73, 0x65, 0x29, 0x3a, 0x74, 0x65, 0x28, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x65, 0x3d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x63, 0x74, 0x69,
-            0x76, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x3d,
-            0x7b, 0x7d, 0x3b, 0x74, 0x3d, 0x7b, 0x65, 0x6c, 0x74, 0x3a, 0x65, 0x2c, 0x73, 0x74, 0x61, 0x72,
-            0x74, 0x3a, 0x65, 0x3f, 0x65, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53,
-            0x74, 0x61, 0x72, 0x74, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x65, 0x6e, 0x64, 0x3a, 0x65, 0x3f,
-            0x65, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x3a, 0x6e,
-            0x75, 0x6c, 0x6c, 0x7d, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x53, 0x6e, 0x28,
-            0x68, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x70, 0x2e, 0x73, 0x77, 0x61, 0x70, 0x53, 0x74, 0x79, 0x6c,
-            0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-            0x22, 0x29, 0x7b, 0x68, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-            0x3d, 0x64, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x3d, 0x44, 0x28,
-            0x64, 0x29, 0x3b, 0x6f, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x67, 0x2e, 0x74, 0x69, 0x74,
-            0x6c, 0x65, 0x7c, 0x7c, 0x6e, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x67,
-            0x2e, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x29,
-            0x7b, 0x6e, 0x3d, 0x6e, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74,
-            0x6f, 0x72, 0x28, 0x22, 0x5b, 0x68, 0x78, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2d,
-            0x65, 0x6c, 0x74, 0x5d, 0x2c, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x68, 0x69,
-            0x73, 0x74, 0x6f, 0x72, 0x79, 0x2d, 0x65, 0x6c, 0x74, 0x5d, 0x22, 0x29, 0x7c, 0x7c, 0x6e, 0x7d,
-            0x69, 0x66, 0x28, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4f, 0x4f, 0x42, 0x29, 0x7b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74,
-            0x4f, 0x4f, 0x42, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, 0x2c, 0x22, 0x29, 0x3b, 0x66,
-            0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x3d, 0x30, 0x3b, 0x74, 0x3c, 0x69, 0x2e, 0x6c,
-            0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x74, 0x2b, 0x2b, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x73, 0x3d, 0x69, 0x5b, 0x74, 0x5d, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, 0x3a,
-            0x22, 0x2c, 0x32, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x73, 0x5b, 0x30, 0x5d, 0x2e,
-            0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x65,
-            0x78, 0x4f, 0x66, 0x28, 0x22, 0x23, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x65, 0x3d,
-            0x65, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x31, 0x29, 0x7d, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6c, 0x3d, 0x73, 0x5b, 0x31, 0x5d, 0x7c, 0x7c, 0x22, 0x74, 0x72,
-            0x75, 0x65, 0x22, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x3d, 0x6e, 0x2e, 0x71, 0x75,
-            0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x28, 0x22, 0x23, 0x22, 0x2b,
-            0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x63, 0x29, 0x7b, 0x54, 0x65, 0x28, 0x6c, 0x2c, 0x63, 0x2c,
-            0x6f, 0x2c, 0x72, 0x29, 0x7d, 0x7d, 0x7d, 0x5f, 0x65, 0x28, 0x6e, 0x2c, 0x6f, 0x2c, 0x72, 0x29,
-            0x3b, 0x69, 0x65, 0x28, 0x78, 0x28, 0x6e, 0x2c, 0x22, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
-            0x65, 0x22, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b,
-            0x69, 0x66, 0x28, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x26, 0x26, 0x5f, 0x65,
-            0x28, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2c, 0x6f, 0x2c, 0x72, 0x29, 0x29,
-            0x7b, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x7d, 0x7d, 0x29, 0x3b, 0x69,
-            0x66, 0x28, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x75, 0x3d, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44,
-            0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x28,
-            0x29, 0x3b, 0x69, 0x65, 0x28, 0x6e, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65,
-            0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74,
-            0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x75, 0x2e,
-            0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x65, 0x29, 0x7d, 0x29,
-            0x3b, 0x6e, 0x3d, 0x75, 0x7d, 0x71, 0x65, 0x28, 0x6e, 0x29, 0x3b, 0x24, 0x65, 0x28, 0x70, 0x2e,
-            0x73, 0x77, 0x61, 0x70, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x2c, 0x67, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
-            0x65, 0x78, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x68, 0x2c, 0x6e, 0x2c, 0x6f,
-            0x29, 0x3b, 0x52, 0x65, 0x28, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x65, 0x6c, 0x74, 0x26,
-            0x26, 0x21, 0x73, 0x65, 0x28, 0x74, 0x2e, 0x65, 0x6c, 0x74, 0x29, 0x26, 0x26, 0x65, 0x65, 0x28,
-            0x74, 0x2e, 0x65, 0x6c, 0x74, 0x2c, 0x22, 0x69, 0x64, 0x22, 0x29, 0x29, 0x7b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x66, 0x3d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65,
-            0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x65, 0x65, 0x28,
-            0x74, 0x2e, 0x65, 0x6c, 0x74, 0x2c, 0x22, 0x69, 0x64, 0x22, 0x29, 0x29, 0x3b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x61, 0x3d, 0x7b, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72,
-            0x6f, 0x6c, 0x6c, 0x3a, 0x70, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x53, 0x63, 0x72, 0x6f, 0x6c,
-            0x6c, 0x21, 0x3d, 0x3d, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x3f, 0x21, 0x70,
-            0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x21, 0x51, 0x2e,
-            0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x46, 0x6f,
-            0x63, 0x75, 0x73, 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x7d, 0x3b, 0x69, 0x66, 0x28, 0x66, 0x29,
-            0x7b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x26, 0x26, 0x66, 0x2e, 0x73,
-            0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65,
-            0x29, 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x66, 0x2e, 0x73, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x72,
-            0x74, 0x2c, 0x74, 0x2e, 0x65, 0x6e, 0x64, 0x29, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65,
-            0x29, 0x7b, 0x7d, 0x7d, 0x66, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x28, 0x61, 0x29, 0x7d, 0x7d,
-            0x68, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
-            0x76, 0x65, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x73, 0x77, 0x61, 0x70,
-            0x70, 0x69, 0x6e, 0x67, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x6f, 0x2e,
-            0x65, 0x6c, 0x74, 0x73, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29,
-            0x7b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x29,
-            0x7b, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x61, 0x64, 0x64,
-            0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x6c, 0x69,
-            0x6e, 0x67, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x29, 0x7d, 0x61, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68,
-            0x74, 0x6d, 0x78, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x53, 0x77, 0x61, 0x70, 0x22, 0x2c, 0x67,
-            0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x29, 0x7d, 0x29, 0x3b, 0x72, 0x65,
-            0x28, 0x67, 0x2e, 0x61, 0x66, 0x74, 0x65, 0x72, 0x53, 0x77, 0x61, 0x70, 0x43, 0x61, 0x6c, 0x6c,
-            0x62, 0x61, 0x63, 0x6b, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x70, 0x2e, 0x69, 0x67, 0x6e, 0x6f,
-            0x72, 0x65, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x29, 0x7b, 0x58, 0x6e, 0x28, 0x6f, 0x2e, 0x74, 0x69,
-            0x74, 0x6c, 0x65, 0x29, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x65, 0x28, 0x6f, 0x2e, 0x74, 0x61, 0x73,
-            0x6b, 0x73, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x65,
-            0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x29, 0x7d, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x6f, 0x2e, 0x65,
-            0x6c, 0x74, 0x73, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b,
-            0x69, 0x66, 0x28, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x29, 0x7b,
-            0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f,
-            0x76, 0x65, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x73, 0x65, 0x74, 0x74,
-            0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x29, 0x7d, 0x61, 0x65, 0x28, 0x65, 0x2c,
-            0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x6c,
-            0x65, 0x22, 0x2c, 0x67, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x29, 0x7d,
-            0x29, 0x3b, 0x69, 0x66, 0x28, 0x67, 0x2e, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d, 0x63, 0x65, 0x28, 0x77, 0x28, 0x22, 0x23, 0x22, 0x2b,
-            0x67, 0x2e, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x29, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x29,
-            0x7b, 0x65, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x6f, 0x56, 0x69, 0x65,
-            0x77, 0x28, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3a, 0x22, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22,
-            0x2c, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x3a, 0x22, 0x61, 0x75, 0x74, 0x6f, 0x22,
-            0x7d, 0x29, 0x7d, 0x7d, 0x45, 0x6e, 0x28, 0x6f, 0x2e, 0x65, 0x6c, 0x74, 0x73, 0x2c, 0x70, 0x29,
-            0x3b, 0x72, 0x65, 0x28, 0x67, 0x2e, 0x61, 0x66, 0x74, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x6c,
-            0x65, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x29, 0x3b, 0x72, 0x65, 0x28, 0x6d, 0x29,
-            0x7d, 0x3b, 0x69, 0x66, 0x28, 0x70, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x65, 0x6c,
-            0x61, 0x79, 0x3e, 0x30, 0x29, 0x7b, 0x62, 0x28, 0x29, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d,
-            0x65, 0x6f, 0x75, 0x74, 0x28, 0x6e, 0x2c, 0x70, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x44,
-            0x65, 0x6c, 0x61, 0x79, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x6e, 0x28, 0x29, 0x7d, 0x7d,
-            0x3b, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x3d, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
-            0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69,
-            0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x69, 0x66, 0x28, 0x70, 0x2e, 0x68, 0x61, 0x73, 0x4f, 0x77,
-            0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73,
-            0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x29, 0x7b, 0x74, 0x3d, 0x70, 0x2e, 0x74, 0x72, 0x61,
-            0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d,
-            0x67, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
-            0x7c, 0x7c, 0x74, 0x65, 0x28, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x26, 0x26, 0x61, 0x65, 0x28,
-            0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x54, 0x72,
-            0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x67, 0x2e, 0x65, 0x76, 0x65, 0x6e,
-            0x74, 0x49, 0x6e, 0x66, 0x6f, 0x29, 0x26, 0x26, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x50,
-            0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x21, 0x3d, 0x3d, 0x22, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69,
-            0x6e, 0x65, 0x64, 0x22, 0x26, 0x26, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x73,
-            0x74, 0x61, 0x72, 0x74, 0x56, 0x69, 0x65, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69,
-            0x6f, 0x6e, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x6e, 0x65, 0x77, 0x20,
-            0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x6d, 0x3d, 0x65, 0x3b, 0x6e, 0x3d, 0x74, 0x7d, 0x29, 0x3b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x65, 0x3b, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
-            0x73, 0x74, 0x61, 0x72, 0x74, 0x56, 0x69, 0x65, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74,
-            0x69, 0x6f, 0x6e, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69,
-            0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x7d, 0x29, 0x7d, 0x7d, 0x74,
-            0x72, 0x79, 0x7b, 0x69, 0x66, 0x28, 0x70, 0x3f, 0x2e, 0x73, 0x77, 0x61, 0x70, 0x44, 0x65, 0x6c,
-            0x61, 0x79, 0x26, 0x26, 0x70, 0x2e, 0x73, 0x77, 0x61, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x3e,
-            0x30, 0x29, 0x7b, 0x62, 0x28, 0x29, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75,
-            0x74, 0x28, 0x65, 0x2c, 0x70, 0x2e, 0x73, 0x77, 0x61, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x29,
-            0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x65, 0x28, 0x29, 0x7d, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68,
-            0x28, 0x65, 0x29, 0x7b, 0x66, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x73,
-            0x77, 0x61, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, 0x67, 0x2e, 0x65, 0x76, 0x65, 0x6e,
-            0x74, 0x49, 0x6e, 0x66, 0x6f, 0x29, 0x3b, 0x72, 0x65, 0x28, 0x6e, 0x29, 0x3b, 0x74, 0x68, 0x72,
-            0x6f, 0x77, 0x20, 0x65, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4a,
-            0x65, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72,
-            0x3d, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65,
-            0x61, 0x64, 0x65, 0x72, 0x28, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x69, 0x6e, 0x64,
-            0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x7b, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x76, 0x28, 0x72, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x29, 0x7b, 0x69, 0x66,
-            0x28, 0x6f, 0x2e, 0x68, 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74,
-            0x79, 0x28, 0x69, 0x29, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x6f, 0x5b, 0x69, 0x5d,
-            0x3b, 0x69, 0x66, 0x28, 0x6b, 0x28, 0x65, 0x29, 0x29, 0x7b, 0x6e, 0x3d, 0x65, 0x2e, 0x74, 0x61,
-            0x72, 0x67, 0x65, 0x74, 0x21, 0x3d, 0x3d, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64,
-            0x3f, 0x65, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x6e, 0x7d, 0x65, 0x6c, 0x73, 0x65,
-            0x7b, 0x65, 0x3d, 0x7b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x65, 0x7d, 0x7d, 0x61, 0x65, 0x28,
-            0x6e, 0x2c, 0x69, 0x2c, 0x65, 0x29, 0x7d, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x73, 0x3d, 0x72, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, 0x2c,
-            0x22, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65,
-            0x3c, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x61,
-            0x65, 0x28, 0x6e, 0x2c, 0x73, 0x5b, 0x65, 0x5d, 0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x2c,
-            0x5b, 0x5d, 0x29, 0x7d, 0x7d, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x4b, 0x65, 0x3d, 0x2f,
-            0x5c, 0x73, 0x2f, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x45, 0x3d, 0x2f, 0x5b, 0x5c, 0x73,
-            0x2c, 0x5d, 0x2f, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x47, 0x65, 0x3d, 0x2f, 0x5b, 0x5f,
-            0x24, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x5d, 0x2f, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x57, 0x65, 0x3d, 0x2f, 0x5b, 0x5f, 0x24, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39,
-            0x5d, 0x2f, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x5a, 0x65, 0x3d, 0x5b, 0x27, 0x22, 0x27,
-            0x2c, 0x22, 0x27, 0x22, 0x2c, 0x22, 0x2f, 0x22, 0x5d, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x43, 0x3d, 0x2f, 0x5b, 0x5e, 0x5c, 0x73, 0x5d, 0x2f, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x59, 0x65, 0x3d, 0x2f, 0x5b, 0x7b, 0x28, 0x5d, 0x2f, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x51, 0x65, 0x3d, 0x2f, 0x5b, 0x7d, 0x29, 0x5d, 0x2f, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x65, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74,
-            0x3d, 0x5b, 0x5d, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x3d, 0x30, 0x3b, 0x77, 0x68, 0x69, 0x6c,
-            0x65, 0x28, 0x6e, 0x3c, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x69, 0x66,
-            0x28, 0x47, 0x65, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41,
-            0x74, 0x28, 0x6e, 0x29, 0x29, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x6e, 0x3b, 0x77,
-            0x68, 0x69, 0x6c, 0x65, 0x28, 0x57, 0x65, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, 0x65, 0x2e, 0x63,
-            0x68, 0x61, 0x72, 0x41, 0x74, 0x28, 0x6e, 0x2b, 0x31, 0x29, 0x29, 0x29, 0x7b, 0x6e, 0x2b, 0x2b,
-            0x7d, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x65, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72,
-            0x69, 0x6e, 0x67, 0x28, 0x72, 0x2c, 0x6e, 0x2b, 0x31, 0x29, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65,
-            0x20, 0x69, 0x66, 0x28, 0x5a, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x65,
-            0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, 0x74, 0x28, 0x6e, 0x29, 0x29, 0x21, 0x3d, 0x3d, 0x2d, 0x31,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x72,
-            0x41, 0x74, 0x28, 0x6e, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x6e, 0x3b, 0x6e, 0x2b,
-            0x2b, 0x3b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x6e, 0x3c, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67,
-            0x74, 0x68, 0x26, 0x26, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, 0x74, 0x28, 0x6e, 0x29, 0x21,
-            0x3d, 0x3d, 0x6f, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, 0x74,
-            0x28, 0x6e, 0x29, 0x3d, 0x3d, 0x3d, 0x22, 0x5c, 0x5c, 0x22, 0x29, 0x7b, 0x6e, 0x2b, 0x2b, 0x7d,
-            0x6e, 0x2b, 0x2b, 0x7d, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x65, 0x2e, 0x73, 0x75, 0x62,
-            0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x72, 0x2c, 0x6e, 0x2b, 0x31, 0x29, 0x29, 0x7d, 0x65,
-            0x6c, 0x73, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x65, 0x2e, 0x63, 0x68,
-            0x61, 0x72, 0x41, 0x74, 0x28, 0x6e, 0x29, 0x3b, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x69,
-            0x29, 0x7d, 0x6e, 0x2b, 0x2b, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x74, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e,
-            0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, 0x65, 0x2e, 0x65, 0x78, 0x65, 0x63,
-            0x28, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, 0x74, 0x28, 0x30, 0x29, 0x29, 0x26, 0x26, 0x65,
-            0x21, 0x3d, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x26, 0x26, 0x65, 0x21, 0x3d, 0x3d, 0x22,
-            0x66, 0x61, 0x6c, 0x73, 0x65, 0x22, 0x26, 0x26, 0x65, 0x21, 0x3d, 0x3d, 0x22, 0x74, 0x68, 0x69,
-            0x73, 0x22, 0x26, 0x26, 0x65, 0x21, 0x3d, 0x3d, 0x6e, 0x26, 0x26, 0x74, 0x21, 0x3d, 0x3d, 0x22,
-            0x2e, 0x22, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x74, 0x28, 0x72,
-            0x2c, 0x6f, 0x2c, 0x69, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6f, 0x5b, 0x30, 0x5d, 0x3d, 0x3d, 0x3d,
-            0x22, 0x5b, 0x22, 0x29, 0x7b, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x3b, 0x6c,
-            0x65, 0x74, 0x20, 0x65, 0x3d, 0x31, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x3d, 0x22, 0x20, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x22, 0x2b, 0x69, 0x2b, 0x22, 0x29, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28,
-            0x22, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x77, 0x68, 0x69,
-            0x6c, 0x65, 0x28, 0x6f, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x73, 0x3d, 0x6f, 0x5b, 0x30, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x73,
-            0x3d, 0x3d, 0x3d, 0x22, 0x5d, 0x22, 0x29, 0x7b, 0x65, 0x2d, 0x2d, 0x3b, 0x69, 0x66, 0x28, 0x65,
-            0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6e, 0x3d, 0x3d, 0x3d, 0x6e, 0x75, 0x6c,
-            0x6c, 0x29, 0x7b, 0x74, 0x3d, 0x74, 0x2b, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x7d, 0x6f, 0x2e,
-            0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x3b, 0x74, 0x2b, 0x3d, 0x22, 0x29, 0x7d, 0x29, 0x22,
-            0x3b, 0x74, 0x72, 0x79, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6c, 0x3d, 0x4f, 0x6e, 0x28,
-            0x72, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x28,
-            0x29, 0x7d, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x29, 0x3b, 0x6c, 0x2e, 0x73, 0x6f,
-            0x75, 0x72, 0x63, 0x65, 0x3d, 0x74, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x7d,
-            0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x7b, 0x66, 0x65, 0x28, 0x74, 0x65, 0x28, 0x29,
-            0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x73, 0x79, 0x6e, 0x74,
-            0x61, 0x78, 0x3a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, 0x7b, 0x65, 0x72, 0x72, 0x6f, 0x72,
-            0x3a, 0x65, 0x2c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x74, 0x7d, 0x29, 0x3b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65,
-            0x20, 0x69, 0x66, 0x28, 0x73, 0x3d, 0x3d, 0x3d, 0x22, 0x5b, 0x22, 0x29, 0x7b, 0x65, 0x2b, 0x2b,
-            0x7d, 0x69, 0x66, 0x28, 0x74, 0x74, 0x28, 0x73, 0x2c, 0x6e, 0x2c, 0x69, 0x29, 0x29, 0x7b, 0x74,
-            0x2b, 0x3d, 0x22, 0x28, 0x28, 0x22, 0x2b, 0x69, 0x2b, 0x22, 0x2e, 0x22, 0x2b, 0x73, 0x2b, 0x22,
-            0x29, 0x20, 0x3f, 0x20, 0x28, 0x22, 0x2b, 0x69, 0x2b, 0x22, 0x2e, 0x22, 0x2b, 0x73, 0x2b, 0x22,
-            0x29, 0x20, 0x3a, 0x20, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x22, 0x2b, 0x73, 0x2b,
-            0x22, 0x29, 0x29, 0x22, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x74, 0x3d, 0x74, 0x2b, 0x73, 0x7d,
-            0x6e, 0x3d, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4f, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x6c, 0x65,
-            0x74, 0x20, 0x6e, 0x3d, 0x22, 0x22, 0x3b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x65, 0x2e, 0x6c,
-            0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x26, 0x26, 0x21, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74,
-            0x28, 0x65, 0x5b, 0x30, 0x5d, 0x29, 0x29, 0x7b, 0x6e, 0x2b, 0x3d, 0x65, 0x2e, 0x73, 0x68, 0x69,
-            0x66, 0x74, 0x28, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x6c, 0x65, 0x74,
-            0x20, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30,
-            0x26, 0x26, 0x59, 0x65, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x65, 0x5b, 0x30, 0x5d, 0x29, 0x29,
-            0x7b, 0x65, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x3b, 0x74, 0x3d, 0x4f, 0x28, 0x65,
-            0x2c, 0x51, 0x65, 0x29, 0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x3b, 0x65, 0x2e, 0x73, 0x68,
-            0x69, 0x66, 0x74, 0x28, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x74, 0x3d, 0x4f, 0x28, 0x65,
-            0x2c, 0x45, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x6f, 0x74, 0x3d, 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2c, 0x20, 0x74, 0x65,
-            0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x22, 0x3b,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x74, 0x28, 0x65, 0x2c, 0x74, 0x2c,
-            0x6e, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x5b, 0x5d, 0x3b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x65, 0x74, 0x28, 0x74, 0x29, 0x3b, 0x64, 0x6f, 0x7b, 0x4f,
-            0x28, 0x6f, 0x2c, 0x43, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6c, 0x3d, 0x6f, 0x2e,
-            0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x3d, 0x4f,
-            0x28, 0x6f, 0x2c, 0x2f, 0x5b, 0x2c, 0x5c, 0x5b, 0x5c, 0x73, 0x5d, 0x2f, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x63, 0x21, 0x3d, 0x3d, 0x22, 0x22, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x63, 0x3d, 0x3d, 0x3d,
-            0x22, 0x65, 0x76, 0x65, 0x72, 0x79, 0x22, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x75,
-            0x3d, 0x7b, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x3a, 0x22, 0x65, 0x76, 0x65, 0x72, 0x79,
-            0x22, 0x7d, 0x3b, 0x4f, 0x28, 0x6f, 0x2c, 0x43, 0x29, 0x3b, 0x75, 0x2e, 0x70, 0x6f, 0x6c, 0x6c,
-            0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x3d, 0x64, 0x28, 0x4f, 0x28, 0x6f, 0x2c, 0x2f,
-            0x5b, 0x2c, 0x5c, 0x5b, 0x5c, 0x73, 0x5d, 0x2f, 0x29, 0x29, 0x3b, 0x4f, 0x28, 0x6f, 0x2c, 0x43,
-            0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x6e, 0x74, 0x28, 0x65, 0x2c, 0x6f, 0x2c, 0x22,
-            0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x29, 0x7b, 0x75, 0x2e,
-            0x65, 0x76, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3d, 0x69, 0x7d, 0x72, 0x2e,
-            0x70, 0x75, 0x73, 0x68, 0x28, 0x75, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x66, 0x3d, 0x7b, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x3a, 0x63, 0x7d,
-            0x3b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x6e, 0x74, 0x28, 0x65, 0x2c, 0x6f, 0x2c, 0x22, 0x65,
-            0x76, 0x65, 0x6e, 0x74, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x29, 0x7b, 0x66, 0x2e, 0x65,
-            0x76, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3d, 0x69, 0x7d, 0x4f, 0x28, 0x6f,
-            0x2c, 0x43, 0x29, 0x3b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x6f, 0x2e, 0x6c, 0x65, 0x6e, 0x67,
-            0x74, 0x68, 0x3e, 0x30, 0x26, 0x26, 0x6f, 0x5b, 0x30, 0x5d, 0x21, 0x3d, 0x3d, 0x22, 0x2c, 0x22,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x61, 0x3d, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66,
-            0x74, 0x28, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x61, 0x3d, 0x3d, 0x3d, 0x22, 0x63, 0x68, 0x61, 0x6e,
-            0x67, 0x65, 0x64, 0x22, 0x29, 0x7b, 0x66, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x3d,
-            0x74, 0x72, 0x75, 0x65, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x61, 0x3d, 0x3d,
-            0x3d, 0x22, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x29, 0x7b, 0x66, 0x2e, 0x6f, 0x6e, 0x63, 0x65, 0x3d,
-            0x74, 0x72, 0x75, 0x65, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x61, 0x3d, 0x3d,
-            0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x22, 0x29, 0x7b, 0x66, 0x2e, 0x63, 0x6f,
-            0x6e, 0x73, 0x75, 0x6d, 0x65, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20,
-            0x69, 0x66, 0x28, 0x61, 0x3d, 0x3d, 0x3d, 0x22, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x22, 0x26, 0x26,
-            0x6f, 0x5b, 0x30, 0x5d, 0x3d, 0x3d, 0x3d, 0x22, 0x3a, 0x22, 0x29, 0x7b, 0x6f, 0x2e, 0x73, 0x68,
-            0x69, 0x66, 0x74, 0x28, 0x29, 0x3b, 0x66, 0x2e, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x3d, 0x64, 0x28,
-            0x4f, 0x28, 0x6f, 0x2c, 0x45, 0x29, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28,
-            0x61, 0x3d, 0x3d, 0x3d, 0x22, 0x66, 0x72, 0x6f, 0x6d, 0x22, 0x26, 0x26, 0x6f, 0x5b, 0x30, 0x5d,
-            0x3d, 0x3d, 0x3d, 0x22, 0x3a, 0x22, 0x29, 0x7b, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28,
-            0x29, 0x3b, 0x69, 0x66, 0x28, 0x59, 0x65, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x6f, 0x5b, 0x30,
-            0x5d, 0x29, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x3d, 0x72, 0x74, 0x28, 0x6f, 0x29, 0x7d,
-            0x65, 0x6c, 0x73, 0x65, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x3d, 0x4f, 0x28, 0x6f, 0x2c, 0x45,
-            0x29, 0x3b, 0x69, 0x66, 0x28, 0x73, 0x3d, 0x3d, 0x3d, 0x22, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x73,
-            0x74, 0x22, 0x7c, 0x7c, 0x73, 0x3d, 0x3d, 0x3d, 0x22, 0x66, 0x69, 0x6e, 0x64, 0x22, 0x7c, 0x7c,
-            0x73, 0x3d, 0x3d, 0x3d, 0x22, 0x6e, 0x65, 0x78, 0x74, 0x22, 0x7c, 0x7c, 0x73, 0x3d, 0x3d, 0x3d,
-            0x22, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x22, 0x29, 0x7b, 0x6f, 0x2e, 0x73, 0x68,
-            0x69, 0x66, 0x74, 0x28, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x68, 0x3d, 0x72, 0x74,
-            0x28, 0x6f, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x68, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e,
-            0x30, 0x29, 0x7b, 0x73, 0x2b, 0x3d, 0x22, 0x20, 0x22, 0x2b, 0x68, 0x7d, 0x7d, 0x7d, 0x66, 0x2e,
-            0x66, 0x72, 0x6f, 0x6d, 0x3d, 0x73, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x61,
-            0x3d, 0x3d, 0x3d, 0x22, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x26, 0x26, 0x6f, 0x5b, 0x30,
-            0x5d, 0x3d, 0x3d, 0x3d, 0x22, 0x3a, 0x22, 0x29, 0x7b, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74,
-            0x28, 0x29, 0x3b, 0x66, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x72, 0x74, 0x28, 0x6f,
-            0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x61, 0x3d, 0x3d, 0x3d, 0x22, 0x74,
-            0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x22, 0x26, 0x26, 0x6f, 0x5b, 0x30, 0x5d, 0x3d, 0x3d,
-            0x3d, 0x22, 0x3a, 0x22, 0x29, 0x7b, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x3b,
-            0x66, 0x2e, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x3d, 0x64, 0x28, 0x4f, 0x28, 0x6f,
-            0x2c, 0x45, 0x29, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x61, 0x3d, 0x3d,
-            0x3d, 0x22, 0x71, 0x75, 0x65, 0x75, 0x65, 0x22, 0x26, 0x26, 0x6f, 0x5b, 0x30, 0x5d, 0x3d, 0x3d,
-            0x3d, 0x22, 0x3a, 0x22, 0x29, 0x7b, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x3b,
-            0x66, 0x2e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x3d, 0x4f, 0x28, 0x6f, 0x2c, 0x45, 0x29, 0x7d, 0x65,
-            0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x61, 0x3d, 0x3d, 0x3d, 0x22, 0x72, 0x6f, 0x6f, 0x74,
-            0x22, 0x26, 0x26, 0x6f, 0x5b, 0x30, 0x5d, 0x3d, 0x3d, 0x3d, 0x22, 0x3a, 0x22, 0x29, 0x7b, 0x6f,
-            0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x3b, 0x66, 0x5b, 0x61, 0x5d, 0x3d, 0x72, 0x74,
-            0x28, 0x6f, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x61, 0x3d, 0x3d, 0x3d,
-            0x22, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x22, 0x26, 0x26, 0x6f, 0x5b, 0x30,
-            0x5d, 0x3d, 0x3d, 0x3d, 0x22, 0x3a, 0x22, 0x29, 0x7b, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74,
-            0x28, 0x29, 0x3b, 0x66, 0x5b, 0x61, 0x5d, 0x3d, 0x4f, 0x28, 0x6f, 0x2c, 0x45, 0x29, 0x7d, 0x65,
-            0x6c, 0x73, 0x65, 0x7b, 0x66, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x73,
-            0x79, 0x6e, 0x74, 0x61, 0x78, 0x3a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, 0x7b, 0x74, 0x6f,
-            0x6b, 0x65, 0x6e, 0x3a, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x7d, 0x29, 0x7d,
-            0x4f, 0x28, 0x6f, 0x2c, 0x43, 0x29, 0x7d, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x66, 0x29,
-            0x7d, 0x7d, 0x69, 0x66, 0x28, 0x6f, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3d, 0x3d, 0x3d,
-            0x6c, 0x29, 0x7b, 0x66, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x73, 0x79,
-            0x6e, 0x74, 0x61, 0x78, 0x3a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, 0x7b, 0x74, 0x6f, 0x6b,
-            0x65, 0x6e, 0x3a, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x7d, 0x29, 0x7d, 0x4f,
-            0x28, 0x6f, 0x2c, 0x43, 0x29, 0x7d, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x6f, 0x5b, 0x30, 0x5d,
-            0x3d, 0x3d, 0x3d, 0x22, 0x2c, 0x22, 0x26, 0x26, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28,
-            0x29, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x5b, 0x74, 0x5d, 0x3d, 0x72, 0x7d,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x73, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d,
-            0x61, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x22,
-            0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x3d, 0x5b, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29,
-            0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-            0x67, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x73, 0x43, 0x61,
-            0x63, 0x68, 0x65, 0x3b, 0x6e, 0x3d, 0x72, 0x26, 0x26, 0x72, 0x5b, 0x74, 0x5d, 0x7c, 0x7c, 0x69,
-            0x74, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x72, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x6c, 0x65,
-            0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e,
-            0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x68, 0x28, 0x65, 0x2c, 0x22, 0x66, 0x6f,
-            0x72, 0x6d, 0x22, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x7b, 0x74, 0x72,
-            0x69, 0x67, 0x67, 0x65, 0x72, 0x3a, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x7d, 0x5d,
-            0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x68, 0x28, 0x65, 0x2c, 0x27, 0x69, 0x6e,
-            0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e,
-            0x22, 0x5d, 0x2c, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22,
-            0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x5d, 0x27, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x5b, 0x7b, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x3a, 0x22, 0x63, 0x6c, 0x69,
-            0x63, 0x6b, 0x22, 0x7d, 0x5d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x68, 0x28,
-            0x65, 0x2c, 0x6f, 0x74, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x7b, 0x74,
-            0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x3a, 0x22, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x7d,
-            0x5d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x7b, 0x74,
-            0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x3a, 0x22, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x22, 0x7d, 0x5d,
-            0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x74, 0x28, 0x65, 0x29,
-            0x7b, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x2e, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64,
-            0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63,
-            0x74, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72,
-            0x3d, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x72, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
-            0x3d, 0x62, 0x28, 0x29, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x73, 0x65,
-            0x28, 0x65, 0x29, 0x26, 0x26, 0x72, 0x2e, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64,
-            0x21, 0x3d, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x70, 0x74, 0x28,
-            0x6e, 0x2c, 0x65, 0x2c, 0x58, 0x74, 0x28, 0x22, 0x68, 0x78, 0x3a, 0x70, 0x6f, 0x6c, 0x6c, 0x3a,
-            0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x22, 0x2c, 0x7b, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
-            0x72, 0x53, 0x70, 0x65, 0x63, 0x3a, 0x6e, 0x2c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x65,
-            0x7d, 0x29, 0x29, 0x29, 0x7b, 0x74, 0x28, 0x65, 0x29, 0x7d, 0x63, 0x74, 0x28, 0x65, 0x2c, 0x74,
-            0x2c, 0x6e, 0x29, 0x7d, 0x7d, 0x2c, 0x6e, 0x2e, 0x70, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65,
-            0x72, 0x76, 0x61, 0x6c, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75,
-            0x74, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x63, 0x61,
-            0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d,
-            0x65, 0x2e, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x26, 0x26, 0x65, 0x65, 0x28, 0x65,
-            0x2c, 0x22, 0x68, 0x72, 0x65, 0x66, 0x22, 0x29, 0x26, 0x26, 0x65, 0x65, 0x28, 0x65, 0x2c, 0x22,
-            0x68, 0x72, 0x65, 0x66, 0x22, 0x29, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22,
-            0x23, 0x22, 0x29, 0x21, 0x3d, 0x3d, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x66, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x28,
-            0x65, 0x2c, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62,
-            0x6c, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x74, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x69,
-            0x66, 0x28, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x48,
-            0x54, 0x4d, 0x4c, 0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
-            0x26, 0x26, 0x75, 0x74, 0x28, 0x74, 0x29, 0x26, 0x26, 0x28, 0x74, 0x2e, 0x74, 0x61, 0x72, 0x67,
-            0x65, 0x74, 0x3d, 0x3d, 0x3d, 0x22, 0x22, 0x7c, 0x7c, 0x74, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65,
-            0x74, 0x3d, 0x3d, 0x3d, 0x22, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x22, 0x29, 0x7c, 0x7c, 0x74, 0x2e,
-            0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x46, 0x4f, 0x52, 0x4d, 0x22,
-            0x26, 0x26, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x65, 0x65, 0x28, 0x74, 0x2c, 0x22, 0x6d,
-            0x65, 0x74, 0x68, 0x6f, 0x64, 0x22, 0x29, 0x29, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72,
-            0x43, 0x61, 0x73, 0x65, 0x28, 0x29, 0x21, 0x3d, 0x3d, 0x22, 0x64, 0x69, 0x61, 0x6c, 0x6f, 0x67,
-            0x22, 0x29, 0x7b, 0x6e, 0x2e, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x3d, 0x74, 0x72, 0x75,
-            0x65, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x2c, 0x6f, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x74,
-            0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x41, 0x22, 0x29, 0x7b, 0x72, 0x3d,
-            0x22, 0x67, 0x65, 0x74, 0x22, 0x3b, 0x6f, 0x3d, 0x65, 0x65, 0x28, 0x74, 0x2c, 0x22, 0x68, 0x72,
-            0x65, 0x66, 0x22, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x69, 0x3d, 0x65, 0x65, 0x28, 0x74, 0x2c, 0x22, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x22, 0x29,
-            0x3b, 0x72, 0x3d, 0x69, 0x3f, 0x69, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x43, 0x61,
-            0x73, 0x65, 0x28, 0x29, 0x3a, 0x22, 0x67, 0x65, 0x74, 0x22, 0x3b, 0x6f, 0x3d, 0x65, 0x65, 0x28,
-            0x74, 0x2c, 0x22, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6f,
-            0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7c, 0x7c, 0x6f, 0x3d, 0x3d, 0x3d, 0x22, 0x22, 0x29, 0x7b,
-            0x6f, 0x3d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x68, 0x72, 0x65, 0x66, 0x7d,
-            0x69, 0x66, 0x28, 0x72, 0x3d, 0x3d, 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, 0x26, 0x26, 0x6f, 0x2e,
-            0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x28, 0x22, 0x3f, 0x22, 0x29, 0x29, 0x7b, 0x6f,
-            0x3d, 0x6f, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x5c, 0x3f, 0x5b, 0x5e,
-            0x23, 0x5d, 0x2b, 0x2f, 0x2c, 0x22, 0x22, 0x29, 0x7d, 0x7d, 0x65, 0x2e, 0x66, 0x6f, 0x72, 0x45,
-            0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b,
-            0x67, 0x74, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c,
-            0x74, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x63, 0x65, 0x28, 0x65, 0x29,
-            0x3b, 0x69, 0x66, 0x28, 0x66, 0x74, 0x28, 0x6e, 0x29, 0x29, 0x7b, 0x53, 0x28, 0x6e, 0x29, 0x3b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x68, 0x65, 0x28, 0x72, 0x2c, 0x6f, 0x2c, 0x6e, 0x2c,
-            0x74, 0x29, 0x7d, 0x2c, 0x6e, 0x2c, 0x65, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x7d, 0x29, 0x7d,
-            0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x74, 0x28, 0x65, 0x2c, 0x74,
-            0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x73,
-            0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x26, 0x26, 0x74, 0x2e, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d,
-            0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x46, 0x4f, 0x52, 0x4d, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28,
-            0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x22,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x74, 0x2e, 0x63, 0x6c, 0x6f, 0x73,
-            0x65, 0x73, 0x74, 0x28, 0x27, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d,
-            0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x5d, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6f,
-            0x6e, 0x27, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x26, 0x26, 0x6e, 0x2e, 0x66, 0x6f, 0x72, 0x6d,
-            0x26, 0x26, 0x6e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d,
-            0x69, 0x74, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65,
-            0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x74, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65,
-            0x73, 0x74, 0x28, 0x22, 0x61, 0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d,
-            0x2f, 0x5e, 0x23, 0x2e, 0x2b, 0x2f, 0x3b, 0x69, 0x66, 0x28, 0x72, 0x26, 0x26, 0x72, 0x2e, 0x68,
-            0x72, 0x65, 0x66, 0x26, 0x26, 0x21, 0x6f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x72, 0x2e, 0x67,
-            0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x68, 0x72, 0x65,
-            0x66, 0x22, 0x29, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75,
-            0x65, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x74, 0x28, 0x65, 0x2c, 0x74, 0x29,
-            0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x2e, 0x62, 0x6f,
-            0x6f, 0x73, 0x74, 0x65, 0x64, 0x26, 0x26, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
-            0x65, 0x6f, 0x66, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x45, 0x6c,
-            0x65, 0x6d, 0x65, 0x6e, 0x74, 0x26, 0x26, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x3d,
-            0x22, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x22, 0x26, 0x26, 0x28, 0x74, 0x2e, 0x63, 0x74, 0x72, 0x6c,
-            0x4b, 0x65, 0x79, 0x7c, 0x7c, 0x74, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x29, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x74, 0x28, 0x65, 0x2c, 0x74, 0x2c,
-            0x6e, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x65, 0x2e, 0x65, 0x76, 0x65,
-            0x6e, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3b, 0x69, 0x66, 0x28, 0x72, 0x29, 0x7b, 0x74,
-            0x72, 0x79, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x2e, 0x63, 0x61, 0x6c, 0x6c,
-            0x28, 0x74, 0x2c, 0x6e, 0x29, 0x21, 0x3d, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x63, 0x61, 0x74,
-            0x63, 0x68, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x72, 0x2e,
-            0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3b, 0x66, 0x65, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62,
-            0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x46,
-            0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, 0x7b, 0x65, 0x72,
-            0x72, 0x6f, 0x72, 0x3a, 0x65, 0x2c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x6f, 0x7d, 0x29,
-            0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x7d, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x67, 0x74, 0x28, 0x6c, 0x2c, 0x63, 0x2c, 0x65, 0x2c, 0x75, 0x2c, 0x66,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x61, 0x3d, 0x6f, 0x65, 0x28, 0x6c, 0x29, 0x3b,
-            0x6c, 0x65, 0x74, 0x20, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x29,
-            0x7b, 0x74, 0x3d, 0x6d, 0x28, 0x6c, 0x2c, 0x75, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x29, 0x7d, 0x65,
-            0x6c, 0x73, 0x65, 0x7b, 0x74, 0x3d, 0x5b, 0x6c, 0x5d, 0x7d, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x63,
-            0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x28, 0x22, 0x6c, 0x61,
-            0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x69, 0x6e, 0x20, 0x61, 0x29, 0x29, 0x7b, 0x61,
-            0x2e, 0x6c, 0x61, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x57,
-            0x65, 0x61, 0x6b, 0x4d, 0x61, 0x70, 0x7d, 0x74, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68,
-            0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x21, 0x61, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x68, 0x61, 0x73,
-            0x28, 0x75, 0x29, 0x29, 0x7b, 0x61, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65,
-            0x2e, 0x73, 0x65, 0x74, 0x28, 0x75, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x57, 0x65, 0x61, 0x6b, 0x4d,
-            0x61, 0x70, 0x29, 0x7d, 0x61, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e,
-            0x67, 0x65, 0x74, 0x28, 0x75, 0x29, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x65, 0x2c, 0x65, 0x2e, 0x76,
-            0x61, 0x6c, 0x75, 0x65, 0x29, 0x7d, 0x29, 0x7d, 0x69, 0x65, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x69, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x73,
-            0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x21, 0x73, 0x65, 0x28, 0x6c, 0x29, 0x29, 0x7b, 0x69, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65,
-            0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x75, 0x2e,
-            0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2c, 0x73, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x7d, 0x69, 0x66, 0x28, 0x64, 0x74, 0x28, 0x6c, 0x2c, 0x65, 0x29, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x7d, 0x69, 0x66, 0x28, 0x66, 0x7c, 0x7c, 0x68, 0x74, 0x28, 0x65, 0x2c,
-            0x69, 0x29, 0x29, 0x7b, 0x65, 0x2e, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x66,
-            0x61, 0x75, 0x6c, 0x74, 0x28, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x70, 0x74, 0x28, 0x75, 0x2c, 0x6c,
-            0x2c, 0x65, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x74, 0x3d, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x74, 0x2e, 0x74, 0x72, 0x69, 0x67,
-            0x67, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x3d, 0x75, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x68,
-            0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29,
-            0x7b, 0x74, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x3d, 0x5b, 0x5d,
-            0x7d, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x46, 0x6f, 0x72,
-            0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x6c, 0x29, 0x3c, 0x30, 0x29, 0x7b, 0x74,
-            0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68,
-            0x28, 0x6c, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
-            0x29, 0x7b, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74,
-            0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65,
-            0x74, 0x26, 0x26, 0x65, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x21, 0x68, 0x28, 0x63, 0x65, 0x28, 0x65, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x2c,
-            0x75, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x6f, 0x6e, 0x63, 0x65, 0x29, 0x7b, 0x69, 0x66,
-            0x28, 0x61, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x65, 0x64, 0x4f, 0x6e, 0x63, 0x65,
-            0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x61, 0x2e,
-            0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x65, 0x64, 0x4f, 0x6e, 0x63, 0x65, 0x3d, 0x74, 0x72,
-            0x75, 0x65, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x65, 0x2e, 0x74, 0x61, 0x72, 0x67,
-            0x65, 0x74, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x6e, 0x2e, 0x76, 0x61, 0x6c,
-            0x75, 0x65, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x61, 0x2e, 0x6c, 0x61, 0x73,
-            0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x75, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x6f, 0x2e, 0x68, 0x61, 0x73, 0x28, 0x6e, 0x29, 0x26, 0x26, 0x6f, 0x2e, 0x67, 0x65, 0x74,
-            0x28, 0x6e, 0x29, 0x3d, 0x3d, 0x3d, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d,
-            0x6f, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x6e, 0x2c, 0x72, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x61, 0x2e,
-            0x64, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x29, 0x7b, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x54, 0x69,
-            0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x61, 0x2e, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x29,
-            0x7d, 0x69, 0x66, 0x28, 0x61, 0x2e, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x29, 0x7b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x74, 0x68, 0x72, 0x6f,
-            0x74, 0x74, 0x6c, 0x65, 0x3e, 0x30, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x61, 0x2e, 0x74, 0x68,
-            0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x6c, 0x2c, 0x22, 0x68, 0x74,
-            0x6d, 0x78, 0x3a, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x22, 0x29, 0x3b, 0x63, 0x28, 0x6c,
-            0x2c, 0x65, 0x29, 0x3b, 0x61, 0x2e, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x3d, 0x62,
-            0x28, 0x29, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x61, 0x2e, 0x74, 0x68, 0x72, 0x6f, 0x74,
-            0x74, 0x6c, 0x65, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x2c, 0x75, 0x2e, 0x74, 0x68, 0x72, 0x6f,
-            0x74, 0x74, 0x6c, 0x65, 0x29, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x75,
-            0x2e, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x3e, 0x30, 0x29, 0x7b, 0x61, 0x2e, 0x64, 0x65, 0x6c, 0x61,
-            0x79, 0x65, 0x64, 0x3d, 0x62, 0x28, 0x29, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f,
-            0x75, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x61, 0x65,
-            0x28, 0x6c, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
-            0x22, 0x29, 0x3b, 0x63, 0x28, 0x6c, 0x2c, 0x65, 0x29, 0x7d, 0x2c, 0x75, 0x2e, 0x64, 0x65, 0x6c,
-            0x61, 0x79, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x61, 0x65, 0x28, 0x6c, 0x2c, 0x22, 0x68,
-            0x74, 0x6d, 0x78, 0x3a, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x22, 0x29, 0x3b, 0x63, 0x28,
-            0x6c, 0x2c, 0x65, 0x29, 0x7d, 0x7d, 0x7d, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x6c, 0x69, 0x73,
-            0x74, 0x65, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c,
-            0x29, 0x7b, 0x65, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f,
-            0x73, 0x3d, 0x5b, 0x5d, 0x7d, 0x65, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x49,
-            0x6e, 0x66, 0x6f, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x7b, 0x74, 0x72, 0x69, 0x67, 0x67,
-            0x65, 0x72, 0x3a, 0x75, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2c, 0x6c, 0x69, 0x73,
-            0x74, 0x65, 0x6e, 0x65, 0x72, 0x3a, 0x73, 0x2c, 0x6f, 0x6e, 0x3a, 0x69, 0x7d, 0x29, 0x3b, 0x69,
-            0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65,
-            0x72, 0x28, 0x75, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2c, 0x73, 0x29, 0x7d, 0x29,
-            0x7d, 0x6c, 0x65, 0x74, 0x20, 0x6d, 0x74, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x6c, 0x65,
-            0x74, 0x20, 0x79, 0x74, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x78, 0x74, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x79, 0x74, 0x29, 0x7b,
-            0x79, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x6d, 0x74,
-            0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x3b, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x61, 0x64,
-            0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22,
-            0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x22, 0x2c, 0x79, 0x74, 0x29, 0x3b, 0x77, 0x69, 0x6e, 0x64,
-            0x6f, 0x77, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65,
-            0x6e, 0x65, 0x72, 0x28, 0x22, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x2c, 0x79, 0x74, 0x29,
-            0x3b, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x28, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6d, 0x74, 0x29, 0x7b, 0x6d,
-            0x74, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x69, 0x65, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2e,
-            0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c,
-            0x28, 0x22, 0x5b, 0x68, 0x78, 0x2d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2a, 0x3d, 0x27,
-            0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x27, 0x5d, 0x2c, 0x5b, 0x64, 0x61, 0x74, 0x61,
-            0x2d, 0x68, 0x78, 0x2d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2a, 0x3d, 0x27, 0x72, 0x65,
-            0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x27, 0x5d, 0x22, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x62, 0x74, 0x28, 0x65, 0x29, 0x7d, 0x29, 0x7d, 0x7d,
-            0x2c, 0x32, 0x30, 0x30, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-            0x62, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x73, 0x28, 0x65, 0x2c, 0x22, 0x64,
-            0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x22,
-            0x29, 0x26, 0x26, 0x46, 0x28, 0x65, 0x29, 0x29, 0x7b, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74,
-            0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78,
-            0x2d, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x22, 0x2c, 0x22, 0x74, 0x72, 0x75, 0x65,
-            0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6f, 0x65, 0x28, 0x65, 0x29,
-            0x3b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x48, 0x61, 0x73, 0x68, 0x29, 0x7b,
-            0x61, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x22, 0x29,
-            0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x65, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74,
-            0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x61,
-            0x66, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x22,
-            0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x65,
-            0x2c, 0x22, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x22, 0x29, 0x7d, 0x2c, 0x7b, 0x6f,
-            0x6e, 0x63, 0x65, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x74, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x2c, 0x72,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x6e, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x65,
-            0x64, 0x29, 0x7b, 0x6e, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x3d, 0x74, 0x72, 0x75, 0x65,
-            0x3b, 0x61, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x74, 0x72, 0x69, 0x67,
-            0x67, 0x65, 0x72, 0x22, 0x29, 0x3b, 0x74, 0x28, 0x65, 0x29, 0x7d, 0x7d, 0x3b, 0x69, 0x66, 0x28,
-            0x72, 0x3e, 0x30, 0x29, 0x7b, 0x62, 0x28, 0x29, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65,
-            0x6f, 0x75, 0x74, 0x28, 0x6f, 0x2c, 0x72, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x6f, 0x28,
-            0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x74, 0x28, 0x74,
-            0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x69, 0x3d, 0x66, 0x61, 0x6c, 0x73,
-            0x65, 0x3b, 0x69, 0x65, 0x28, 0x64, 0x65, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x28, 0x72, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x73, 0x28, 0x74, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x22,
-            0x2b, 0x72, 0x29, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x61, 0x28, 0x74,
-            0x2c, 0x22, 0x68, 0x78, 0x2d, 0x22, 0x2b, 0x72, 0x29, 0x3b, 0x69, 0x3d, 0x74, 0x72, 0x75, 0x65,
-            0x3b, 0x6e, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x3d, 0x6f, 0x3b, 0x6e, 0x2e, 0x76, 0x65, 0x72, 0x62,
-            0x3d, 0x72, 0x3b, 0x65, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x53, 0x74, 0x28, 0x74, 0x2c, 0x65, 0x2c,
-            0x6e, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x63, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x66, 0x74, 0x28, 0x6e, 0x29, 0x29, 0x7b, 0x53, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x7d, 0x68, 0x65, 0x28, 0x72, 0x2c, 0x6f, 0x2c, 0x6e, 0x2c, 0x74, 0x29, 0x7d,
-            0x29, 0x7d, 0x29, 0x7d, 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x74, 0x28, 0x72, 0x2c, 0x65, 0x2c,
-            0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
-            0x72, 0x3d, 0x3d, 0x3d, 0x22, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x22, 0x29, 0x7b,
-            0x78, 0x74, 0x28, 0x29, 0x3b, 0x67, 0x74, 0x28, 0x72, 0x2c, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29,
-            0x3b, 0x62, 0x74, 0x28, 0x63, 0x65, 0x28, 0x72, 0x29, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20,
-            0x69, 0x66, 0x28, 0x65, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x3d, 0x3d, 0x3d, 0x22,
-            0x69, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x22, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x6f, 0x3d, 0x7b, 0x7d, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x72, 0x6f, 0x6f, 0x74,
-            0x29, 0x7b, 0x6f, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x3d, 0x75, 0x65, 0x28, 0x72, 0x2c, 0x65, 0x2e,
-            0x72, 0x6f, 0x6f, 0x74, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x73,
-            0x68, 0x6f, 0x6c, 0x64, 0x29, 0x7b, 0x6f, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c,
-            0x64, 0x3d, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x65, 0x2e, 0x74,
-            0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x29, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x69, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65,
-            0x3d, 0x30, 0x3b, 0x65, 0x3c, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b,
-            0x2b, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x74, 0x5b, 0x65, 0x5d, 0x3b,
-            0x69, 0x66, 0x28, 0x6e, 0x2e, 0x69, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74,
-            0x69, 0x6e, 0x67, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72,
-            0x73, 0x65, 0x63, 0x74, 0x22, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x7d, 0x7d, 0x7d, 0x2c,
-            0x6f, 0x29, 0x3b, 0x69, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x28, 0x63, 0x65, 0x28,
-            0x72, 0x29, 0x29, 0x3b, 0x67, 0x74, 0x28, 0x63, 0x65, 0x28, 0x72, 0x29, 0x2c, 0x6e, 0x2c, 0x74,
-            0x2c, 0x65, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x21, 0x74, 0x2e, 0x66,
-            0x69, 0x72, 0x73, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65,
-            0x64, 0x26, 0x26, 0x65, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x3d, 0x3d, 0x3d, 0x22,
-            0x6c, 0x6f, 0x61, 0x64, 0x22, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x70, 0x74, 0x28, 0x65, 0x2c,
-            0x72, 0x2c, 0x58, 0x74, 0x28, 0x22, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x2c, 0x7b, 0x65, 0x6c, 0x74,
-            0x3a, 0x72, 0x7d, 0x29, 0x29, 0x29, 0x7b, 0x76, 0x74, 0x28, 0x63, 0x65, 0x28, 0x72, 0x29, 0x2c,
-            0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2e, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x29, 0x7d, 0x7d, 0x65, 0x6c,
-            0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x70, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65,
-            0x72, 0x76, 0x61, 0x6c, 0x3e, 0x30, 0x29, 0x7b, 0x74, 0x2e, 0x70, 0x6f, 0x6c, 0x6c, 0x69, 0x6e,
-            0x67, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x63, 0x74, 0x28, 0x63, 0x65, 0x28, 0x72, 0x29, 0x2c,
-            0x6e, 0x2c, 0x65, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x67, 0x74, 0x28, 0x72, 0x2c, 0x6e,
-            0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-            0x45, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x63, 0x65,
-            0x28, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d,
-            0x74, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x3b, 0x66, 0x6f, 0x72,
-            0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65, 0x3c, 0x6e, 0x2e, 0x6c, 0x65, 0x6e,
-            0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72,
-            0x3d, 0x6e, 0x5b, 0x65, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x6c, 0x28,
-            0x72, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x6f, 0x6e, 0x3a, 0x22, 0x29, 0x7c, 0x7c, 0x6c, 0x28, 0x72,
-            0x2c, 0x22, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x6f, 0x6e, 0x3a, 0x22, 0x29, 0x7c,
-            0x7c, 0x6c, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x6f, 0x6e, 0x2d, 0x22, 0x29, 0x7c, 0x7c,
-            0x6c, 0x28, 0x72, 0x2c, 0x22, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x6f, 0x6e, 0x2d,
-            0x22, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x7d,
-            0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x43, 0x74, 0x3d, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x58, 0x50, 0x61, 0x74,
-            0x68, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x29, 0x2e, 0x63, 0x72, 0x65, 0x61,
-            0x74, 0x65, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x27, 0x2e, 0x2f,
-            0x2f, 0x2a, 0x5b, 0x40, 0x2a, 0x5b, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x2d, 0x77, 0x69,
-            0x74, 0x68, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x2c, 0x20, 0x22, 0x68, 0x78, 0x2d, 0x6f,
-            0x6e, 0x3a, 0x22, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x2d, 0x77,
-            0x69, 0x74, 0x68, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74,
-            0x61, 0x2d, 0x68, 0x78, 0x2d, 0x6f, 0x6e, 0x3a, 0x22, 0x29, 0x20, 0x6f, 0x72, 0x27, 0x2b, 0x27,
-            0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x2d, 0x77, 0x69, 0x74, 0x68, 0x28, 0x6e, 0x61, 0x6d,
-            0x65, 0x28, 0x29, 0x2c, 0x20, 0x22, 0x68, 0x78, 0x2d, 0x6f, 0x6e, 0x2d, 0x22, 0x29, 0x20, 0x6f,
-            0x72, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x2d, 0x77, 0x69, 0x74, 0x68, 0x28, 0x6e, 0x61,
-            0x6d, 0x65, 0x28, 0x29, 0x2c, 0x20, 0x22, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x6f,
-            0x6e, 0x2d, 0x22, 0x29, 0x20, 0x5d, 0x5d, 0x27, 0x29, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x4f, 0x74, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x45, 0x74,
-            0x28, 0x65, 0x29, 0x29, 0x7b, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x63, 0x65, 0x28, 0x65,
-            0x29, 0x29, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x43, 0x74, 0x2e, 0x65, 0x76,
-            0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x3d,
-            0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x72, 0x3d, 0x6e, 0x2e, 0x69,
-            0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x28, 0x29, 0x29, 0x74, 0x2e, 0x70,
-            0x75, 0x73, 0x68, 0x28, 0x63, 0x65, 0x28, 0x72, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x48, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x74, 0x3d, 0x5b, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
-            0x63, 0x65, 0x6f, 0x66, 0x20, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x72, 0x61,
-            0x67, 0x6d, 0x65, 0x6e, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64,
-            0x65, 0x73, 0x29, 0x7b, 0x4f, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x7b, 0x4f, 0x74, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x74, 0x28, 0x65,
-            0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65,
-            0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e,
-            0x3d, 0x22, 0x2c, 0x20, 0x5b, 0x68, 0x78, 0x2d, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x5d, 0x20, 0x61,
-            0x2c, 0x20, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x62, 0x6f, 0x6f, 0x73, 0x74,
-            0x5d, 0x20, 0x61, 0x2c, 0x20, 0x61, 0x5b, 0x68, 0x78, 0x2d, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x5d,
-            0x2c, 0x20, 0x61, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x62, 0x6f, 0x6f, 0x73,
-            0x74, 0x5d, 0x22, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x5b, 0x5d, 0x3b, 0x66,
-            0x6f, 0x72, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x20, 0x69, 0x6e, 0x20, 0x6a, 0x6e,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x73, 0x3d, 0x6a, 0x6e, 0x5b, 0x69, 0x5d, 0x3b,
-            0x69, 0x66, 0x28, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72,
-            0x73, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x53, 0x65,
-            0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x28, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b,
-            0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x29, 0x7d, 0x7d, 0x7d, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x6f, 0x3d, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63,
-            0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x52, 0x2b, 0x6e, 0x2b, 0x22, 0x2c, 0x20, 0x66, 0x6f,
-            0x72, 0x6d, 0x2c, 0x20, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x27, 0x73, 0x75, 0x62, 0x6d, 0x69,
-            0x74, 0x27, 0x5d, 0x2c, 0x22, 0x2b, 0x22, 0x20, 0x5b, 0x68, 0x78, 0x2d, 0x65, 0x78, 0x74, 0x5d,
-            0x2c, 0x20, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x65, 0x78, 0x74, 0x5d, 0x2c,
-            0x20, 0x5b, 0x68, 0x78, 0x2d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5d, 0x2c, 0x20, 0x5b,
-            0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5d,
-            0x22, 0x2b, 0x72, 0x2e, 0x66, 0x6c, 0x61, 0x74, 0x28, 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x65,
-            0x3d, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x2b, 0x65, 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22,
-            0x22, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x5d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x74, 0x3d, 0x41, 0x74, 0x28, 0x65, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x3b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x4e, 0x74, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e,
-            0x43, 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x3d, 0x74, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x71, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x74, 0x3d, 0x4e, 0x74, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x74, 0x2e,
-            0x6c, 0x61, 0x73, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x65,
-            0x64, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x41, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x28,
-            0x63, 0x65, 0x28, 0x65, 0x29, 0x2c, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x2c, 0x20, 0x69,
-            0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x27, 0x73, 0x75, 0x62, 0x6d, 0x69,
-            0x74, 0x27, 0x5d, 0x22, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4c,
-            0x74, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x66, 0x6f,
-            0x72, 0x6d, 0x7c, 0x7c, 0x67, 0x28, 0x65, 0x2c, 0x22, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x29, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x41, 0x74, 0x28, 0x65, 0x2e, 0x74, 0x61, 0x72, 0x67,
-            0x65, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x4c, 0x74, 0x28, 0x74, 0x29, 0x3b,
-            0x69, 0x66, 0x28, 0x21, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x65, 0x28, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x49, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x65, 0x2e, 0x61, 0x64, 0x64, 0x45,
-            0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x63, 0x6c,
-            0x69, 0x63, 0x6b, 0x22, 0x2c, 0x52, 0x74, 0x29, 0x3b, 0x65, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76,
-            0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x66, 0x6f, 0x63,
-            0x75, 0x73, 0x69, 0x6e, 0x22, 0x2c, 0x52, 0x74, 0x29, 0x3b, 0x65, 0x2e, 0x61, 0x64, 0x64, 0x45,
-            0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x66, 0x6f,
-            0x63, 0x75, 0x73, 0x6f, 0x75, 0x74, 0x22, 0x2c, 0x71, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x74, 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x6e, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x6f, 0x65, 0x28, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28,
-            0x21, 0x41, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x69, 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x72,
-            0x2e, 0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x29, 0x29, 0x7b, 0x72, 0x2e,
-            0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x3d, 0x5b, 0x5d, 0x7d, 0x6c, 0x65,
-            0x74, 0x20, 0x6f, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x4f, 0x6e, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x66, 0x74, 0x28, 0x74, 0x29,
-            0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x69, 0x66, 0x28, 0x21, 0x6f, 0x29, 0x7b,
-            0x6f, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x22,
-            0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x6e, 0x29, 0x7d, 0x6f, 0x2e, 0x63, 0x61, 0x6c, 0x6c,
-            0x28, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x29, 0x7d, 0x3b, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76,
-            0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x65, 0x2c, 0x69, 0x29,
-            0x3b, 0x72, 0x2e, 0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x75,
-            0x73, 0x68, 0x28, 0x7b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3a, 0x65, 0x2c, 0x6c, 0x69, 0x73, 0x74,
-            0x65, 0x6e, 0x65, 0x72, 0x3a, 0x69, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x50, 0x74, 0x28, 0x74, 0x29, 0x7b, 0x50, 0x65, 0x28, 0x74, 0x29, 0x3b, 0x66, 0x6f,
-            0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65, 0x3c, 0x74, 0x2e, 0x61, 0x74,
-            0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b,
-            0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x74, 0x2e, 0x61,
-            0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5b, 0x65, 0x5d, 0x2e, 0x6e, 0x61, 0x6d,
-            0x65, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x74, 0x2e, 0x61, 0x74, 0x74, 0x72,
-            0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5b, 0x65, 0x5d, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3b,
-            0x69, 0x66, 0x28, 0x6c, 0x28, 0x6e, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x6f, 0x6e, 0x22, 0x29, 0x7c,
-            0x7c, 0x6c, 0x28, 0x6e, 0x2c, 0x22, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x6f, 0x6e,
-            0x22, 0x29, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x6e, 0x2e, 0x69, 0x6e,
-            0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x2d, 0x6f, 0x6e, 0x22, 0x29, 0x2b, 0x33, 0x3b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x6e, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x6f,
-            0x2c, 0x6f, 0x2b, 0x31, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x3d, 0x3d, 0x3d, 0x22, 0x2d, 0x22,
-            0x7c, 0x7c, 0x69, 0x3d, 0x3d, 0x3d, 0x22, 0x3a, 0x22, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x65,
-            0x3d, 0x6e, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x6f, 0x2b, 0x31, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x6c, 0x28, 0x65, 0x2c, 0x22, 0x3a, 0x22, 0x29, 0x29, 0x7b, 0x65, 0x3d, 0x22, 0x68, 0x74,
-            0x6d, 0x78, 0x22, 0x2b, 0x65, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x6c, 0x28,
-            0x65, 0x2c, 0x22, 0x2d, 0x22, 0x29, 0x29, 0x7b, 0x65, 0x3d, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a,
-            0x22, 0x2b, 0x65, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x31, 0x29, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x20, 0x69, 0x66, 0x28, 0x6c, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x2d, 0x22,
-            0x29, 0x29, 0x7b, 0x65, 0x3d, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x22, 0x2b, 0x65, 0x2e, 0x73,
-            0x6c, 0x69, 0x63, 0x65, 0x28, 0x35, 0x29, 0x7d, 0x44, 0x74, 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x72,
-            0x29, 0x7d, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6b, 0x74,
-            0x28, 0x74, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x74, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x62,
-            0x65, 0x66, 0x6f, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x6f, 0x64, 0x65,
-            0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x6f, 0x65, 0x28, 0x74, 0x29,
-            0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d, 0x73, 0x74, 0x28, 0x74, 0x29, 0x3b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x77, 0x74, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x29,
-            0x3b, 0x69, 0x66, 0x28, 0x21, 0x72, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6e, 0x65, 0x28, 0x74, 0x2c,
-            0x22, 0x68, 0x78, 0x2d, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x22, 0x74,
-            0x72, 0x75, 0x65, 0x22, 0x29, 0x7b, 0x61, 0x74, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x7d,
-            0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x73, 0x28, 0x74, 0x2c, 0x22, 0x68, 0x78, 0x2d,
-            0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x22, 0x29, 0x29, 0x7b, 0x65, 0x2e, 0x66, 0x6f, 0x72,
-            0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29,
-            0x7b, 0x53, 0x74, 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x6e, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x7d, 0x29, 0x7d, 0x29, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x2e,
-            0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x46, 0x4f, 0x52, 0x4d, 0x22,
-            0x7c, 0x7c, 0x65, 0x65, 0x28, 0x74, 0x2c, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x29, 0x3d, 0x3d,
-            0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x26, 0x26, 0x73, 0x28, 0x74, 0x2c, 0x22,
-            0x66, 0x6f, 0x72, 0x6d, 0x22, 0x29, 0x29, 0x7b, 0x49, 0x74, 0x28, 0x74, 0x29, 0x7d, 0x6e, 0x2e,
-            0x66, 0x69, 0x72, 0x73, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74,
-            0x65, 0x64, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x61, 0x65, 0x28, 0x74, 0x2c, 0x22, 0x68, 0x74,
-            0x6d, 0x78, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e,
-            0x6f, 0x64, 0x65, 0x22, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4d,
-            0x74, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x28, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74,
-            0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x29, 0x29,
-            0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x6e, 0x3d, 0x44, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x69,
-            0x6e, 0x69, 0x74, 0x48, 0x61, 0x73, 0x68, 0x21, 0x3d, 0x3d, 0x6e, 0x29, 0x7b, 0x6b, 0x65, 0x28,
-            0x65, 0x29, 0x3b, 0x74, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x48, 0x61, 0x73, 0x68, 0x3d, 0x6e, 0x3b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x46, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x65, 0x3d, 0x77, 0x28, 0x65, 0x29, 0x3b, 0x69,
-            0x66, 0x28, 0x66, 0x74, 0x28, 0x65, 0x29, 0x29, 0x7b, 0x53, 0x28, 0x65, 0x29, 0x3b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x5b, 0x5d, 0x3b,
-            0x69, 0x66, 0x28, 0x4d, 0x74, 0x28, 0x65, 0x29, 0x29, 0x7b, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68,
-            0x28, 0x65, 0x29, 0x7d, 0x69, 0x65, 0x28, 0x54, 0x74, 0x28, 0x65, 0x29, 0x2c, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x66, 0x74, 0x28, 0x65,
-            0x29, 0x29, 0x7b, 0x53, 0x28, 0x65, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x69,
-            0x66, 0x28, 0x4d, 0x74, 0x28, 0x65, 0x29, 0x29, 0x7b, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28,
-            0x65, 0x29, 0x7d, 0x7d, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x48, 0x74, 0x28, 0x65, 0x29, 0x2c, 0x50,
-            0x74, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x74, 0x2c, 0x6b, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x28, 0x5b, 0x61,
-            0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x28, 0x5b, 0x41, 0x2d, 0x5a, 0x5d, 0x29, 0x2f, 0x67,
-            0x2c, 0x22, 0x24, 0x31, 0x2d, 0x24, 0x32, 0x22, 0x29, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65,
-            0x72, 0x43, 0x61, 0x73, 0x65, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x58, 0x74, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x6e, 0x65, 0x77, 0x20, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x28,
-            0x65, 0x2c, 0x7b, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x73, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c,
-            0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c,
-            0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x64, 0x65,
-            0x74, 0x61, 0x69, 0x6c, 0x3a, 0x74, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x66, 0x65, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x65,
-            0x2c, 0x74, 0x2c, 0x6c, 0x65, 0x28, 0x7b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x74, 0x7d, 0x2c,
-            0x6e, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x55, 0x74, 0x28,
-            0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x68,
-            0x74, 0x6d, 0x78, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
-            0x4e, 0x6f, 0x64, 0x65, 0x22, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56,
-            0x74, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x69, 0x65, 0x28, 0x4a, 0x6e, 0x28, 0x65,
-            0x2c, 0x5b, 0x5d, 0x2c, 0x6e, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x65, 0x29, 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x74, 0x28, 0x65, 0x29, 0x7d, 0x63, 0x61, 0x74, 0x63,
-            0x68, 0x28, 0x65, 0x29, 0x7b, 0x48, 0x28, 0x65, 0x29, 0x7d, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x48, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
-            0x6c, 0x65, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x65, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x65, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x65,
-            0x3d, 0x77, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c,
-            0x29, 0x7b, 0x6e, 0x3d, 0x7b, 0x7d, 0x7d, 0x6e, 0x2e, 0x65, 0x6c, 0x74, 0x3d, 0x65, 0x3b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x58, 0x74, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x3b, 0x69,
-            0x66, 0x28, 0x51, 0x2e, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x72, 0x26, 0x26, 0x21, 0x55, 0x74, 0x28,
-            0x74, 0x29, 0x29, 0x7b, 0x51, 0x2e, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x72, 0x28, 0x65, 0x2c, 0x74,
-            0x2c, 0x6e, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x29, 0x7b,
-            0x48, 0x28, 0x6e, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x29, 0x3b, 0x61, 0x65, 0x28, 0x65, 0x2c,
-            0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, 0x7b, 0x65, 0x72,
-            0x72, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x3a, 0x6e, 0x7d, 0x29, 0x7d, 0x6c, 0x65, 0x74, 0x20,
-            0x6f, 0x3d, 0x65, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e,
-            0x74, 0x28, 0x72, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x42, 0x74, 0x28,
-            0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6f, 0x26, 0x26, 0x69, 0x21, 0x3d, 0x3d, 0x74, 0x29, 0x7b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x73, 0x3d, 0x58, 0x74, 0x28, 0x69, 0x2c, 0x72, 0x2e, 0x64,
-            0x65, 0x74, 0x61, 0x69, 0x6c, 0x29, 0x3b, 0x6f, 0x3d, 0x6f, 0x26, 0x26, 0x65, 0x2e, 0x64, 0x69,
-            0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x28, 0x73, 0x29, 0x7d, 0x56,
-            0x74, 0x28, 0x63, 0x65, 0x28, 0x65, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x28, 0x65, 0x29, 0x7b, 0x6f, 0x3d, 0x6f, 0x26, 0x26, 0x28, 0x65, 0x2e, 0x6f, 0x6e, 0x45, 0x76,
-            0x65, 0x6e, 0x74, 0x28, 0x74, 0x2c, 0x72, 0x29, 0x21, 0x3d, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65,
-            0x26, 0x26, 0x21, 0x72, 0x2e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x76,
-            0x65, 0x6e, 0x74, 0x65, 0x64, 0x29, 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x6f, 0x7d, 0x6c, 0x65, 0x74, 0x20, 0x6a, 0x74, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x24, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x6a, 0x74, 0x3d, 0x65, 0x3b, 0x69, 0x66, 0x28,
-            0x58, 0x28, 0x29, 0x29, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x6f, 0x72,
-            0x61, 0x67, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x28, 0x22, 0x68, 0x74, 0x6d,
-            0x78, 0x2d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x70, 0x61, 0x74, 0x68, 0x2d, 0x66,
-            0x6f, 0x72, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x65, 0x29, 0x7d, 0x7d,
-            0x24, 0x74, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x61, 0x74, 0x68,
-            0x6e, 0x61, 0x6d, 0x65, 0x2b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x65,
-            0x61, 0x72, 0x63, 0x68, 0x29, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f,
-            0x74, 0x28, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d, 0x74, 0x65, 0x28, 0x29,
-            0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x28, 0x22,
-            0x5b, 0x68, 0x78, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2d, 0x65, 0x6c, 0x74, 0x5d,
-            0x2c, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72,
-            0x79, 0x2d, 0x65, 0x6c, 0x74, 0x5d, 0x22, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x65, 0x7c, 0x7c, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7a, 0x74, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x69, 0x66,
-            0x28, 0x21, 0x58, 0x28, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x4b, 0x74, 0x28, 0x65, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x72, 0x3d, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x63,
-            0x72, 0x6f, 0x6c, 0x6c, 0x59, 0x3b, 0x69, 0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-            0x67, 0x2e, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69,
-            0x7a, 0x65, 0x3c, 0x3d, 0x30, 0x29, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
-            0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x74, 0x65, 0x6d,
-            0x28, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2d, 0x63,
-            0x61, 0x63, 0x68, 0x65, 0x22, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x74, 0x3d,
-            0x55, 0x28, 0x74, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x76, 0x28, 0x73,
-            0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x67, 0x65,
-            0x74, 0x49, 0x74, 0x65, 0x6d, 0x28, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x2d, 0x68, 0x69, 0x73, 0x74,
-            0x6f, 0x72, 0x79, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x22, 0x29, 0x29, 0x7c, 0x7c, 0x5b, 0x5d,
-            0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65, 0x3c, 0x69,
-            0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x69, 0x5b, 0x65, 0x5d, 0x2e, 0x75, 0x72, 0x6c, 0x3d, 0x3d, 0x3d, 0x74, 0x29, 0x7b, 0x69, 0x2e,
-            0x73, 0x70, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, 0x2c, 0x31, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61,
-            0x6b, 0x7d, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x73, 0x3d, 0x7b, 0x75, 0x72, 0x6c, 0x3a,
-            0x74, 0x2c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x6e, 0x2c, 0x74, 0x69, 0x74, 0x6c,
-            0x65, 0x3a, 0x72, 0x2c, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x6f, 0x7d, 0x3b, 0x61, 0x65,
-            0x28, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78,
-            0x3a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x74, 0x65, 0x6d, 0x43, 0x72, 0x65, 0x61,
-            0x74, 0x65, 0x64, 0x22, 0x2c, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x3a, 0x73, 0x2c, 0x63, 0x61, 0x63,
-            0x68, 0x65, 0x3a, 0x69, 0x7d, 0x29, 0x3b, 0x69, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x73, 0x29,
-            0x3b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x69, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e,
-            0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
-            0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x29, 0x7b, 0x69, 0x2e, 0x73, 0x68, 0x69,
-            0x66, 0x74, 0x28, 0x29, 0x7d, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x69, 0x2e, 0x6c, 0x65, 0x6e,
-            0x67, 0x74, 0x68, 0x3e, 0x30, 0x29, 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69,
-            0x6f, 0x6e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x49, 0x74, 0x65,
-            0x6d, 0x28, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2d,
-            0x63, 0x61, 0x63, 0x68, 0x65, 0x22, 0x2c, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69,
-            0x6e, 0x67, 0x69, 0x66, 0x79, 0x28, 0x69, 0x29, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x7d,
-            0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x7b, 0x66, 0x65, 0x28, 0x74, 0x65, 0x28, 0x29,
-            0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x68, 0x69, 0x73, 0x74,
-            0x6f, 0x72, 0x79, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, 0x7b,
-            0x63, 0x61, 0x75, 0x73, 0x65, 0x3a, 0x65, 0x2c, 0x63, 0x61, 0x63, 0x68, 0x65, 0x3a, 0x69, 0x7d,
-            0x29, 0x3b, 0x69, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4a, 0x74, 0x28, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x21, 0x58, 0x28, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c,
-            0x6c, 0x7d, 0x74, 0x3d, 0x55, 0x28, 0x74, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e,
-            0x3d, 0x76, 0x28, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67,
-            0x65, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x28, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x2d,
-            0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x22, 0x29, 0x29,
-            0x7c, 0x7c, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x30,
-            0x3b, 0x65, 0x3c, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29,
-            0x7b, 0x69, 0x66, 0x28, 0x6e, 0x5b, 0x65, 0x5d, 0x2e, 0x75, 0x72, 0x6c, 0x3d, 0x3d, 0x3d, 0x74,
-            0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x5b, 0x65, 0x5d, 0x7d, 0x7d, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x4b, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x74, 0x3d, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65,
-            0x73, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d,
-            0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x74, 0x72, 0x75, 0x65,
-            0x29, 0x3b, 0x69, 0x65, 0x28, 0x78, 0x28, 0x6e, 0x2c, 0x22, 0x2e, 0x22, 0x2b, 0x74, 0x29, 0x2c,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x47, 0x28, 0x65, 0x2c,
-            0x74, 0x29, 0x7d, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x78, 0x28, 0x6e, 0x2c, 0x22, 0x5b, 0x64, 0x61,
-            0x74, 0x61, 0x2d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2d, 0x62, 0x79, 0x2d, 0x68,
-            0x74, 0x6d, 0x78, 0x5d, 0x22, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x65, 0x29, 0x7b, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69,
-            0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x29,
-            0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x69, 0x6e, 0x6e, 0x65,
-            0x72, 0x48, 0x54, 0x4d, 0x4c, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x47,
-            0x74, 0x28, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d, 0x5f, 0x74, 0x28, 0x29,
-            0x3b, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x3d, 0x6a, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x58, 0x28, 0x29,
-            0x29, 0x7b, 0x74, 0x3d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x6f, 0x72, 0x61,
-            0x67, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x28, 0x22, 0x68, 0x74, 0x6d, 0x78,
-            0x2d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x70, 0x61, 0x74, 0x68, 0x2d, 0x66, 0x6f,
-            0x72, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x29, 0x7d, 0x74, 0x3d, 0x74, 0x7c,
-            0x7c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x6e, 0x61,
-            0x6d, 0x65, 0x2b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x61, 0x72,
-            0x63, 0x68, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x74, 0x65, 0x28, 0x29, 0x2e,
-            0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x28, 0x27, 0x5b,
-            0x68, 0x78, 0x2d, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x3d, 0x22, 0x66, 0x61, 0x6c, 0x73,
-            0x65, 0x22, 0x20, 0x69, 0x5d, 0x2c, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x68,
-            0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x3d, 0x22, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x22, 0x20, 0x69,
-            0x5d, 0x27, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x6e, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x74, 0x65,
-            0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x62, 0x65,
-            0x66, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x61, 0x76, 0x65, 0x22,
-            0x2c, 0x7b, 0x70, 0x61, 0x74, 0x68, 0x3a, 0x74, 0x2c, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
-            0x45, 0x6c, 0x74, 0x3a, 0x65, 0x7d, 0x29, 0x3b, 0x7a, 0x74, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7d,
-            0x69, 0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x68, 0x69, 0x73, 0x74,
-            0x6f, 0x72, 0x79, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x29, 0x68, 0x69, 0x73, 0x74, 0x6f,
-            0x72, 0x79, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x28,
-            0x7b, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x2c, 0x74, 0x65, 0x28, 0x29,
-            0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x2c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
-            0x68, 0x72, 0x65, 0x66, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x57,
-            0x74, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-            0x2e, 0x67, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x42, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50,
-            0x61, 0x72, 0x61, 0x6d, 0x29, 0x7b, 0x65, 0x3d, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63,
-            0x65, 0x28, 0x2f, 0x6f, 0x72, 0x67, 0x5c, 0x2e, 0x68, 0x74, 0x6d, 0x78, 0x5c, 0x2e, 0x63, 0x61,
-            0x63, 0x68, 0x65, 0x2d, 0x62, 0x75, 0x73, 0x74, 0x65, 0x72, 0x3d, 0x5b, 0x5e, 0x26, 0x5d, 0x2a,
-            0x26, 0x3f, 0x2f, 0x2c, 0x22, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x59, 0x28, 0x65, 0x2c, 0x22,
-            0x26, 0x22, 0x29, 0x7c, 0x7c, 0x59, 0x28, 0x65, 0x2c, 0x22, 0x3f, 0x22, 0x29, 0x29, 0x7b, 0x65,
-            0x3d, 0x65, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2c, 0x2d, 0x31, 0x29, 0x7d, 0x7d,
-            0x69, 0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x68, 0x69, 0x73, 0x74,
-            0x6f, 0x72, 0x79, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x29, 0x7b, 0x68, 0x69, 0x73, 0x74,
-            0x6f, 0x72, 0x79, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x28, 0x7b, 0x68,
-            0x74, 0x6d, 0x78, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x2c, 0x22, 0x22, 0x2c, 0x65, 0x29, 0x7d,
-            0x24, 0x74, 0x28, 0x65, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5a,
-            0x74, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-            0x2e, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x29,
-            0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x53,
-            0x74, 0x61, 0x74, 0x65, 0x28, 0x7b, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x7d,
-            0x2c, 0x22, 0x22, 0x2c, 0x65, 0x29, 0x3b, 0x24, 0x74, 0x28, 0x65, 0x29, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x59, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x65, 0x28, 0x65,
-            0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x65, 0x2e, 0x63,
-            0x61, 0x6c, 0x6c, 0x28, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x29, 0x7d, 0x29,
-            0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x51, 0x74, 0x28, 0x65, 0x29, 0x7b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x58, 0x4d, 0x4c, 0x48,
-            0x74, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x6e, 0x3d, 0x7b, 0x73, 0x77, 0x61, 0x70, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x3a, 0x22, 0x69,
-            0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x22, 0x2c, 0x73, 0x77, 0x61, 0x70, 0x44, 0x65,
-            0x6c, 0x61, 0x79, 0x3a, 0x30, 0x2c, 0x73, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x61,
-            0x79, 0x3a, 0x30, 0x7d, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x7b, 0x70, 0x61,
-            0x74, 0x68, 0x3a, 0x65, 0x2c, 0x78, 0x68, 0x72, 0x3a, 0x74, 0x2c, 0x68, 0x69, 0x73, 0x74, 0x6f,
-            0x72, 0x79, 0x45, 0x6c, 0x74, 0x3a, 0x5f, 0x74, 0x28, 0x29, 0x2c, 0x73, 0x77, 0x61, 0x70, 0x53,
-            0x70, 0x65, 0x63, 0x3a, 0x6e, 0x7d, 0x3b, 0x74, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x22, 0x47,
-            0x45, 0x54, 0x22, 0x2c, 0x65, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x51,
-            0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52,
-            0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x41, 0x73, 0x48, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-            0x74, 0x29, 0x7b, 0x74, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48,
-            0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 0x48, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-            0x74, 0x22, 0x2c, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x29, 0x7d, 0x74, 0x2e, 0x73, 0x65, 0x74,
-            0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 0x48,
-            0x58, 0x2d, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2d, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72,
-            0x65, 0x2d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2c, 0x22, 0x74, 0x72, 0x75, 0x65,
-            0x22, 0x29, 0x3b, 0x74, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48,
-            0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 0x48, 0x58, 0x2d, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e,
-            0x74, 0x2d, 0x55, 0x52, 0x4c, 0x22, 0x2c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
-            0x68, 0x72, 0x65, 0x66, 0x29, 0x3b, 0x74, 0x2e, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x3d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x68, 0x69,
-            0x73, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3e, 0x3d, 0x32, 0x30, 0x30, 0x26, 0x26, 0x74,
-            0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3c, 0x34, 0x30, 0x30, 0x29, 0x7b,
-            0x72, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e,
-            0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3b, 0x61, 0x65, 0x28, 0x74, 0x65, 0x28, 0x29,
-            0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x68, 0x69, 0x73, 0x74,
-            0x6f, 0x72, 0x79, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64,
-            0x22, 0x2c, 0x72, 0x29, 0x3b, 0x7a, 0x65, 0x28, 0x72, 0x2e, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72,
-            0x79, 0x45, 0x6c, 0x74, 0x2c, 0x72, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2c,
-            0x6e, 0x2c, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
-            0x74, 0x3a, 0x72, 0x2e, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6c, 0x74, 0x2c, 0x68,
-            0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x3a, 0x74, 0x72,
-            0x75, 0x65, 0x7d, 0x29, 0x3b, 0x24, 0x74, 0x28, 0x72, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x29, 0x3b,
-            0x61, 0x65, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74,
-            0x6d, 0x78, 0x3a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72,
-            0x65, 0x22, 0x2c, 0x7b, 0x70, 0x61, 0x74, 0x68, 0x3a, 0x65, 0x2c, 0x63, 0x61, 0x63, 0x68, 0x65,
-            0x4d, 0x69, 0x73, 0x73, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
-            0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3a, 0x72, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f,
-            0x6e, 0x73, 0x65, 0x7d, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x66, 0x65, 0x28, 0x74, 0x65,
-            0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x68, 0x69,
-            0x73, 0x74, 0x6f, 0x72, 0x79, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x4c, 0x6f,
-            0x61, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, 0x72, 0x29, 0x7d, 0x7d, 0x3b, 0x69, 0x66,
-            0x28, 0x61, 0x65, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68,
-            0x74, 0x6d, 0x78, 0x3a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x43, 0x61, 0x63, 0x68, 0x65,
-            0x4d, 0x69, 0x73, 0x73, 0x22, 0x2c, 0x72, 0x29, 0x29, 0x7b, 0x74, 0x2e, 0x73, 0x65, 0x6e, 0x64,
-            0x28, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x6e, 0x28,
-            0x65, 0x29, 0x7b, 0x47, 0x74, 0x28, 0x29, 0x3b, 0x65, 0x3d, 0x65, 0x7c, 0x7c, 0x6c, 0x6f, 0x63,
-            0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x6e, 0x61, 0x6d, 0x65, 0x2b, 0x6c,
-            0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x3b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x4a, 0x74, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28,
-            0x74, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x7b, 0x73, 0x77, 0x61, 0x70,
-            0x53, 0x74, 0x79, 0x6c, 0x65, 0x3a, 0x22, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c,
-            0x22, 0x2c, 0x73, 0x77, 0x61, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x3a, 0x30, 0x2c, 0x73, 0x65,
-            0x74, 0x74, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x3a, 0x30, 0x2c, 0x73, 0x63, 0x72, 0x6f,
-            0x6c, 0x6c, 0x3a, 0x74, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x7d, 0x3b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x72, 0x3d, 0x7b, 0x70, 0x61, 0x74, 0x68, 0x3a, 0x65, 0x2c, 0x69, 0x74, 0x65,
-            0x6d, 0x3a, 0x74, 0x2c, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6c, 0x74, 0x3a, 0x5f,
-            0x74, 0x28, 0x29, 0x2c, 0x73, 0x77, 0x61, 0x70, 0x53, 0x70, 0x65, 0x63, 0x3a, 0x6e, 0x7d, 0x3b,
-            0x69, 0x66, 0x28, 0x61, 0x65, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c,
-            0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x43, 0x61, 0x63,
-            0x68, 0x65, 0x48, 0x69, 0x74, 0x22, 0x2c, 0x72, 0x29, 0x29, 0x7b, 0x7a, 0x65, 0x28, 0x72, 0x2e,
-            0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6c, 0x74, 0x2c, 0x74, 0x2e, 0x63, 0x6f, 0x6e,
-            0x74, 0x65, 0x6e, 0x74, 0x2c, 0x6e, 0x2c, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x45,
-            0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x72, 0x2e, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
-            0x45, 0x6c, 0x74, 0x2c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3a, 0x74, 0x2e, 0x74, 0x69, 0x74, 0x6c,
-            0x65, 0x7d, 0x29, 0x3b, 0x24, 0x74, 0x28, 0x72, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x29, 0x3b, 0x61,
-            0x65, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d,
-            0x78, 0x3a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65,
-            0x22, 0x2c, 0x72, 0x29, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x69, 0x66, 0x28, 0x51, 0x2e,
-            0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4f, 0x6e,
-            0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x29, 0x7b, 0x51, 0x2e, 0x6c,
-            0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x74,
-            0x72, 0x75, 0x65, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x51, 0x74, 0x28, 0x65, 0x29, 0x7d,
-            0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6e, 0x28, 0x65, 0x29,
-            0x7b, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x3d, 0x77, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d,
-            0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74,
-            0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x74, 0x3d, 0x5b, 0x65, 0x5d, 0x7d, 0x69, 0x65,
-            0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x74, 0x2e, 0x72,
-            0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3d, 0x28, 0x74, 0x2e, 0x72,
-            0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x7c, 0x7c, 0x30, 0x29, 0x2b,
-            0x31, 0x3b, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x61, 0x64,
-            0x64, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69,
-            0x73, 0x74, 0x2c, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x72, 0x65, 0x71, 0x75,
-            0x65, 0x73, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x29, 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x6e,
-            0x28, 0x65, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x3d, 0x77, 0x65, 0x28, 0x65, 0x2c, 0x22,
-            0x68, 0x78, 0x2d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2d, 0x65, 0x6c, 0x74, 0x22,
-            0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x74, 0x3d,
-            0x5b, 0x5d, 0x7d, 0x69, 0x65, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6f, 0x65, 0x28, 0x65,
-            0x29, 0x3b, 0x74, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74,
-            0x3d, 0x28, 0x74, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74,
-            0x7c, 0x7c, 0x30, 0x29, 0x2b, 0x31, 0x3b, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72,
-            0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22,
-            0x2c, 0x22, 0x22, 0x29, 0x3b, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62,
-            0x75, 0x74, 0x65, 0x28, 0x22, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c,
-            0x65, 0x64, 0x2d, 0x62, 0x79, 0x2d, 0x68, 0x74, 0x6d, 0x78, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x7d,
-            0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x72, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x69, 0x65, 0x28, 0x65,
-            0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6f,
-            0x65, 0x28, 0x65, 0x29, 0x3b, 0x74, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f,
-            0x75, 0x6e, 0x74, 0x3d, 0x28, 0x74, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f,
-            0x75, 0x6e, 0x74, 0x7c, 0x7c, 0x31, 0x29, 0x2d, 0x31, 0x7d, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x65,
-            0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x74, 0x3d, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x2e,
-            0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3d, 0x3d, 0x3d, 0x30,
-            0x29, 0x7b, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65,
-            0x6d, 0x6f, 0x76, 0x65, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73,
-            0x73, 0x4c, 0x69, 0x73, 0x74, 0x2c, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x72,
-            0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x29, 0x7d, 0x7d, 0x29, 0x3b,
-            0x69, 0x65, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29,
-            0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x69,
-            0x66, 0x28, 0x74, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74,
-            0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74,
-            0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
-            0x64, 0x22, 0x29, 0x3b, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74, 0x74, 0x72,
-            0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x64, 0x69, 0x73, 0x61,
-            0x62, 0x6c, 0x65, 0x64, 0x2d, 0x62, 0x79, 0x2d, 0x68, 0x74, 0x6d, 0x78, 0x22, 0x29, 0x7d, 0x7d,
-            0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x28, 0x74, 0x2c,
-            0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65,
-            0x3c, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x74, 0x5b, 0x65, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x72,
-            0x2e, 0x69, 0x73, 0x53, 0x61, 0x6d, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x6e, 0x29, 0x29, 0x7b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x7d, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x73, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74,
-            0x3d, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22,
-            0x22, 0x7c, 0x7c, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7c,
-            0x7c, 0x74, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x7c, 0x7c, 0x67, 0x28, 0x74,
-            0x2c, 0x22, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62,
-            0x6c, 0x65, 0x64, 0x5d, 0x22, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66,
-            0x61, 0x6c, 0x73, 0x65, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d,
-            0x3d, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x7c, 0x7c, 0x74, 0x2e, 0x74, 0x79, 0x70,
-            0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x7c, 0x7c, 0x74, 0x2e,
-            0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65,
-            0x22, 0x7c, 0x7c, 0x74, 0x2e, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22,
-            0x72, 0x65, 0x73, 0x65, 0x74, 0x22, 0x7c, 0x7c, 0x74, 0x2e, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d,
-            0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x74, 0x79,
-            0x70, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x22, 0x7c,
-            0x7c, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x72, 0x61, 0x64, 0x69, 0x6f,
-            0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x63, 0x68, 0x65, 0x63,
-            0x6b, 0x65, 0x64, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x2c,
-            0x6e, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x21, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x26, 0x26, 0x65,
-            0x21, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x41, 0x72, 0x72, 0x61, 0x79,
-            0x2e, 0x69, 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x65, 0x29, 0x29, 0x7b, 0x65, 0x2e, 0x66,
-            0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x65, 0x29, 0x7b, 0x6e, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x74, 0x2c, 0x65, 0x29,
-            0x7d, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x6e, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64,
-            0x28, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x63, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x21,
-            0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x26, 0x26, 0x6e, 0x21, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b,
-            0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x72, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x74,
-            0x29, 0x3b, 0x69, 0x66, 0x28, 0x41, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x69, 0x73, 0x41, 0x72, 0x72,
-            0x61, 0x79, 0x28, 0x6e, 0x29, 0x29, 0x7b, 0x65, 0x3d, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65,
-            0x72, 0x28, 0x65, 0x3d, 0x3e, 0x6e, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x65,
-            0x29, 0x3c, 0x30, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x65, 0x3d, 0x65, 0x2e, 0x66, 0x69,
-            0x6c, 0x74, 0x65, 0x72, 0x28, 0x65, 0x3d, 0x3e, 0x65, 0x21, 0x3d, 0x3d, 0x6e, 0x29, 0x7d, 0x72,
-            0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x74, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x65, 0x2c,
-            0x65, 0x3d, 0x3e, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x74, 0x2c, 0x65, 0x29,
-            0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x6e, 0x28, 0x65,
-            0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f,
-            0x66, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x45, 0x6c, 0x65, 0x6d,
-            0x65, 0x6e, 0x74, 0x26, 0x26, 0x65, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x29,
-            0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x28, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72,
-            0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x22, 0x6f, 0x70,
-            0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x22, 0x29, 0x29, 0x2e,
-            0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x7d, 0x29,
-            0x7d, 0x69, 0x66, 0x28, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66,
-            0x20, 0x48, 0x54, 0x4d, 0x4c, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
-            0x74, 0x26, 0x26, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x4d, 0x28, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x29, 0x7d, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x2c, 0x65,
-            0x2c, 0x6f, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7c, 0x7c,
-            0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d,
-            0x65, 0x6c, 0x73, 0x65, 0x7b, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x65, 0x29, 0x7d, 0x69,
-            0x66, 0x28, 0x73, 0x6e, 0x28, 0x65, 0x29, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69,
-            0x3d, 0x65, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x29, 0x3b, 0x6c, 0x6e,
-            0x28, 0x69, 0x2c, 0x75, 0x6e, 0x28, 0x65, 0x29, 0x2c, 0x6e, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6f,
-            0x29, 0x7b, 0x61, 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x29, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x65, 0x20,
-            0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x46,
-            0x6f, 0x72, 0x6d, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x29, 0x7b, 0x69, 0x65, 0x28, 0x65,
-            0x2e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78,
-            0x4f, 0x66, 0x28, 0x65, 0x29, 0x3e, 0x3d, 0x30, 0x29, 0x7b, 0x63, 0x6e, 0x28, 0x65, 0x2e, 0x6e,
-            0x61, 0x6d, 0x65, 0x2c, 0x75, 0x6e, 0x28, 0x65, 0x29, 0x2c, 0x6e, 0x29, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x7b, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x65, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x6f,
-            0x29, 0x7b, 0x61, 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x29, 0x7d, 0x7d, 0x29, 0x3b, 0x6e, 0x65, 0x77,
-            0x20, 0x46, 0x6f, 0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x28, 0x65, 0x29, 0x2e, 0x66, 0x6f, 0x72,
-            0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c,
-            0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
-            0x6f, 0x66, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x26, 0x26, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d,
-            0x3d, 0x3d, 0x22, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x6c, 0x6e, 0x28,
-            0x74, 0x2c, 0x65, 0x2c, 0x6e, 0x29, 0x7d, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x6e, 0x3d, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x77, 0x69, 0x6c, 0x6c, 0x56, 0x61,
-            0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x6e, 0x2c, 0x22, 0x68, 0x74,
-            0x6d, 0x78, 0x3a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x76, 0x61,
-            0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x6e, 0x2e, 0x63,
-            0x68, 0x65, 0x63, 0x6b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x69, 0x74, 0x79, 0x28, 0x29, 0x29, 0x7b,
-            0x69, 0x66, 0x28, 0x61, 0x65, 0x28, 0x6e, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x76, 0x61,
-            0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22,
-            0x2c, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x3a, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x69,
-            0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2c, 0x76, 0x61,
-            0x6c, 0x69, 0x64, 0x69, 0x74, 0x79, 0x3a, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x69, 0x74,
-            0x79, 0x7d, 0x29, 0x26, 0x26, 0x21, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x26, 0x26,
-            0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x56,
-            0x61, 0x6c, 0x69, 0x64, 0x69, 0x74, 0x79, 0x4f, 0x66, 0x46, 0x6f, 0x72, 0x6d, 0x73, 0x29, 0x7b,
-            0x6e, 0x2e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x69, 0x74, 0x79,
-            0x28, 0x29, 0x7d, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x7b, 0x65, 0x6c, 0x74, 0x3a, 0x6e,
-            0x2c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x3a, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64,
-            0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2c, 0x76, 0x61, 0x6c,
-            0x69, 0x64, 0x69, 0x74, 0x79, 0x3a, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x69, 0x74, 0x79,
-            0x7d, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x6e,
-            0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x74, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x28, 0x29, 0x29, 0x7b, 0x6e,
-            0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x74, 0x29, 0x7d, 0x65, 0x2e, 0x66, 0x6f, 0x72,
-            0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c,
-            0x74, 0x29, 0x7b, 0x6e, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x74, 0x2c, 0x65, 0x29,
-            0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x6e, 0x3d, 0x5b, 0x5d, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d,
-            0x6e, 0x65, 0x77, 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x3b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x6f, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x44, 0x61, 0x74,
-            0x61, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x5b, 0x5d, 0x3b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x73, 0x3d, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x73, 0x2e,
-            0x6c, 0x61, 0x73, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x65,
-            0x64, 0x26, 0x26, 0x21, 0x73, 0x65, 0x28, 0x73, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x42, 0x75, 0x74,
-            0x74, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x29, 0x29, 0x7b, 0x73, 0x2e, 0x6c,
-            0x61, 0x73, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64,
-            0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x6c, 0x65, 0x74, 0x20, 0x6c, 0x3d, 0x65, 0x20, 0x69, 0x6e,
-            0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x46, 0x6f, 0x72,
-            0x6d, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x26, 0x26, 0x65, 0x2e, 0x6e, 0x6f, 0x56, 0x61,
-            0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x21, 0x3d, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7c, 0x7c, 0x61,
-            0x28, 0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x22,
-            0x29, 0x3d, 0x3d, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x3b, 0x69, 0x66, 0x28, 0x73, 0x2e,
-            0x6c, 0x61, 0x73, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x65,
-            0x64, 0x29, 0x7b, 0x6c, 0x3d, 0x6c, 0x26, 0x26, 0x73, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x42, 0x75,
-            0x74, 0x74, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x2e, 0x66, 0x6f, 0x72, 0x6d,
-            0x4e, 0x6f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x21, 0x3d, 0x3d, 0x74, 0x72, 0x75,
-            0x65, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x21, 0x3d, 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, 0x29, 0x7b,
-            0x66, 0x6e, 0x28, 0x6e, 0x2c, 0x6f, 0x2c, 0x69, 0x2c, 0x4c, 0x74, 0x28, 0x65, 0x29, 0x2c, 0x6c,
-            0x29, 0x7d, 0x66, 0x6e, 0x28, 0x6e, 0x2c, 0x72, 0x2c, 0x69, 0x2c, 0x65, 0x2c, 0x6c, 0x29, 0x3b,
-            0x69, 0x66, 0x28, 0x73, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x43,
-            0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x7c, 0x7c, 0x65, 0x2e, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d,
-            0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x42, 0x55, 0x54, 0x54, 0x4f, 0x4e, 0x22, 0x7c, 0x7c, 0x65, 0x2e,
-            0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x49, 0x4e, 0x50, 0x55, 0x54,
-            0x22, 0x26, 0x26, 0x65, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x29, 0x3d,
-            0x3d, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x75, 0x3d, 0x73, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e,
-            0x43, 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x7c, 0x7c, 0x65, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x66, 0x3d, 0x65, 0x65, 0x28, 0x75, 0x2c, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x29, 0x3b,
-            0x6c, 0x6e, 0x28, 0x66, 0x2c, 0x75, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x6f, 0x29, 0x7d,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x3d, 0x77, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x78,
-            0x2d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x22, 0x29, 0x3b, 0x69, 0x65, 0x28, 0x63, 0x2c,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x66, 0x6e, 0x28, 0x6e,
-            0x2c, 0x72, 0x2c, 0x69, 0x2c, 0x63, 0x65, 0x28, 0x65, 0x29, 0x2c, 0x6c, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x21, 0x68, 0x28, 0x65, 0x2c, 0x22, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x29, 0x29, 0x7b, 0x69,
-            0x65, 0x28, 0x70, 0x28, 0x65, 0x29, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65,
-            0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x6f, 0x74, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x66, 0x6e, 0x28, 0x6e, 0x2c, 0x72, 0x2c, 0x69,
-            0x2c, 0x65, 0x2c, 0x6c, 0x29, 0x7d, 0x29, 0x7d, 0x7d, 0x29, 0x3b, 0x68, 0x6e, 0x28, 0x72, 0x2c,
-            0x6f, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73,
-            0x3a, 0x69, 0x2c, 0x66, 0x6f, 0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x3a, 0x72, 0x2c, 0x76, 0x61,
-            0x6c, 0x75, 0x65, 0x73, 0x3a, 0x6b, 0x6e, 0x28, 0x72, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x69,
-            0x66, 0x28, 0x65, 0x21, 0x3d, 0x3d, 0x22, 0x22, 0x29, 0x7b, 0x65, 0x2b, 0x3d, 0x22, 0x26, 0x22,
-            0x7d, 0x69, 0x66, 0x28, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x6e, 0x29, 0x3d, 0x3d, 0x3d,
-            0x22, 0x5b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5d,
-            0x22, 0x29, 0x7b, 0x6e, 0x3d, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
-            0x69, 0x66, 0x79, 0x28, 0x6e, 0x29, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x65,
-            0x6e, 0x63, 0x6f, 0x64, 0x65, 0x55, 0x52, 0x49, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
-            0x74, 0x28, 0x6e, 0x29, 0x3b, 0x65, 0x2b, 0x3d, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x55, 0x52,
-            0x49, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x28, 0x74, 0x29, 0x2b, 0x22, 0x3d,
-            0x22, 0x2b, 0x72, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x65, 0x3d, 0x44, 0x6e,
-            0x28, 0x65, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x3d, 0x22, 0x22, 0x3b, 0x65, 0x2e, 0x66,
-            0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x65, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x3d, 0x70, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29,
-            0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x7b, 0x22, 0x48, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75,
-            0x65, 0x73, 0x74, 0x22, 0x3a, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x2c, 0x22, 0x48, 0x58, 0x2d,
-            0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x22, 0x3a, 0x65, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x69,
-            0x64, 0x22, 0x29, 0x2c, 0x22, 0x48, 0x58, 0x2d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2d,
-            0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x65, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x6e, 0x61, 0x6d, 0x65,
-            0x22, 0x29, 0x2c, 0x22, 0x48, 0x58, 0x2d, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x3a, 0x61,
-            0x28, 0x74, 0x2c, 0x22, 0x69, 0x64, 0x22, 0x29, 0x2c, 0x22, 0x48, 0x58, 0x2d, 0x43, 0x75, 0x72,
-            0x72, 0x65, 0x6e, 0x74, 0x2d, 0x55, 0x52, 0x4c, 0x22, 0x3a, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69,
-            0x6f, 0x6e, 0x2e, 0x68, 0x72, 0x65, 0x66, 0x7d, 0x3b, 0x43, 0x6e, 0x28, 0x65, 0x2c, 0x22, 0x68,
-            0x78, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x22, 0x2c, 0x66, 0x61, 0x6c, 0x73, 0x65,
-            0x2c, 0x72, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x21, 0x3d, 0x3d, 0x75, 0x6e, 0x64, 0x65, 0x66,
-            0x69, 0x6e, 0x65, 0x64, 0x29, 0x7b, 0x72, 0x5b, 0x22, 0x48, 0x58, 0x2d, 0x50, 0x72, 0x6f, 0x6d,
-            0x70, 0x74, 0x22, 0x5d, 0x3d, 0x6e, 0x7d, 0x69, 0x66, 0x28, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x2e,
-            0x62, 0x6f, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x29, 0x7b, 0x72, 0x5b, 0x22, 0x48, 0x58, 0x2d, 0x42,
-            0x6f, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x22, 0x5d, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x7d,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x79, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x74, 0x3d, 0x6e, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x70, 0x61, 0x72, 0x61, 0x6d,
-            0x73, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x3d, 0x3d,
-            0x3d, 0x22, 0x6e, 0x6f, 0x6e, 0x65, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x6e, 0x65, 0x77, 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x20, 0x69, 0x66, 0x28, 0x74, 0x3d, 0x3d, 0x3d, 0x22, 0x2a, 0x22, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x74,
-            0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x6e, 0x6f, 0x74, 0x20, 0x22, 0x29,
-            0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x69, 0x65, 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65,
-            0x28, 0x34, 0x29, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, 0x2c, 0x22, 0x29, 0x2c, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x65, 0x3d, 0x65, 0x2e, 0x74,
-            0x72, 0x69, 0x6d, 0x28, 0x29, 0x3b, 0x6e, 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x65,
-            0x29, 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x46, 0x6f,
-            0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x3b, 0x69, 0x65, 0x28, 0x74, 0x2e, 0x73, 0x70, 0x6c, 0x69,
-            0x74, 0x28, 0x22, 0x2c, 0x22, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x74, 0x29, 0x7b, 0x74, 0x3d, 0x74, 0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x6e, 0x2e, 0x68, 0x61, 0x73, 0x28, 0x74, 0x29, 0x29, 0x7b, 0x6e, 0x2e, 0x67, 0x65, 0x74,
-            0x41, 0x6c, 0x6c, 0x28, 0x74, 0x29, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x2e, 0x61, 0x70, 0x70,
-            0x65, 0x6e, 0x64, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x29, 0x7d, 0x7d, 0x29, 0x3b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-            0x78, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, 0x21, 0x65, 0x65,
-            0x28, 0x65, 0x2c, 0x22, 0x68, 0x72, 0x65, 0x66, 0x22, 0x29, 0x26, 0x26, 0x65, 0x65, 0x28, 0x65,
-            0x2c, 0x22, 0x68, 0x72, 0x65, 0x66, 0x22, 0x29, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66,
-            0x28, 0x22, 0x23, 0x22, 0x29, 0x3e, 0x3d, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x62, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x6e, 0x3d, 0x74, 0x7c, 0x7c, 0x6e, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x73, 0x77,
-            0x61, 0x70, 0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x7b, 0x73, 0x77,
-            0x61, 0x70, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x3a, 0x6f, 0x65, 0x28, 0x65, 0x29, 0x2e, 0x62, 0x6f,
-            0x6f, 0x73, 0x74, 0x65, 0x64, 0x3f, 0x22, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c,
-            0x22, 0x3a, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x64, 0x65, 0x66, 0x61, 0x75,
-            0x6c, 0x74, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x2c, 0x73, 0x77, 0x61, 0x70,
-            0x44, 0x65, 0x6c, 0x61, 0x79, 0x3a, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x64,
-            0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x77, 0x61, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x2c,
-            0x73, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x3a, 0x51, 0x2e, 0x63, 0x6f,
-            0x6e, 0x66, 0x69, 0x67, 0x2e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x65, 0x74, 0x74,
-            0x6c, 0x65, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x7d, 0x3b, 0x69, 0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f,
-            0x6e, 0x66, 0x69, 0x67, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x6f, 0x56,
-            0x69, 0x65, 0x77, 0x4f, 0x6e, 0x42, 0x6f, 0x6f, 0x73, 0x74, 0x26, 0x26, 0x6f, 0x65, 0x28, 0x65,
-            0x29, 0x2e, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x26, 0x26, 0x21, 0x78, 0x6e, 0x28, 0x65,
-            0x29, 0x29, 0x7b, 0x72, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x3d, 0x22, 0x74, 0x6f, 0x70, 0x22, 0x7d,
-            0x69, 0x66, 0x28, 0x6e, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x73, 0x3d, 0x42, 0x28,
-            0x6e, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30,
-            0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65, 0x3c,
-            0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x6c, 0x3d, 0x73, 0x5b, 0x65, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x6c, 0x2e,
-            0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x73, 0x77, 0x61, 0x70, 0x3a, 0x22, 0x29,
-            0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x72, 0x2e, 0x73, 0x77, 0x61, 0x70, 0x44, 0x65, 0x6c, 0x61,
-            0x79, 0x3d, 0x64, 0x28, 0x6c, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x35, 0x29, 0x29, 0x7d,
-            0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x6c, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f,
-            0x66, 0x28, 0x22, 0x73, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x3a, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x30,
-            0x29, 0x7b, 0x72, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x3d,
-            0x64, 0x28, 0x6c, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x37, 0x29, 0x29, 0x7d, 0x65, 0x6c,
-            0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x6c, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28,
-            0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x22, 0x29, 0x3d, 0x3d,
-            0x3d, 0x30, 0x29, 0x7b, 0x72, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
-            0x3d, 0x6c, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x31, 0x31, 0x29, 0x3d, 0x3d, 0x3d, 0x22,
-            0x74, 0x72, 0x75, 0x65, 0x22, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x6c, 0x2e,
-            0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x54,
-            0x69, 0x74, 0x6c, 0x65, 0x3a, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x72, 0x2e, 0x69,
-            0x67, 0x6e, 0x6f, 0x72, 0x65, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x6c, 0x2e, 0x73, 0x6c, 0x69,
-            0x63, 0x65, 0x28, 0x31, 0x32, 0x29, 0x3d, 0x3d, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x7d,
-            0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x6c, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f,
-            0x66, 0x28, 0x22, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x30,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x3d, 0x6c, 0x2e, 0x73, 0x6c, 0x69, 0x63,
-            0x65, 0x28, 0x37, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x63, 0x2e, 0x73, 0x70, 0x6c,
-            0x69, 0x74, 0x28, 0x22, 0x3a, 0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x75, 0x3d,
-            0x6f, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x6f, 0x2e,
-            0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x3f, 0x6f, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28,
-            0x22, 0x3a, 0x22, 0x29, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x72, 0x2e, 0x73, 0x63, 0x72, 0x6f,
-            0x6c, 0x6c, 0x3d, 0x75, 0x3b, 0x72, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x61, 0x72,
-            0x67, 0x65, 0x74, 0x3d, 0x69, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x6c, 0x2e,
-            0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x73, 0x68, 0x6f, 0x77, 0x3a, 0x22, 0x29,
-            0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x66, 0x3d, 0x6c, 0x2e,
-            0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x35, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x66,
-            0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, 0x3a, 0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x61, 0x3d, 0x6f, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20,
-            0x69, 0x3d, 0x6f, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x3f, 0x6f, 0x2e, 0x6a,
-            0x6f, 0x69, 0x6e, 0x28, 0x22, 0x3a, 0x22, 0x29, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x72, 0x2e,
-            0x73, 0x68, 0x6f, 0x77, 0x3d, 0x61, 0x3b, 0x72, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, 0x72,
-            0x67, 0x65, 0x74, 0x3d, 0x69, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x6c, 0x2e,
-            0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2d, 0x73,
-            0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x68, 0x3d, 0x6c, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x22, 0x66,
-            0x6f, 0x63, 0x75, 0x73, 0x2d, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x22, 0x2e, 0x6c, 0x65,
-            0x6e, 0x67, 0x74, 0x68, 0x29, 0x3b, 0x72, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x53, 0x63, 0x72,
-            0x6f, 0x6c, 0x6c, 0x3d, 0x68, 0x3d, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x7d, 0x65, 0x6c,
-            0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x65, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x72, 0x2e, 0x73, 0x77,
-            0x61, 0x70, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x6c, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x48,
-            0x28, 0x22, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69,
-            0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x68, 0x78, 0x2d, 0x73, 0x77, 0x61, 0x70, 0x3a, 0x20, 0x22,
-            0x2b, 0x6c, 0x29, 0x7d, 0x7d, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x65,
-            0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x22, 0x6d, 0x75, 0x6c,
-            0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61,
-            0x22, 0x7c, 0x7c, 0x68, 0x28, 0x65, 0x2c, 0x22, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x29, 0x26, 0x26,
-            0x65, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x22, 0x29, 0x3d,
-            0x3d, 0x3d, 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x2f, 0x66, 0x6f, 0x72,
-            0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x22, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x77, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x6f,
-            0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x56, 0x74, 0x28, 0x6e, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6f, 0x3d, 0x3d, 0x6e, 0x75, 0x6c,
-            0x6c, 0x29, 0x7b, 0x6f, 0x3d, 0x65, 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x50, 0x61, 0x72,
-            0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x28, 0x74, 0x2c, 0x72, 0x2c, 0x6e, 0x29, 0x7d, 0x7d,
-            0x29, 0x3b, 0x69, 0x66, 0x28, 0x6f, 0x21, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x69, 0x66, 0x28, 0x76,
-            0x6e, 0x28, 0x6e, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x6e, 0x28,
-            0x6e, 0x65, 0x77, 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x2c, 0x44, 0x6e, 0x28,
-            0x72, 0x29, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x67, 0x6e, 0x28, 0x72, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x53, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x74, 0x61,
-            0x73, 0x6b, 0x73, 0x3a, 0x5b, 0x5d, 0x2c, 0x65, 0x6c, 0x74, 0x73, 0x3a, 0x5b, 0x65, 0x5d, 0x7d,
-            0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x6e, 0x28, 0x65, 0x2c, 0x74,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x65, 0x5b, 0x30, 0x5d, 0x3b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x65, 0x5b, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74,
-            0x68, 0x2d, 0x31, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c,
-            0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x69, 0x66, 0x28,
-            0x74, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x7b,
-            0x6f, 0x3d, 0x63, 0x65, 0x28, 0x75, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2e, 0x73, 0x63, 0x72, 0x6f,
-            0x6c, 0x6c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x2e,
-            0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x3d, 0x3d, 0x3d, 0x22, 0x74, 0x6f, 0x70, 0x22, 0x26, 0x26,
-            0x28, 0x6e, 0x7c, 0x7c, 0x6f, 0x29, 0x29, 0x7b, 0x6f, 0x3d, 0x6f, 0x7c, 0x7c, 0x6e, 0x3b, 0x6f,
-            0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x70, 0x3d, 0x30, 0x7d, 0x69, 0x66, 0x28,
-            0x74, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x3d, 0x3d, 0x3d, 0x22, 0x62, 0x6f, 0x74, 0x74,
-            0x6f, 0x6d, 0x22, 0x26, 0x26, 0x28, 0x72, 0x7c, 0x7c, 0x6f, 0x29, 0x29, 0x7b, 0x6f, 0x3d, 0x6f,
-            0x7c, 0x7c, 0x72, 0x3b, 0x6f, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x70, 0x3d,
-            0x6f, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x7d, 0x69,
-            0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c,
-            0x6c, 0x3d, 0x3d, 0x3d, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x29, 0x7b, 0x62, 0x28,
-            0x29, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73,
-            0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x28, 0x30, 0x2c, 0x74, 0x2e, 0x73, 0x63, 0x72, 0x6f,
-            0x6c, 0x6c, 0x29, 0x7d, 0x2c, 0x30, 0x29, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x73, 0x68,
-            0x6f, 0x77, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x69,
-            0x66, 0x28, 0x74, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x7b,
-            0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x74, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, 0x72, 0x67,
-            0x65, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, 0x72, 0x67,
-            0x65, 0x74, 0x3d, 0x3d, 0x3d, 0x22, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 0x29, 0x7b, 0x65,
-            0x3d, 0x22, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x7d, 0x6f, 0x3d, 0x63, 0x65, 0x28, 0x75, 0x65, 0x28,
-            0x6e, 0x2c, 0x65, 0x29, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x3d,
-            0x3d, 0x3d, 0x22, 0x74, 0x6f, 0x70, 0x22, 0x26, 0x26, 0x28, 0x6e, 0x7c, 0x7c, 0x6f, 0x29, 0x29,
-            0x7b, 0x6f, 0x3d, 0x6f, 0x7c, 0x7c, 0x6e, 0x3b, 0x6f, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c,
-            0x49, 0x6e, 0x74, 0x6f, 0x56, 0x69, 0x65, 0x77, 0x28, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3a,
-            0x22, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x2c, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72,
-            0x3a, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c,
-            0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x7d, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x2e,
-            0x73, 0x68, 0x6f, 0x77, 0x3d, 0x3d, 0x3d, 0x22, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x22, 0x26,
-            0x26, 0x28, 0x72, 0x7c, 0x7c, 0x6f, 0x29, 0x29, 0x7b, 0x6f, 0x3d, 0x6f, 0x7c, 0x7c, 0x72, 0x3b,
-            0x6f, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x6f, 0x56, 0x69, 0x65, 0x77,
-            0x28, 0x7b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3a, 0x22, 0x65, 0x6e, 0x64, 0x22, 0x2c, 0x62, 0x65,
-            0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x3a, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
-            0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x7d, 0x29,
-            0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x6e, 0x28, 0x72,
-            0x2c, 0x65, 0x2c, 0x6f, 0x2c, 0x69, 0x2c, 0x73, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x3d, 0x3d,
-            0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x69, 0x3d, 0x7b, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x72, 0x3d,
-            0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x7d,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6c, 0x3d, 0x61, 0x28, 0x72, 0x2c, 0x65, 0x29, 0x3b, 0x69,
-            0x66, 0x28, 0x6c, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x6c, 0x2e, 0x74, 0x72, 0x69,
-            0x6d, 0x28, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x3d, 0x6f, 0x3b, 0x69, 0x66, 0x28, 0x65,
-            0x3d, 0x3d, 0x3d, 0x22, 0x75, 0x6e, 0x73, 0x65, 0x74, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x69, 0x6e, 0x64,
-            0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
-            0x3a, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x65, 0x3d, 0x65, 0x2e, 0x73, 0x6c, 0x69,
-            0x63, 0x65, 0x28, 0x31, 0x31, 0x29, 0x3b, 0x74, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x65, 0x6c,
-            0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28,
-            0x22, 0x6a, 0x73, 0x3a, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x65, 0x3d, 0x65, 0x2e,
-            0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x33, 0x29, 0x3b, 0x74, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d,
-            0x69, 0x66, 0x28, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x7b, 0x22,
-            0x29, 0x21, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x65, 0x3d, 0x22, 0x7b, 0x22, 0x2b, 0x65, 0x2b, 0x22,
-            0x7d, 0x22, 0x7d, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x6e,
-            0x3d, 0x4f, 0x6e, 0x28, 0x72, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29,
-            0x7b, 0x69, 0x66, 0x28, 0x73, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x46, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x22, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x22,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x22, 0x2b, 0x65, 0x2b, 0x22, 0x29, 0x22, 0x29,
-            0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x73, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x22, 0x2b, 0x65, 0x2b, 0x22, 0x29, 0x22,
-            0x29, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x29, 0x7d, 0x7d, 0x2c, 0x7b, 0x7d, 0x29, 0x7d,
-            0x65, 0x6c, 0x73, 0x65, 0x7b, 0x6e, 0x3d, 0x76, 0x28, 0x65, 0x29, 0x7d, 0x66, 0x6f, 0x72, 0x28,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x29, 0x7b, 0x69, 0x66,
-            0x28, 0x6e, 0x2e, 0x68, 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74,
-            0x79, 0x28, 0x63, 0x29, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x5b, 0x63, 0x5d, 0x3d, 0x3d, 0x6e,
-            0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x69, 0x5b, 0x63, 0x5d, 0x3d, 0x6e, 0x5b, 0x63, 0x5d, 0x7d, 0x7d,
-            0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x43, 0x6e, 0x28, 0x63, 0x65, 0x28, 0x75,
-            0x28, 0x72, 0x29, 0x29, 0x2c, 0x65, 0x2c, 0x6f, 0x2c, 0x69, 0x2c, 0x73, 0x29, 0x7d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29,
-            0x7b, 0x69, 0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x61, 0x6c, 0x6c,
-            0x6f, 0x77, 0x45, 0x76, 0x61, 0x6c, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74,
-            0x28, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x66, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74,
-            0x6d, 0x78, 0x3a, 0x65, 0x76, 0x61, 0x6c, 0x44, 0x69, 0x73, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65,
-            0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x6e, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x48, 0x6e, 0x28, 0x65,
-            0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x43, 0x6e, 0x28,
-            0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x76, 0x61, 0x72, 0x73, 0x22, 0x2c, 0x74, 0x72, 0x75, 0x65,
-            0x2c, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54,
-            0x6e, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x43, 0x6e, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x76, 0x61, 0x6c, 0x73, 0x22, 0x2c, 0x66,
-            0x61, 0x6c, 0x73, 0x65, 0x2c, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x52, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x6c, 0x65, 0x28, 0x48, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x2c, 0x54, 0x6e, 0x28,
-            0x65, 0x2c, 0x74, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x71,
-            0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x72, 0x21, 0x3d, 0x3d,
-            0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x74, 0x2e, 0x73, 0x65, 0x74, 0x52,
-            0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x6e, 0x2c, 0x72,
-            0x29, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x7b, 0x74, 0x2e, 0x73, 0x65, 0x74,
-            0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x6e, 0x2c,
-            0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x55, 0x52, 0x49, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65,
-            0x6e, 0x74, 0x28, 0x72, 0x29, 0x29, 0x3b, 0x74, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75,
-            0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x6e, 0x2b, 0x22, 0x2d, 0x55, 0x52,
-            0x49, 0x2d, 0x41, 0x75, 0x74, 0x6f, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x22, 0x2c, 0x22,
-            0x74, 0x72, 0x75, 0x65, 0x22, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x41, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x72, 0x65, 0x73,
-            0x70, 0x6f, 0x6e, 0x73, 0x65, 0x55, 0x52, 0x4c, 0x29, 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x52, 0x4c, 0x28, 0x74, 0x2e,
-            0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x55, 0x52, 0x4c, 0x29, 0x3b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x6e, 0x61, 0x6d, 0x65, 0x2b, 0x65,
-            0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29,
-            0x7b, 0x66, 0x65, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68,
-            0x74, 0x6d, 0x78, 0x3a, 0x62, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x55,
-            0x72, 0x6c, 0x22, 0x2c, 0x7b, 0x75, 0x72, 0x6c, 0x3a, 0x74, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f,
-            0x6e, 0x73, 0x65, 0x55, 0x52, 0x4c, 0x7d, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x20, 0x54, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x6c,
-            0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73,
-            0x28, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4c, 0x6e, 0x28,
-            0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x7b, 0x74, 0x3d, 0x74, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77,
-            0x65, 0x72, 0x43, 0x61, 0x73, 0x65, 0x28, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x72, 0x29, 0x7b, 0x69,
-            0x66, 0x28, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x45,
-            0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x7c, 0x7c, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x72,
-            0x3d, 0x3d, 0x3d, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x68, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c,
-            0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x7b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72,
-            0x72, 0x69, 0x64, 0x65, 0x3a, 0x77, 0x28, 0x72, 0x29, 0x7c, 0x7c, 0x76, 0x65, 0x2c, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x3a, 0x74, 0x72, 0x75, 0x65,
-            0x7d, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x77, 0x28,
-            0x72, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x72, 0x2e, 0x74,
-            0x61, 0x72, 0x67, 0x65, 0x74, 0x26, 0x26, 0x21, 0x65, 0x7c, 0x7c, 0x72, 0x2e, 0x73, 0x6f, 0x75,
-            0x72, 0x63, 0x65, 0x26, 0x26, 0x21, 0x65, 0x26, 0x26, 0x21, 0x77, 0x28, 0x72, 0x2e, 0x73, 0x6f,
-            0x75, 0x72, 0x63, 0x65, 0x29, 0x29, 0x7b, 0x65, 0x3d, 0x76, 0x65, 0x7d, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x68, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x77, 0x28, 0x72, 0x2e, 0x73, 0x6f,
-            0x75, 0x72, 0x63, 0x65, 0x29, 0x2c, 0x72, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2c, 0x7b, 0x68,
-            0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x3a, 0x72, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72,
-            0x2c, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3a, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65,
-            0x72, 0x73, 0x2c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x3a, 0x72, 0x2e, 0x76, 0x61, 0x6c, 0x75,
-            0x65, 0x73, 0x2c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64,
-            0x65, 0x3a, 0x65, 0x2c, 0x73, 0x77, 0x61, 0x70, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65,
-            0x3a, 0x72, 0x2e, 0x73, 0x77, 0x61, 0x70, 0x2c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3a, 0x72,
-            0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x2c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x50, 0x72,
-            0x6f, 0x6d, 0x69, 0x73, 0x65, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x3a,
-            0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x2c, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x3a, 0x72,
-            0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4f,
-            0x4f, 0x42, 0x3a, 0x72, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4f, 0x4f, 0x42, 0x7d, 0x29,
-            0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x65,
-            0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x7b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x3a, 0x74, 0x72,
-            0x75, 0x65, 0x7d, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e,
-            0x6e, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x5b, 0x5d, 0x3b,
-            0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28,
-            0x65, 0x29, 0x3b, 0x65, 0x3d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x6c, 0x65,
-            0x6d, 0x65, 0x6e, 0x74, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29,
-            0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x52, 0x4c,
-            0x28, 0x74, 0x2c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-            0x6f, 0x63, 0x6f, 0x6c, 0x21, 0x3d, 0x3d, 0x22, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3a, 0x22, 0x3f,
-            0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x68, 0x72, 0x65, 0x66, 0x3a, 0x77, 0x69,
-            0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x29, 0x3b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x6f, 0x3d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72,
-            0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x21, 0x3d, 0x3d, 0x22, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3a,
-            0x22, 0x3f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69,
-            0x6e, 0x3a, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x3b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x6f, 0x3d, 0x3d, 0x3d, 0x72, 0x2e, 0x6f, 0x72,
-            0x69, 0x67, 0x69, 0x6e, 0x3b, 0x69, 0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-            0x2e, 0x73, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x4f, 0x6e, 0x6c,
-            0x79, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x69, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61,
-            0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
-            0x74, 0x65, 0x55, 0x72, 0x6c, 0x22, 0x2c, 0x6c, 0x65, 0x28, 0x7b, 0x75, 0x72, 0x6c, 0x3a, 0x72,
-            0x2c, 0x73, 0x61, 0x6d, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x69, 0x7d, 0x2c, 0x6e, 0x29, 0x29,
-            0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x6e, 0x28, 0x65, 0x29, 0x7b,
-            0x69, 0x66, 0x28, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20,
-            0x46, 0x6f, 0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x65, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x46, 0x6f,
-            0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x68, 0x61,
-            0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6e, 0x29, 0x29,
-            0x7b, 0x69, 0x66, 0x28, 0x65, 0x5b, 0x6e, 0x5d, 0x26, 0x26, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66,
-            0x20, 0x65, 0x5b, 0x6e, 0x5d, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x3d, 0x3d, 0x3d,
-            0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x7b, 0x65, 0x5b, 0x6e, 0x5d,
-            0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x28, 0x65, 0x29, 0x7b, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x6e, 0x2c,
-            0x65, 0x29, 0x7d, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x74, 0x79, 0x70,
-            0x65, 0x6f, 0x66, 0x20, 0x65, 0x5b, 0x6e, 0x5d, 0x3d, 0x3d, 0x3d, 0x22, 0x6f, 0x62, 0x6a, 0x65,
-            0x63, 0x74, 0x22, 0x26, 0x26, 0x21, 0x28, 0x65, 0x5b, 0x6e, 0x5d, 0x69, 0x6e, 0x73, 0x74, 0x61,
-            0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x42, 0x6c, 0x6f, 0x62, 0x29, 0x29, 0x7b, 0x74, 0x2e, 0x61,
-            0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x6e, 0x2c, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72,
-            0x69, 0x6e, 0x67, 0x69, 0x66, 0x79, 0x28, 0x65, 0x5b, 0x6e, 0x5d, 0x29, 0x29, 0x7d, 0x65, 0x6c,
-            0x73, 0x65, 0x7b, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x6e, 0x2c, 0x65, 0x5b,
-            0x6e, 0x5d, 0x29, 0x7d, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x6e, 0x28, 0x72, 0x2c, 0x6f, 0x2c, 0x65,
-            0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x50, 0x72, 0x6f,
-            0x78, 0x79, 0x28, 0x65, 0x2c, 0x7b, 0x67, 0x65, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f,
-            0x66, 0x20, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x29, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x5b, 0x65, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x3d,
-            0x3d, 0x3d, 0x22, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x3d,
-            0x3d, 0x3d, 0x22, 0x70, 0x75, 0x73, 0x68, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x74, 0x2e, 0x70,
-            0x75, 0x73, 0x68, 0x28, 0x65, 0x29, 0x3b, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28,
-            0x6f, 0x2c, 0x65, 0x29, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20,
-            0x74, 0x5b, 0x65, 0x5d, 0x3d, 0x3d, 0x3d, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x5b, 0x65, 0x5d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28,
-            0x74, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, 0x72, 0x2e, 0x64,
-            0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, 0x6f, 0x29, 0x3b, 0x74, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61,
-            0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72,
-            0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x6f, 0x2c, 0x65, 0x29, 0x7d, 0x29, 0x7d, 0x7d,
-            0x69, 0x66, 0x28, 0x74, 0x5b, 0x65, 0x5d, 0x26, 0x26, 0x74, 0x5b, 0x65, 0x5d, 0x2e, 0x6c, 0x65,
-            0x6e, 0x67, 0x74, 0x68, 0x3d, 0x3d, 0x3d, 0x31, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x74, 0x5b, 0x65, 0x5d, 0x5b, 0x30, 0x5d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x5b, 0x65, 0x5d, 0x7d, 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x3a,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b,
-            0x65, 0x5b, 0x74, 0x5d, 0x3d, 0x6e, 0x3b, 0x72, 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28,
-            0x6f, 0x29, 0x3b, 0x65, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e,
-            0x64, 0x28, 0x6f, 0x2c, 0x65, 0x29, 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x74, 0x72, 0x75, 0x65, 0x7d, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x6b, 0x6e, 0x28, 0x6f, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65,
-            0x77, 0x20, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x28, 0x6f, 0x2c, 0x7b, 0x67, 0x65, 0x74, 0x3a, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x3d, 0x3d, 0x3d, 0x22, 0x73, 0x79, 0x6d, 0x62,
-            0x6f, 0x6c, 0x22, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x3d, 0x52, 0x65, 0x66,
-            0x6c, 0x65, 0x63, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x3b, 0x69, 0x66,
-            0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x72, 0x3d, 0x3d, 0x3d, 0x22, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x6f, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d,
-            0x65, 0x6e, 0x74, 0x73, 0x29, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x72, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x3d, 0x3d, 0x3d, 0x22, 0x74, 0x6f,
-            0x4a, 0x53, 0x4f, 0x4e, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x29, 0x3d,
-            0x3e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x45, 0x6e, 0x74, 0x72,
-            0x69, 0x65, 0x73, 0x28, 0x6f, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x65,
-            0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x65, 0x5b, 0x74, 0x5d,
-            0x3d, 0x3d, 0x3d, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x7b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29,
-            0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x5b, 0x74, 0x5d, 0x2e, 0x61, 0x70, 0x70,
-            0x6c, 0x79, 0x28, 0x6f, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x7d,
-            0x7d, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x6f, 0x2e, 0x67, 0x65, 0x74, 0x41,
-            0x6c, 0x6c, 0x28, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74,
-            0x68, 0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x6e,
-            0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28,
-            0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3d, 0x3d, 0x3d, 0x31, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x5b, 0x30, 0x5d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x50, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7d,
-            0x7d, 0x2c, 0x73, 0x65, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74,
-            0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20,
-            0x6e, 0x21, 0x3d, 0x3d, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x74, 0x2e, 0x64, 0x65, 0x6c,
-            0x65, 0x74, 0x65, 0x28, 0x6e, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x26, 0x26, 0x74, 0x79, 0x70,
-            0x65, 0x6f, 0x66, 0x20, 0x65, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x3d, 0x3d, 0x3d,
-            0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x7b, 0x65, 0x2e, 0x66, 0x6f,
-            0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65,
-            0x29, 0x7b, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7d,
-            0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66,
-            0x20, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x26, 0x26, 0x21,
-            0x28, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x42, 0x6c,
-            0x6f, 0x62, 0x29, 0x29, 0x7b, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x6e, 0x2c,
-            0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x66, 0x79, 0x28, 0x65,
-            0x29, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64,
-            0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75,
-            0x65, 0x7d, 0x2c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74,
-            0x79, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b,
-            0x69, 0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x3d, 0x3d, 0x3d, 0x22, 0x73,
-            0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x29, 0x7b, 0x65, 0x2e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65,
-            0x28, 0x74, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x7d,
-            0x2c, 0x6f, 0x77, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x52, 0x65, 0x66, 0x6c,
-            0x65, 0x63, 0x74, 0x2e, 0x6f, 0x77, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x28, 0x4f, 0x62, 0x6a, 0x65,
-            0x63, 0x74, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x28, 0x65,
-            0x29, 0x29, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72,
-            0x74, 0x79, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x3a, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
-            0x6e, 0x20, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x4f, 0x77, 0x6e,
-            0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
-            0x6f, 0x72, 0x28, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x45, 0x6e,
-            0x74, 0x72, 0x69, 0x65, 0x73, 0x28, 0x65, 0x29, 0x2c, 0x74, 0x29, 0x7d, 0x7d, 0x29, 0x7d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72,
-            0x2c, 0x6f, 0x2c, 0x69, 0x2c, 0x6b, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x3d, 0x6e, 0x75,
-            0x6c, 0x6c, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x6c, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x69, 0x3d,
-            0x69, 0x21, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3f, 0x69, 0x3a, 0x7b, 0x7d, 0x3b, 0x69, 0x66, 0x28,
-            0x69, 0x2e, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x26,
-            0x26, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x21,
-            0x3d, 0x3d, 0x22, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x29, 0x7b, 0x76,
-            0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65,
-            0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x73,
-            0x3d, 0x65, 0x3b, 0x6c, 0x3d, 0x74, 0x7d, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x3d, 0x6e,
-            0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x72, 0x3d, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79,
-            0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x4d, 0x3d, 0x69, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c,
-            0x65, 0x72, 0x7c, 0x7c, 0x56, 0x6e, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x46, 0x3d, 0x69,
-            0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x7c, 0x7c, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x69, 0x66,
-            0x28, 0x21, 0x73, 0x65, 0x28, 0x72, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x28, 0x73, 0x29, 0x3b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x3d,
-            0x69, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65,
-            0x7c, 0x7c, 0x63, 0x65, 0x28, 0x45, 0x65, 0x28, 0x72, 0x29, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x63,
-            0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7c, 0x7c, 0x63, 0x3d, 0x3d, 0x76, 0x65, 0x29, 0x7b, 0x66,
-            0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
-            0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, 0x7b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x6e,
-            0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x29,
-            0x7d, 0x29, 0x3b, 0x72, 0x65, 0x28, 0x6c, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x65, 0x7d, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x3d, 0x6f, 0x65, 0x28, 0x72, 0x29, 0x3b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x66, 0x3d, 0x75, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x42, 0x75, 0x74, 0x74,
-            0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x3b, 0x69, 0x66, 0x28, 0x66, 0x29, 0x7b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x41, 0x3d, 0x65, 0x65, 0x28, 0x66, 0x2c, 0x22, 0x66, 0x6f,
-            0x72, 0x6d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x41, 0x21,
-            0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x6e, 0x3d, 0x41, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x4c, 0x3d, 0x65, 0x65, 0x28, 0x66, 0x2c, 0x22, 0x66, 0x6f, 0x72, 0x6d, 0x6d, 0x65, 0x74,
-            0x68, 0x6f, 0x64, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x4c, 0x21, 0x3d, 0x6e, 0x75, 0x6c, 0x6c,
-            0x29, 0x7b, 0x69, 0x66, 0x28, 0x64, 0x65, 0x2e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73,
-            0x28, 0x4c, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x43, 0x61, 0x73, 0x65, 0x28, 0x29,
-            0x29, 0x29, 0x7b, 0x74, 0x3d, 0x4c, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65, 0x28, 0x73,
-            0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x7d, 0x7d, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x61, 0x3d, 0x6e, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x63, 0x6f,
-            0x6e, 0x66, 0x69, 0x72, 0x6d, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6b, 0x3d, 0x3d, 0x3d, 0x75,
-            0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x4b, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x2c,
-            0x69, 0x2c, 0x21, 0x21, 0x65, 0x29, 0x7d, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x47, 0x3d,
-            0x7b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x63, 0x2c, 0x65, 0x6c, 0x74, 0x3a, 0x72, 0x2c,
-            0x70, 0x61, 0x74, 0x68, 0x3a, 0x6e, 0x2c, 0x76, 0x65, 0x72, 0x62, 0x3a, 0x74, 0x2c, 0x74, 0x72,
-            0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x3a, 0x6f, 0x2c,
-            0x65, 0x74, 0x63, 0x3a, 0x69, 0x2c, 0x69, 0x73, 0x73, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
-            0x73, 0x74, 0x3a, 0x4b, 0x2c, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x61, 0x7d,
-            0x3b, 0x69, 0x66, 0x28, 0x61, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x63,
-            0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x22, 0x2c, 0x47, 0x29, 0x3d, 0x3d, 0x3d, 0x66, 0x61, 0x6c,
-            0x73, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x28, 0x73, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x65, 0x7d, 0x7d, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x3d, 0x72, 0x3b, 0x6c, 0x65, 0x74, 0x20,
-            0x64, 0x3d, 0x6e, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x73, 0x79, 0x6e, 0x63, 0x22,
-            0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x70, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x6c, 0x65, 0x74,
-            0x20, 0x42, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x64, 0x29, 0x7b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x4e, 0x3d, 0x64, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22,
-            0x3a, 0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x49, 0x3d, 0x4e, 0x5b, 0x30, 0x5d,
-            0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x49, 0x3d, 0x3d, 0x3d, 0x22,
-            0x74, 0x68, 0x69, 0x73, 0x22, 0x29, 0x7b, 0x68, 0x3d, 0x53, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68,
-            0x78, 0x2d, 0x73, 0x79, 0x6e, 0x63, 0x22, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x68, 0x3d,
-            0x63, 0x65, 0x28, 0x75, 0x65, 0x28, 0x72, 0x2c, 0x49, 0x29, 0x29, 0x7d, 0x64, 0x3d, 0x28, 0x4e,
-            0x5b, 0x31, 0x5d, 0x7c, 0x7c, 0x22, 0x64, 0x72, 0x6f, 0x70, 0x22, 0x29, 0x2e, 0x74, 0x72, 0x69,
-            0x6d, 0x28, 0x29, 0x3b, 0x75, 0x3d, 0x6f, 0x65, 0x28, 0x68, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x64,
-            0x3d, 0x3d, 0x3d, 0x22, 0x64, 0x72, 0x6f, 0x70, 0x22, 0x26, 0x26, 0x75, 0x2e, 0x78, 0x68, 0x72,
-            0x26, 0x26, 0x75, 0x2e, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x21, 0x3d, 0x3d,
-            0x74, 0x72, 0x75, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x28, 0x73, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x20, 0x65, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x64, 0x3d, 0x3d,
-            0x3d, 0x22, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x22, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x78,
-            0x68, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x28, 0x73, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x65, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x42, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x7d,
-            0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x64, 0x3d, 0x3d, 0x3d, 0x22, 0x72, 0x65, 0x70,
-            0x6c, 0x61, 0x63, 0x65, 0x22, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x68, 0x2c, 0x22, 0x68, 0x74, 0x6d,
-            0x78, 0x3a, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x22, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69,
-            0x66, 0x28, 0x64, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x71, 0x75, 0x65,
-            0x75, 0x65, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x57, 0x3d, 0x64, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, 0x20, 0x22, 0x29, 0x3b, 0x70,
-            0x3d, 0x28, 0x57, 0x5b, 0x31, 0x5d, 0x7c, 0x7c, 0x22, 0x6c, 0x61, 0x73, 0x74, 0x22, 0x29, 0x2e,
-            0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x78, 0x68, 0x72,
-            0x29, 0x7b, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65,
-            0x29, 0x7b, 0x61, 0x65, 0x28, 0x68, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x61, 0x62, 0x6f,
-            0x72, 0x74, 0x22, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x69, 0x66, 0x28, 0x70, 0x3d, 0x3d,
-            0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6f, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x44, 0x3d, 0x6f, 0x65, 0x28, 0x6f, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x44, 0x26, 0x26,
-            0x44, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x26, 0x26, 0x44,
-            0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x71, 0x75, 0x65,
-            0x75, 0x65, 0x29, 0x7b, 0x70, 0x3d, 0x44, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53,
-            0x70, 0x65, 0x63, 0x2e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x70, 0x3d,
-            0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x70, 0x3d, 0x22, 0x6c, 0x61, 0x73, 0x74, 0x22, 0x7d,
-            0x7d, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75,
-            0x65, 0x73, 0x74, 0x73, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x75, 0x2e, 0x71, 0x75,
-            0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x3d, 0x5b, 0x5d, 0x7d,
-            0x69, 0x66, 0x28, 0x70, 0x3d, 0x3d, 0x3d, 0x22, 0x66, 0x69, 0x72, 0x73, 0x74, 0x22, 0x26, 0x26,
-            0x75, 0x2e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73,
-            0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3d, 0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x75, 0x2e, 0x71,
-            0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x2e, 0x70, 0x75,
-            0x73, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x68, 0x65,
-            0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x2c, 0x69, 0x29, 0x7d, 0x29, 0x7d, 0x65, 0x6c,
-            0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x70, 0x3d, 0x3d, 0x3d, 0x22, 0x61, 0x6c, 0x6c, 0x22, 0x29,
-            0x7b, 0x75, 0x2e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-            0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x29, 0x7b, 0x68, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x2c, 0x69, 0x29, 0x7d,
-            0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x70, 0x3d, 0x3d, 0x3d, 0x22, 0x6c,
-            0x61, 0x73, 0x74, 0x22, 0x29, 0x7b, 0x75, 0x2e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65,
-            0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x3d, 0x5b, 0x5d, 0x3b, 0x75, 0x2e, 0x71, 0x75, 0x65, 0x75,
-            0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x68, 0x65, 0x28, 0x74, 0x2c,
-            0x6e, 0x2c, 0x72, 0x2c, 0x6f, 0x2c, 0x69, 0x29, 0x7d, 0x29, 0x7d, 0x72, 0x65, 0x28, 0x73, 0x29,
-            0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x67, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65,
-            0x71, 0x75, 0x65, 0x73, 0x74, 0x3b, 0x75, 0x2e, 0x78, 0x68, 0x72, 0x3d, 0x67, 0x3b, 0x75, 0x2e,
-            0x61, 0x62, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3d, 0x42, 0x3b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x6d, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x75,
-            0x2e, 0x78, 0x68, 0x72, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x75, 0x2e, 0x61, 0x62, 0x6f, 0x72,
-            0x74, 0x61, 0x62, 0x6c, 0x65, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x75,
-            0x2e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x21,
-            0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x26, 0x26, 0x75, 0x2e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52,
-            0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30,
-            0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x65, 0x3d, 0x75, 0x2e, 0x71, 0x75, 0x65, 0x75,
-            0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74,
-            0x28, 0x29, 0x3b, 0x65, 0x28, 0x29, 0x7d, 0x7d, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x58,
-            0x3d, 0x6e, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74,
-            0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x58, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x79, 0x3d, 0x70,
-            0x72, 0x6f, 0x6d, 0x70, 0x74, 0x28, 0x58, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x79, 0x3d, 0x3d, 0x3d,
-            0x6e, 0x75, 0x6c, 0x6c, 0x7c, 0x7c, 0x21, 0x61, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d,
-            0x78, 0x3a, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x22, 0x2c, 0x7b, 0x70, 0x72, 0x6f, 0x6d, 0x70,
-            0x74, 0x3a, 0x79, 0x2c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x63, 0x7d, 0x29, 0x29, 0x7b,
-            0x72, 0x65, 0x28, 0x73, 0x29, 0x3b, 0x6d, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-            0x20, 0x65, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x61, 0x26, 0x26, 0x21, 0x6b, 0x29, 0x7b, 0x69, 0x66,
-            0x28, 0x21, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x28, 0x61, 0x29, 0x29, 0x7b, 0x72, 0x65,
-            0x28, 0x73, 0x29, 0x3b, 0x6d, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65,
-            0x7d, 0x7d, 0x6c, 0x65, 0x74, 0x20, 0x78, 0x3d, 0x6d, 0x6e, 0x28, 0x72, 0x2c, 0x63, 0x2c, 0x79,
-            0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x21, 0x3d, 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, 0x26, 0x26,
-            0x21, 0x76, 0x6e, 0x28, 0x72, 0x29, 0x29, 0x7b, 0x78, 0x5b, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65,
-            0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x22, 0x5d, 0x3d, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69,
-            0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x77, 0x77, 0x77, 0x2d, 0x66, 0x6f, 0x72,
-            0x6d, 0x2d, 0x75, 0x72, 0x6c, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x22, 0x7d, 0x69, 0x66,
-            0x28, 0x69, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x29, 0x7b, 0x78, 0x3d, 0x6c, 0x65,
-            0x28, 0x78, 0x2c, 0x69, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x29, 0x7d, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x55, 0x3d, 0x64, 0x6e, 0x28, 0x72, 0x2c, 0x74, 0x29, 0x3b, 0x6c, 0x65,
-            0x74, 0x20, 0x62, 0x3d, 0x55, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x3b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x56, 0x3d, 0x55, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x3b,
-            0x69, 0x66, 0x28, 0x69, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x29, 0x7b, 0x68, 0x6e, 0x28,
-            0x56, 0x2c, 0x44, 0x6e, 0x28, 0x69, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x29, 0x29, 0x7d,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6a, 0x3d, 0x44, 0x6e, 0x28, 0x52, 0x6e, 0x28, 0x72, 0x2c,
-            0x6f, 0x29, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x76, 0x3d, 0x68, 0x6e, 0x28, 0x56,
-            0x2c, 0x6a, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x77, 0x3d, 0x79, 0x6e, 0x28, 0x76, 0x2c, 0x72,
-            0x29, 0x3b, 0x69, 0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x65,
-            0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x42, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61,
-            0x6d, 0x26, 0x26, 0x74, 0x3d, 0x3d, 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, 0x29, 0x7b, 0x77, 0x2e,
-            0x73, 0x65, 0x74, 0x28, 0x22, 0x6f, 0x72, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x78, 0x2e, 0x63, 0x61,
-            0x63, 0x68, 0x65, 0x2d, 0x62, 0x75, 0x73, 0x74, 0x65, 0x72, 0x22, 0x2c, 0x65, 0x65, 0x28, 0x63,
-            0x2c, 0x22, 0x69, 0x64, 0x22, 0x29, 0x7c, 0x7c, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x29, 0x7d,
-            0x69, 0x66, 0x28, 0x6e, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7c, 0x7c, 0x6e, 0x3d, 0x3d, 0x3d,
-            0x22, 0x22, 0x29, 0x7b, 0x6e, 0x3d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x68,
-            0x72, 0x65, 0x66, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x53, 0x3d, 0x43, 0x6e, 0x28, 0x72,
-            0x2c, 0x22, 0x68, 0x78, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x29, 0x3b, 0x63,
-            0x6f, 0x6e, 0x73, 0x74, 0x20, 0x24, 0x3d, 0x6f, 0x65, 0x28, 0x72, 0x29, 0x2e, 0x62, 0x6f, 0x6f,
-            0x73, 0x74, 0x65, 0x64, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x45, 0x3d, 0x51, 0x2e, 0x63, 0x6f, 0x6e,
-            0x66, 0x69, 0x67, 0x2e, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x54, 0x68, 0x61, 0x74, 0x55,
-            0x73, 0x65, 0x55, 0x72, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x69, 0x6e, 0x64, 0x65,
-            0x78, 0x4f, 0x66, 0x28, 0x74, 0x29, 0x3e, 0x3d, 0x30, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x43, 0x3d, 0x7b, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x3a, 0x24, 0x2c, 0x75, 0x73, 0x65,
-            0x55, 0x72, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x45, 0x2c, 0x66, 0x6f, 0x72, 0x6d,
-            0x44, 0x61, 0x74, 0x61, 0x3a, 0x77, 0x2c, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
-            0x73, 0x3a, 0x6b, 0x6e, 0x28, 0x77, 0x29, 0x2c, 0x75, 0x6e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
-            0x65, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x3a, 0x76, 0x2c, 0x75, 0x6e, 0x66,
-            0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
-            0x73, 0x3a, 0x6b, 0x6e, 0x28, 0x76, 0x29, 0x2c, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3a,
-            0x78, 0x2c, 0x65, 0x6c, 0x74, 0x3a, 0x72, 0x2c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x63,
-            0x2c, 0x76, 0x65, 0x72, 0x62, 0x3a, 0x74, 0x2c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x3a, 0x62,
-            0x2c, 0x77, 0x69, 0x74, 0x68, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
-            0x3a, 0x69, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x7c, 0x7c,
-            0x53, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x7c, 0x7c, 0x51,
-            0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x77, 0x69, 0x74, 0x68, 0x43, 0x72, 0x65, 0x64,
-            0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2c, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x3a,
-            0x69, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x7c, 0x7c, 0x53, 0x2e, 0x74, 0x69, 0x6d,
-            0x65, 0x6f, 0x75, 0x74, 0x7c, 0x7c, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74,
-            0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x2c, 0x70, 0x61, 0x74, 0x68, 0x3a, 0x6e, 0x2c, 0x74, 0x72,
-            0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x3a, 0x6f, 0x7d,
-            0x3b, 0x69, 0x66, 0x28, 0x21, 0x61, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a,
-            0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2c, 0x43,
-            0x29, 0x29, 0x7b, 0x72, 0x65, 0x28, 0x73, 0x29, 0x3b, 0x6d, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x6e, 0x3d, 0x43, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x3b, 0x74,
-            0x3d, 0x43, 0x2e, 0x76, 0x65, 0x72, 0x62, 0x3b, 0x78, 0x3d, 0x43, 0x2e, 0x68, 0x65, 0x61, 0x64,
-            0x65, 0x72, 0x73, 0x3b, 0x77, 0x3d, 0x44, 0x6e, 0x28, 0x43, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d,
-            0x65, 0x74, 0x65, 0x72, 0x73, 0x29, 0x3b, 0x62, 0x3d, 0x43, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72,
-            0x73, 0x3b, 0x45, 0x3d, 0x43, 0x2e, 0x75, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x50, 0x61, 0x72, 0x61,
-            0x6d, 0x73, 0x3b, 0x69, 0x66, 0x28, 0x62, 0x26, 0x26, 0x62, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74,
-            0x68, 0x3e, 0x30, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a,
-            0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x68, 0x61, 0x6c, 0x74, 0x65,
-            0x64, 0x22, 0x2c, 0x43, 0x29, 0x3b, 0x72, 0x65, 0x28, 0x73, 0x29, 0x3b, 0x6d, 0x28, 0x29, 0x3b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x5f,
-            0x3d, 0x6e, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, 0x23, 0x22, 0x29, 0x3b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x7a, 0x3d, 0x5f, 0x5b, 0x30, 0x5d, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x4f, 0x3d, 0x5f, 0x5b, 0x31, 0x5d, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x48, 0x3d, 0x6e, 0x3b,
-            0x69, 0x66, 0x28, 0x45, 0x29, 0x7b, 0x48, 0x3d, 0x7a, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x5a, 0x3d, 0x21, 0x77, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x28, 0x29, 0x2e, 0x6e, 0x65, 0x78, 0x74,
-            0x28, 0x29, 0x2e, 0x64, 0x6f, 0x6e, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x5a, 0x29, 0x7b, 0x69, 0x66,
-            0x28, 0x48, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x3f, 0x22, 0x29, 0x3c,
-            0x30, 0x29, 0x7b, 0x48, 0x2b, 0x3d, 0x22, 0x3f, 0x22, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x48,
-            0x2b, 0x3d, 0x22, 0x26, 0x22, 0x7d, 0x48, 0x2b, 0x3d, 0x67, 0x6e, 0x28, 0x77, 0x29, 0x3b, 0x69,
-            0x66, 0x28, 0x4f, 0x29, 0x7b, 0x48, 0x2b, 0x3d, 0x22, 0x23, 0x22, 0x2b, 0x4f, 0x7d, 0x7d, 0x7d,
-            0x69, 0x66, 0x28, 0x21, 0x49, 0x6e, 0x28, 0x72, 0x2c, 0x48, 0x2c, 0x43, 0x29, 0x29, 0x7b, 0x66,
-            0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69,
-            0x64, 0x50, 0x61, 0x74, 0x68, 0x22, 0x2c, 0x43, 0x29, 0x3b, 0x72, 0x65, 0x28, 0x6c, 0x29, 0x3b,
-            0x6d, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x67, 0x2e, 0x6f,
-            0x70, 0x65, 0x6e, 0x28, 0x74, 0x2e, 0x74, 0x6f, 0x55, 0x70, 0x70, 0x65, 0x72, 0x43, 0x61, 0x73,
-            0x65, 0x28, 0x29, 0x2c, 0x48, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x3b, 0x67, 0x2e, 0x6f, 0x76,
-            0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x4d, 0x69, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x28, 0x22,
-            0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x29, 0x3b, 0x67, 0x2e, 0x77, 0x69,
-            0x74, 0x68, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x3d, 0x43, 0x2e,
-            0x77, 0x69, 0x74, 0x68, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x3b,
-            0x67, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x3d, 0x43, 0x2e, 0x74, 0x69, 0x6d, 0x65,
-            0x6f, 0x75, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x53, 0x2e, 0x6e, 0x6f, 0x48, 0x65, 0x61, 0x64, 0x65,
-            0x72, 0x73, 0x29, 0x7b, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x50, 0x20, 0x69, 0x6e, 0x20, 0x78, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x78,
-            0x2e, 0x68, 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28,
-            0x50, 0x29, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x59, 0x3d, 0x78, 0x5b, 0x50, 0x5d,
-            0x3b, 0x71, 0x6e, 0x28, 0x67, 0x2c, 0x50, 0x2c, 0x59, 0x29, 0x7d, 0x7d, 0x7d, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x54, 0x3d, 0x7b, 0x78, 0x68, 0x72, 0x3a, 0x67, 0x2c, 0x74, 0x61, 0x72, 0x67,
-            0x65, 0x74, 0x3a, 0x63, 0x2c, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66,
-            0x69, 0x67, 0x3a, 0x43, 0x2c, 0x65, 0x74, 0x63, 0x3a, 0x69, 0x2c, 0x62, 0x6f, 0x6f, 0x73, 0x74,
-            0x65, 0x64, 0x3a, 0x24, 0x2c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3a, 0x46, 0x2c, 0x70, 0x61,
-            0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x3a, 0x7b, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50,
-            0x61, 0x74, 0x68, 0x3a, 0x6e, 0x2c, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65,
-            0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x3a, 0x48, 0x2c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-            0x65, 0x50, 0x61, 0x74, 0x68, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x61, 0x6e, 0x63, 0x68, 0x6f,
-            0x72, 0x3a, 0x4f, 0x7d, 0x7d, 0x3b, 0x67, 0x2e, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x3d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x4e, 0x6e, 0x28, 0x72, 0x29, 0x3b, 0x54, 0x2e, 0x70, 0x61,
-            0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x50,
-            0x61, 0x74, 0x68, 0x3d, 0x41, 0x6e, 0x28, 0x67, 0x29, 0x3b, 0x4d, 0x28, 0x72, 0x2c, 0x54, 0x29,
-            0x3b, 0x69, 0x66, 0x28, 0x54, 0x2e, 0x6b, 0x65, 0x65, 0x70, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61,
-            0x74, 0x6f, 0x72, 0x73, 0x21, 0x3d, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x29, 0x7b, 0x72, 0x6e, 0x28,
-            0x52, 0x2c, 0x71, 0x29, 0x7d, 0x61, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a,
-            0x61, 0x66, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2c, 0x54, 0x29,
-            0x3b, 0x61, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x61, 0x66, 0x74, 0x65,
-            0x72, 0x4f, 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x22, 0x2c, 0x54, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21,
-            0x73, 0x65, 0x28, 0x72, 0x29, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x6e, 0x75, 0x6c,
-            0x6c, 0x3b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
-            0x3e, 0x30, 0x26, 0x26, 0x65, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x6e, 0x3d, 0x74, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x3b, 0x69,
-            0x66, 0x28, 0x73, 0x65, 0x28, 0x6e, 0x29, 0x29, 0x7b, 0x65, 0x3d, 0x6e, 0x7d, 0x7d, 0x69, 0x66,
-            0x28, 0x65, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x61,
-            0x66, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2c, 0x54, 0x29, 0x3b,
-            0x61, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72,
-            0x4f, 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x22, 0x2c, 0x54, 0x29, 0x7d, 0x7d, 0x72, 0x65, 0x28, 0x73,
-            0x29, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x7b, 0x66, 0x65, 0x28, 0x72, 0x2c,
-            0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x6f, 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x45, 0x72, 0x72, 0x6f,
-            0x72, 0x22, 0x2c, 0x6c, 0x65, 0x28, 0x7b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x65, 0x7d, 0x2c,
-            0x54, 0x29, 0x29, 0x3b, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x20, 0x65, 0x7d, 0x66, 0x69, 0x6e, 0x61,
-            0x6c, 0x6c, 0x79, 0x7b, 0x6d, 0x28, 0x29, 0x7d, 0x7d, 0x3b, 0x67, 0x2e, 0x6f, 0x6e, 0x65, 0x72,
-            0x72, 0x6f, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72,
-            0x6e, 0x28, 0x52, 0x2c, 0x71, 0x29, 0x3b, 0x66, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d,
-            0x78, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2c,
-            0x54, 0x29, 0x3b, 0x66, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x73, 0x65,
-            0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, 0x54, 0x29, 0x3b, 0x72, 0x65, 0x28, 0x6c,
-            0x29, 0x3b, 0x6d, 0x28, 0x29, 0x7d, 0x3b, 0x67, 0x2e, 0x6f, 0x6e, 0x61, 0x62, 0x6f, 0x72, 0x74,
-            0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x6e, 0x28, 0x52,
-            0x2c, 0x71, 0x29, 0x3b, 0x66, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x61,
-            0x66, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2c, 0x54, 0x29, 0x3b,
-            0x66, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x73, 0x65, 0x6e, 0x64, 0x41,
-            0x62, 0x6f, 0x72, 0x74, 0x22, 0x2c, 0x54, 0x29, 0x3b, 0x72, 0x65, 0x28, 0x6c, 0x29, 0x3b, 0x6d,
-            0x28, 0x29, 0x7d, 0x3b, 0x67, 0x2e, 0x6f, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x3d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x6e, 0x28, 0x52, 0x2c,
-            0x71, 0x29, 0x3b, 0x66, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x61, 0x66,
-            0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2c, 0x54, 0x29, 0x3b, 0x66,
-            0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75,
-            0x74, 0x22, 0x2c, 0x54, 0x29, 0x3b, 0x72, 0x65, 0x28, 0x6c, 0x29, 0x3b, 0x6d, 0x28, 0x29, 0x7d,
-            0x3b, 0x69, 0x66, 0x28, 0x21, 0x61, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a,
-            0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2c, 0x54,
-            0x29, 0x29, 0x7b, 0x72, 0x65, 0x28, 0x73, 0x29, 0x3b, 0x6d, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x52, 0x3d, 0x74, 0x6e, 0x28, 0x72,
-            0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x71, 0x3d, 0x6e, 0x6e, 0x28, 0x72, 0x29, 0x3b, 0x69, 0x65,
-            0x28, 0x5b, 0x22, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x2c, 0x22, 0x6c,
-            0x6f, 0x61, 0x64, 0x65, 0x6e, 0x64, 0x22, 0x2c, 0x22, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73,
-            0x73, 0x22, 0x2c, 0x22, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x22, 0x5d, 0x2c, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x69, 0x65, 0x28, 0x5b, 0x67, 0x2c, 0x67, 0x2e,
-            0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5d, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x28, 0x65, 0x29, 0x7b, 0x65, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69,
-            0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x28, 0x65, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a,
-            0x78, 0x68, 0x72, 0x3a, 0x22, 0x2b, 0x74, 0x2c, 0x7b, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x43,
-            0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67,
-            0x74, 0x68, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x6c, 0x6f, 0x61,
-            0x64, 0x65, 0x64, 0x3a, 0x65, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x2c, 0x74, 0x6f, 0x74,
-            0x61, 0x6c, 0x3a, 0x65, 0x2e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x7d, 0x29, 0x7d, 0x29, 0x7d, 0x29,
-            0x7d, 0x29, 0x3b, 0x61, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x62, 0x65,
-            0x66, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x22, 0x2c, 0x54, 0x29, 0x3b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x4a, 0x3d, 0x45, 0x3f, 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x77, 0x6e, 0x28, 0x67,
-            0x2c, 0x72, 0x2c, 0x77, 0x29, 0x3b, 0x67, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x4a, 0x29, 0x3b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x4d, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x6e, 0x3d, 0x74, 0x2e, 0x78, 0x68, 0x72, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x3d, 0x6e, 0x75,
-            0x6c, 0x6c, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x69, 0x66,
-            0x28, 0x54, 0x28, 0x6e, 0x2c, 0x2f, 0x48, 0x58, 0x2d, 0x50, 0x75, 0x73, 0x68, 0x3a, 0x2f, 0x69,
-            0x29, 0x29, 0x7b, 0x72, 0x3d, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-            0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 0x48, 0x58, 0x2d, 0x50, 0x75, 0x73,
-            0x68, 0x22, 0x29, 0x3b, 0x6f, 0x3d, 0x22, 0x70, 0x75, 0x73, 0x68, 0x22, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x20, 0x69, 0x66, 0x28, 0x54, 0x28, 0x6e, 0x2c, 0x2f, 0x48, 0x58, 0x2d, 0x50, 0x75, 0x73,
-            0x68, 0x2d, 0x55, 0x72, 0x6c, 0x3a, 0x2f, 0x69, 0x29, 0x29, 0x7b, 0x72, 0x3d, 0x6e, 0x2e, 0x67,
-            0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
-            0x28, 0x22, 0x48, 0x58, 0x2d, 0x50, 0x75, 0x73, 0x68, 0x2d, 0x55, 0x72, 0x6c, 0x22, 0x29, 0x3b,
-            0x6f, 0x3d, 0x22, 0x70, 0x75, 0x73, 0x68, 0x22, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66,
-            0x28, 0x54, 0x28, 0x6e, 0x2c, 0x2f, 0x48, 0x58, 0x2d, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
-            0x2d, 0x55, 0x72, 0x6c, 0x3a, 0x2f, 0x69, 0x29, 0x29, 0x7b, 0x72, 0x3d, 0x6e, 0x2e, 0x67, 0x65,
-            0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28,
-            0x22, 0x48, 0x58, 0x2d, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2d, 0x55, 0x72, 0x6c, 0x22,
-            0x29, 0x3b, 0x6f, 0x3d, 0x22, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x22, 0x7d, 0x69, 0x66,
-            0x28, 0x72, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x3d, 0x3d, 0x22, 0x66, 0x61, 0x6c, 0x73,
-            0x65, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x7d, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x6f, 0x2c,
-            0x70, 0x61, 0x74, 0x68, 0x3a, 0x72, 0x7d, 0x7d, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69,
-            0x3d, 0x74, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x69, 0x6e, 0x61,
-            0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x3b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x73, 0x3d, 0x74, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x2e,
-            0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x3b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x6c, 0x3d, 0x74, 0x2e, 0x65, 0x74, 0x63, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x7c,
-            0x7c, 0x6e, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x75,
-            0x72, 0x6c, 0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x3d, 0x74, 0x2e, 0x65,
-            0x74, 0x63, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x7c, 0x7c, 0x6e, 0x65, 0x28, 0x65,
-            0x2c, 0x22, 0x68, 0x78, 0x2d, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2d, 0x75, 0x72, 0x6c,
-            0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x75, 0x3d, 0x6f, 0x65, 0x28, 0x65, 0x29,
-            0x2e, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x66, 0x3d, 0x6e,
-            0x75, 0x6c, 0x6c, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x61, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x69,
-            0x66, 0x28, 0x6c, 0x29, 0x7b, 0x66, 0x3d, 0x22, 0x70, 0x75, 0x73, 0x68, 0x22, 0x3b, 0x61, 0x3d,
-            0x6c, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x63, 0x29, 0x7b, 0x66, 0x3d, 0x22,
-            0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x22, 0x3b, 0x61, 0x3d, 0x63, 0x7d, 0x65, 0x6c, 0x73,
-            0x65, 0x20, 0x69, 0x66, 0x28, 0x75, 0x29, 0x7b, 0x66, 0x3d, 0x22, 0x70, 0x75, 0x73, 0x68, 0x22,
-            0x3b, 0x61, 0x3d, 0x73, 0x7c, 0x7c, 0x69, 0x7d, 0x69, 0x66, 0x28, 0x61, 0x29, 0x7b, 0x69, 0x66,
-            0x28, 0x61, 0x3d, 0x3d, 0x3d, 0x22, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x22, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x7b, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x61, 0x3d, 0x3d, 0x3d, 0x22, 0x74,
-            0x72, 0x75, 0x65, 0x22, 0x29, 0x7b, 0x61, 0x3d, 0x73, 0x7c, 0x7c, 0x69, 0x7d, 0x69, 0x66, 0x28,
-            0x74, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x61, 0x6e, 0x63, 0x68, 0x6f,
-            0x72, 0x26, 0x26, 0x61, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x23, 0x22,
-            0x29, 0x3d, 0x3d, 0x3d, 0x2d, 0x31, 0x29, 0x7b, 0x61, 0x3d, 0x61, 0x2b, 0x22, 0x23, 0x22, 0x2b,
-            0x74, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x61, 0x6e, 0x63, 0x68, 0x6f,
-            0x72, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x66, 0x2c,
-            0x70, 0x61, 0x74, 0x68, 0x3a, 0x61, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x7b, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-            0x46, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x6e, 0x65,
-            0x77, 0x20, 0x52, 0x65, 0x67, 0x45, 0x78, 0x70, 0x28, 0x65, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x29,
-            0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x74,
-            0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x31, 0x30, 0x29, 0x29, 0x7d, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x66, 0x6f,
-            0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x30, 0x3b, 0x74, 0x3c, 0x51, 0x2e, 0x63, 0x6f,
-            0x6e, 0x66, 0x69, 0x67, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x61, 0x6e,
-            0x64, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x74, 0x2b, 0x2b,
-            0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-            0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e,
-            0x67, 0x5b, 0x74, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x46, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x2e, 0x73,
-            0x74, 0x61, 0x74, 0x75, 0x73, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e,
-            0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x73, 0x77, 0x61, 0x70, 0x3a, 0x66, 0x61,
-            0x6c, 0x73, 0x65, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x58, 0x6e,
-            0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
-            0x74, 0x3d, 0x66, 0x28, 0x22, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28,
-            0x74, 0x29, 0x7b, 0x74, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-            0x3d, 0x65, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x64,
-            0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x65, 0x7d,
-            0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x55, 0x6e, 0x28, 0x65, 0x2c,
-            0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x3d, 0x3d, 0x3d, 0x22, 0x74, 0x68, 0x69, 0x73, 0x22,
-            0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x6e, 0x3d, 0x63, 0x65, 0x28, 0x75, 0x65, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x29, 0x3b, 0x69,
-            0x66, 0x28, 0x6e, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x66, 0x65, 0x28, 0x65, 0x2c,
-            0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x45, 0x72, 0x72, 0x6f,
-            0x72, 0x22, 0x2c, 0x7b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x74, 0x7d, 0x29, 0x3b, 0x74,
-            0x68, 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x60,
-            0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x65, 0x2d, 0x74, 0x61, 0x72, 0x67, 0x65,
-            0x74, 0x20, 0x24, 0x7b, 0x74, 0x7d, 0x60, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56, 0x6e, 0x28, 0x74, 0x2c,
-            0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x65, 0x2e, 0x78, 0x68, 0x72,
-            0x3b, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x3d, 0x65, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3b,
-            0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6f, 0x3d, 0x65, 0x2e, 0x65, 0x74, 0x63, 0x3b, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x69, 0x3d, 0x65, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3b, 0x69,
-            0x66, 0x28, 0x21, 0x61, 0x65, 0x28, 0x74, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x62, 0x65,
-            0x66, 0x6f, 0x72, 0x65, 0x4f, 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x22, 0x2c, 0x65, 0x29, 0x29, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x69, 0x66, 0x28, 0x54, 0x28, 0x6e, 0x2c, 0x2f, 0x48, 0x58,
-            0x2d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x3a, 0x2f, 0x69, 0x29, 0x29, 0x7b, 0x4a, 0x65,
-            0x28, 0x6e, 0x2c, 0x22, 0x48, 0x58, 0x2d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x22, 0x2c,
-            0x74, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x54, 0x28, 0x6e, 0x2c, 0x2f, 0x48, 0x58, 0x2d, 0x4c, 0x6f,
-            0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x2f, 0x69, 0x29, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20,
-            0x65, 0x3d, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48,
-            0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 0x48, 0x58, 0x2d, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69,
-            0x6f, 0x6e, 0x22, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x3d, 0x7b, 0x7d, 0x3b, 0x69, 0x66,
-            0x28, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x7b, 0x22, 0x29, 0x3d,
-            0x3d, 0x3d, 0x30, 0x29, 0x7b, 0x73, 0x3d, 0x76, 0x28, 0x65, 0x29, 0x3b, 0x65, 0x3d, 0x73, 0x2e,
-            0x70, 0x61, 0x74, 0x68, 0x3b, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x73, 0x2e, 0x70, 0x61,
-            0x74, 0x68, 0x7d, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x3d, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68,
-            0x7c, 0x7c, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x3b, 0x4c, 0x6e, 0x28, 0x22, 0x67, 0x65, 0x74,
-            0x22, 0x2c, 0x65, 0x2c, 0x73, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x6c, 0x3d, 0x54, 0x28, 0x6e, 0x2c, 0x2f, 0x48, 0x58, 0x2d, 0x52, 0x65,
-            0x66, 0x72, 0x65, 0x73, 0x68, 0x3a, 0x2f, 0x69, 0x29, 0x26, 0x26, 0x6e, 0x2e, 0x67, 0x65, 0x74,
-            0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22,
-            0x48, 0x58, 0x2d, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x22,
-            0x74, 0x72, 0x75, 0x65, 0x22, 0x3b, 0x69, 0x66, 0x28, 0x54, 0x28, 0x6e, 0x2c, 0x2f, 0x48, 0x58,
-            0x2d, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x3a, 0x2f, 0x69, 0x29, 0x29, 0x7b, 0x65,
-            0x2e, 0x6b, 0x65, 0x65, 0x70, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x3d,
-            0x74, 0x72, 0x75, 0x65, 0x3b, 0x51, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
-            0x68, 0x72, 0x65, 0x66, 0x3d, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-            0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 0x48, 0x58, 0x2d, 0x52, 0x65, 0x64,
-            0x69, 0x72, 0x65, 0x63, 0x74, 0x22, 0x29, 0x3b, 0x6c, 0x26, 0x26, 0x51, 0x2e, 0x6c, 0x6f, 0x63,
-            0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x29, 0x3b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x69, 0x66, 0x28, 0x6c, 0x29, 0x7b, 0x65, 0x2e, 0x6b, 0x65,
-            0x65, 0x70, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x3d, 0x74, 0x72, 0x75,
-            0x65, 0x3b, 0x51, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x65, 0x6c,
-            0x6f, 0x61, 0x64, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x63, 0x3d, 0x4d, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x3b, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x75, 0x3d, 0x42, 0x6e, 0x28, 0x6e, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x66, 0x3d, 0x75, 0x2e, 0x73, 0x77, 0x61, 0x70, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x61, 0x3d,
-            0x21, 0x21, 0x75, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x3d,
-            0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x54,
-            0x69, 0x74, 0x6c, 0x65, 0x7c, 0x7c, 0x75, 0x2e, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x54, 0x69,
-            0x74, 0x6c, 0x65, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x3d, 0x75, 0x2e, 0x73, 0x65, 0x6c, 0x65,
-            0x63, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x7b,
-            0x65, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x55, 0x6e, 0x28, 0x74, 0x2c, 0x75, 0x2e,
-            0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x70, 0x3d, 0x6f, 0x2e,
-            0x73, 0x77, 0x61, 0x70, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x3b, 0x69, 0x66, 0x28,
-            0x70, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x26, 0x26, 0x75, 0x2e, 0x73, 0x77, 0x61, 0x70, 0x4f,
-            0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x29, 0x7b, 0x70, 0x3d, 0x75, 0x2e, 0x73, 0x77, 0x61,
-            0x70, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x7d, 0x69, 0x66, 0x28, 0x54, 0x28, 0x6e,
-            0x2c, 0x2f, 0x48, 0x58, 0x2d, 0x52, 0x65, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x2f, 0x69,
-            0x29, 0x29, 0x7b, 0x65, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x55, 0x6e, 0x28, 0x74,
-            0x2c, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65,
-            0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 0x48, 0x58, 0x2d, 0x52, 0x65, 0x74, 0x61, 0x72, 0x67, 0x65,
-            0x74, 0x22, 0x29, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x54, 0x28, 0x6e, 0x2c, 0x2f, 0x48, 0x58, 0x2d,
-            0x52, 0x65, 0x73, 0x77, 0x61, 0x70, 0x3a, 0x2f, 0x69, 0x29, 0x29, 0x7b, 0x70, 0x3d, 0x6e, 0x2e,
-            0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65,
-            0x72, 0x28, 0x22, 0x48, 0x58, 0x2d, 0x52, 0x65, 0x73, 0x77, 0x61, 0x70, 0x22, 0x29, 0x7d, 0x76,
-            0x61, 0x72, 0x20, 0x67, 0x3d, 0x6e, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3b,
-            0x76, 0x61, 0x72, 0x20, 0x6d, 0x3d, 0x6c, 0x65, 0x28, 0x7b, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64,
-            0x53, 0x77, 0x61, 0x70, 0x3a, 0x66, 0x2c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73,
-            0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3a, 0x67, 0x2c, 0x69, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a,
-            0x61, 0x2c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x3a, 0x68, 0x2c,
-            0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x3a, 0x64,
-            0x2c, 0x73, 0x77, 0x61, 0x70, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x3a, 0x70, 0x7d,
-            0x2c, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x26, 0x26,
-            0x21, 0x61, 0x65, 0x28, 0x72, 0x2c, 0x75, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2c, 0x6d, 0x29,
-            0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x61, 0x65, 0x28, 0x72,
-            0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x53, 0x77, 0x61,
-            0x70, 0x22, 0x2c, 0x6d, 0x29, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x72, 0x3d, 0x6d,
-            0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3b, 0x67, 0x3d, 0x6d, 0x2e, 0x73, 0x65, 0x72, 0x76,
-            0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3b, 0x61, 0x3d, 0x6d, 0x2e, 0x69,
-            0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3b, 0x68, 0x3d, 0x6d, 0x2e, 0x69, 0x67, 0x6e, 0x6f, 0x72,
-            0x65, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x3b, 0x64, 0x3d, 0x6d, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63,
-            0x74, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x3b, 0x70, 0x3d, 0x6d, 0x2e, 0x73, 0x77,
-            0x61, 0x70, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x3b, 0x65, 0x2e, 0x74, 0x61, 0x72,
-            0x67, 0x65, 0x74, 0x3d, 0x72, 0x3b, 0x65, 0x2e, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x3d, 0x61,
-            0x3b, 0x65, 0x2e, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x3d, 0x21, 0x61,
-            0x3b, 0x69, 0x66, 0x28, 0x6d, 0x2e, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x53, 0x77, 0x61, 0x70,
-            0x29, 0x7b, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3d, 0x3d, 0x3d,
-            0x32, 0x38, 0x36, 0x29, 0x7b, 0x6c, 0x74, 0x28, 0x74, 0x29, 0x7d, 0x56, 0x74, 0x28, 0x74, 0x2c,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x67, 0x3d, 0x65, 0x2e,
-            0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-            0x65, 0x28, 0x67, 0x2c, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x63, 0x2e,
-            0x74, 0x79, 0x70, 0x65, 0x29, 0x7b, 0x47, 0x74, 0x28, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x79,
-            0x3d, 0x62, 0x6e, 0x28, 0x74, 0x2c, 0x70, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x79, 0x2e, 0x68,
-            0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x22, 0x69,
-            0x67, 0x6e, 0x6f, 0x72, 0x65, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x29, 0x29, 0x7b, 0x79, 0x2e,
-            0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x68, 0x7d, 0x72, 0x2e,
-            0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x51, 0x2e,
-            0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x73, 0x77, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43,
-            0x6c, 0x61, 0x73, 0x73, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x29, 0x7b, 0x64, 0x3d, 0x69, 0x7d,
-            0x69, 0x66, 0x28, 0x54, 0x28, 0x6e, 0x2c, 0x2f, 0x48, 0x58, 0x2d, 0x52, 0x65, 0x73, 0x65, 0x6c,
-            0x65, 0x63, 0x74, 0x3a, 0x2f, 0x69, 0x29, 0x29, 0x7b, 0x64, 0x3d, 0x6e, 0x2e, 0x67, 0x65, 0x74,
-            0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22,
-            0x48, 0x58, 0x2d, 0x52, 0x65, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x22, 0x29, 0x7d, 0x63, 0x6f,
-            0x6e, 0x73, 0x74, 0x20, 0x78, 0x3d, 0x6f, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4f, 0x4f,
-            0x42, 0x7c, 0x7c, 0x6e, 0x65, 0x28, 0x74, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x73, 0x65, 0x6c, 0x65,
-            0x63, 0x74, 0x2d, 0x6f, 0x6f, 0x62, 0x22, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x62,
-            0x3d, 0x6e, 0x65, 0x28, 0x74, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74,
-            0x22, 0x29, 0x3b, 0x7a, 0x65, 0x28, 0x72, 0x2c, 0x67, 0x2c, 0x79, 0x2c, 0x7b, 0x73, 0x65, 0x6c,
-            0x65, 0x63, 0x74, 0x3a, 0x64, 0x3d, 0x3d, 0x3d, 0x22, 0x75, 0x6e, 0x73, 0x65, 0x74, 0x22, 0x3f,
-            0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x64, 0x7c, 0x7c, 0x62, 0x2c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74,
-            0x4f, 0x4f, 0x42, 0x3a, 0x78, 0x2c, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x3a,
-            0x65, 0x2c, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x3a, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x49,
-            0x6e, 0x66, 0x6f, 0x2e, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x2c, 0x63, 0x6f, 0x6e, 0x74, 0x65,
-            0x78, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x74, 0x2c, 0x61, 0x66, 0x74, 0x65,
-            0x72, 0x53, 0x77, 0x61, 0x70, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x3a, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x54, 0x28, 0x6e, 0x2c,
-            0x2f, 0x48, 0x58, 0x2d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2d, 0x41, 0x66, 0x74, 0x65,
-            0x72, 0x2d, 0x53, 0x77, 0x61, 0x70, 0x3a, 0x2f, 0x69, 0x29, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20,
-            0x65, 0x3d, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x73, 0x65, 0x28, 0x74, 0x29, 0x29, 0x7b, 0x65,
-            0x3d, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x7d, 0x4a, 0x65, 0x28, 0x6e, 0x2c,
-            0x22, 0x48, 0x58, 0x2d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2d, 0x41, 0x66, 0x74, 0x65,
-            0x72, 0x2d, 0x53, 0x77, 0x61, 0x70, 0x22, 0x2c, 0x65, 0x29, 0x7d, 0x7d, 0x2c, 0x61, 0x66, 0x74,
-            0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b,
-            0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x54,
-            0x28, 0x6e, 0x2c, 0x2f, 0x48, 0x58, 0x2d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2d, 0x41,
-            0x66, 0x74, 0x65, 0x72, 0x2d, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x3a, 0x2f, 0x69, 0x29, 0x29,
-            0x7b, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x73, 0x65, 0x28,
-            0x74, 0x29, 0x29, 0x7b, 0x65, 0x3d, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x7d,
-            0x4a, 0x65, 0x28, 0x6e, 0x2c, 0x22, 0x48, 0x58, 0x2d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
-            0x2d, 0x41, 0x66, 0x74, 0x65, 0x72, 0x2d, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x22, 0x2c, 0x65,
-            0x29, 0x7d, 0x7d, 0x2c, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x53, 0x77, 0x61, 0x70, 0x43, 0x61,
-            0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
-            0x29, 0x7b, 0x69, 0x66, 0x28, 0x63, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x7b, 0x61, 0x65, 0x28,
-            0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a,
-            0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x55, 0x70, 0x64,
-            0x61, 0x74, 0x65, 0x22, 0x2c, 0x6c, 0x65, 0x28, 0x7b, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
-            0x3a, 0x63, 0x7d, 0x2c, 0x65, 0x29, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x63, 0x2e, 0x74, 0x79, 0x70,
-            0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x70, 0x75, 0x73, 0x68, 0x22, 0x29, 0x7b, 0x57, 0x74, 0x28, 0x63,
-            0x2e, 0x70, 0x61, 0x74, 0x68, 0x29, 0x3b, 0x61, 0x65, 0x28, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62,
-            0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x70, 0x75, 0x73, 0x68, 0x65, 0x64,
-            0x49, 0x6e, 0x74, 0x6f, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x7b, 0x70, 0x61,
-            0x74, 0x68, 0x3a, 0x63, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x7d, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65,
-            0x7b, 0x5a, 0x74, 0x28, 0x63, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x29, 0x3b, 0x61, 0x65, 0x28, 0x74,
-            0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x72,
-            0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x49, 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
-            0x22, 0x2c, 0x7b, 0x70, 0x61, 0x74, 0x68, 0x3a, 0x63, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x7d, 0x29,
-            0x7d, 0x7d, 0x7d, 0x7d, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x61, 0x29, 0x7b, 0x66, 0x65, 0x28, 0x74,
-            0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45,
-            0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, 0x6c, 0x65, 0x28, 0x7b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a,
-            0x22, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
-            0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x43, 0x6f, 0x64, 0x65, 0x20, 0x22, 0x2b, 0x6e, 0x2e,
-            0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2b, 0x22, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x22, 0x2b,
-            0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65,
-            0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x7d, 0x2c, 0x65, 0x29, 0x29, 0x7d, 0x7d, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x6a, 0x6e, 0x3d, 0x7b, 0x7d, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x20, 0x24, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x69, 0x6e,
-            0x69, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x53,
-            0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d,
-            0x2c, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72,
-            0x75, 0x65, 0x7d, 0x2c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73,
-            0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65,
-            0x2c, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x2c,
-            0x69, 0x73, 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x77, 0x61, 0x70, 0x3a, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-            0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x2c, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x53, 0x77, 0x61,
-            0x70, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x6e,
-            0x2c, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65,
-            0x7d, 0x2c, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,
-            0x72, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x2c,
-            0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x7d,
-            0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x6e, 0x28, 0x65, 0x2c, 0x74,
-            0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x29, 0x7b, 0x74, 0x2e, 0x69,
-            0x6e, 0x69, 0x74, 0x28, 0x6e, 0x29, 0x7d, 0x6a, 0x6e, 0x5b, 0x65, 0x5d, 0x3d, 0x6c, 0x65, 0x28,
-            0x24, 0x6e, 0x28, 0x29, 0x2c, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x7a, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x6a, 0x6e,
-            0x5b, 0x65, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4a, 0x6e, 0x28,
-            0x65, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6e, 0x3d, 0x3d, 0x75, 0x6e, 0x64,
-            0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x29, 0x7b, 0x6e, 0x3d, 0x5b, 0x5d, 0x7d, 0x69, 0x66, 0x28,
-            0x65, 0x3d, 0x3d, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x29, 0x7b, 0x72, 0x65,
-            0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x3d, 0x75, 0x6e, 0x64,
-            0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x29, 0x7b, 0x72, 0x3d, 0x5b, 0x5d, 0x7d, 0x63, 0x6f, 0x6e,
-            0x73, 0x74, 0x20, 0x74, 0x3d, 0x61, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x65, 0x78, 0x74,
-            0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x69, 0x65, 0x28, 0x74, 0x2e, 0x73, 0x70,
-            0x6c, 0x69, 0x74, 0x28, 0x22, 0x2c, 0x22, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x28, 0x65, 0x29, 0x7b, 0x65, 0x3d, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
-            0x28, 0x2f, 0x20, 0x2f, 0x67, 0x2c, 0x22, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x73,
-            0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2c, 0x37, 0x29, 0x3d, 0x3d, 0x22, 0x69, 0x67, 0x6e, 0x6f,
-            0x72, 0x65, 0x3a, 0x22, 0x29, 0x7b, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x65, 0x2e, 0x73,
-            0x6c, 0x69, 0x63, 0x65, 0x28, 0x37, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d,
-            0x69, 0x66, 0x28, 0x72, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x65, 0x29, 0x3c,
-            0x30, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x6a, 0x6e, 0x5b, 0x65, 0x5d,
-            0x3b, 0x69, 0x66, 0x28, 0x74, 0x26, 0x26, 0x6e, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66,
-            0x28, 0x74, 0x29, 0x3c, 0x30, 0x29, 0x7b, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x29,
-            0x7d, 0x7d, 0x7d, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4a, 0x6e, 0x28, 0x63,
-            0x65, 0x28, 0x75, 0x28, 0x65, 0x29, 0x29, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x7d, 0x76, 0x61, 0x72,
-            0x20, 0x4b, 0x6e, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x61,
-            0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28,
-            0x22, 0x44, 0x4f, 0x4d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x65,
-            0x64, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x4b, 0x6e,
-            0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x29, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-            0x20, 0x47, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x4b, 0x6e, 0x7c, 0x7c, 0x74, 0x65,
-            0x28, 0x29, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3d, 0x3d, 0x3d,
-            0x22, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x22, 0x29, 0x7b, 0x65, 0x28, 0x29, 0x7d,
-            0x65, 0x6c, 0x73, 0x65, 0x7b, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65,
-            0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x44, 0x4f, 0x4d, 0x43,
-            0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x22, 0x2c, 0x65, 0x29,
-            0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x57, 0x6e, 0x28, 0x29, 0x7b,
-            0x69, 0x66, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x69, 0x6e, 0x63, 0x6c,
-            0x75, 0x64, 0x65, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x79, 0x6c,
-            0x65, 0x73, 0x21, 0x3d, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x65, 0x3d, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x69, 0x6e, 0x6c,
-            0x69, 0x6e, 0x65, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x3f, 0x60, 0x20,
-            0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x3d, 0x22, 0x24, 0x7b, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-            0x67, 0x2e, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x4e, 0x6f, 0x6e,
-            0x63, 0x65, 0x7d, 0x22, 0x60, 0x3a, 0x22, 0x22, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74,
-            0x3d, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61,
-            0x74, 0x6f, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e,
-            0x3d, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-            0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3b, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x68, 0x65, 0x61, 0x64,
-            0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x41, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x48,
-            0x54, 0x4d, 0x4c, 0x28, 0x22, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x65, 0x6e, 0x64, 0x22, 0x2c,
-            0x60, 0x3c, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x24, 0x7b, 0x65, 0x7d, 0x3e, 0x60, 0x2b, 0x60, 0x2e,
-            0x24, 0x7b, 0x74, 0x7d, 0x7b, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3a, 0x30, 0x3b, 0x76,
-            0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65,
-            0x6e, 0x7d, 0x20, 0x60, 0x2b, 0x60, 0x2e, 0x24, 0x7b, 0x6e, 0x7d, 0x20, 0x2e, 0x24, 0x7b, 0x74,
-            0x7d, 0x2c, 0x20, 0x2e, 0x24, 0x7b, 0x6e, 0x7d, 0x2e, 0x24, 0x7b, 0x74, 0x7d, 0x7b, 0x6f, 0x70,
-            0x61, 0x63, 0x69, 0x74, 0x79, 0x3a, 0x31, 0x3b, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69,
-            0x74, 0x79, 0x3a, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x3b, 0x74, 0x72, 0x61, 0x6e,
-            0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x20,
-            0x32, 0x30, 0x30, 0x6d, 0x73, 0x20, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x69, 0x6e, 0x7d, 0x60, 0x2b,
-            0x22, 0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x22, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5a, 0x6e, 0x28, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74,
-            0x20, 0x65, 0x3d, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c,
-            0x65, 0x63, 0x74, 0x6f, 0x72, 0x28, 0x27, 0x6d, 0x65, 0x74, 0x61, 0x5b, 0x6e, 0x61, 0x6d, 0x65,
-            0x3d, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x5d, 0x27,
-            0x29, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76,
-            0x28, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65,
-            0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x7d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x59, 0x6e, 0x28, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73,
-            0x74, 0x20, 0x65, 0x3d, 0x5a, 0x6e, 0x28, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x29, 0x7b, 0x51,
-            0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3d, 0x6c, 0x65, 0x28, 0x51, 0x2e, 0x63, 0x6f, 0x6e,
-            0x66, 0x69, 0x67, 0x2c, 0x65, 0x29, 0x7d, 0x7d, 0x47, 0x6e, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74,
-            0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x59, 0x6e, 0x28, 0x29, 0x3b, 0x57, 0x6e, 0x28, 0x29, 0x3b,
-            0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x74, 0x65, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x3b,
-            0x46, 0x74, 0x28, 0x65, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x74, 0x65,
-            0x28, 0x29, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72,
-            0x41, 0x6c, 0x6c, 0x28, 0x22, 0x5b, 0x68, 0x78, 0x2d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
-            0x3d, 0x27, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x27, 0x5d, 0x2c, 0x5b, 0x64, 0x61,
-            0x74, 0x61, 0x2d, 0x68, 0x78, 0x2d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x3d, 0x27, 0x72,
-            0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x27, 0x5d, 0x22, 0x29, 0x3b, 0x65, 0x2e, 0x61, 0x64,
-            0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22,
-            0x68, 0x74, 0x6d, 0x78, 0x3a, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63,
-            0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d,
-            0x65, 0x2e, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x2e, 0x65, 0x6c, 0x74, 0x7c, 0x7c, 0x65, 0x2e,
-            0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x6f,
-            0x65, 0x28, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x26, 0x26, 0x6e, 0x2e, 0x78, 0x68, 0x72,
-            0x29, 0x7b, 0x6e, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x28, 0x29, 0x7d,
-            0x7d, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6e, 0x3d, 0x77, 0x69, 0x6e, 0x64, 0x6f,
-            0x77, 0x2e, 0x6f, 0x6e, 0x70, 0x6f, 0x70, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3f, 0x77, 0x69, 0x6e,
-            0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x70, 0x6f, 0x70, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x62,
-            0x69, 0x6e, 0x64, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x29, 0x3a, 0x6e, 0x75, 0x6c, 0x6c,
-            0x3b, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x70, 0x6f, 0x70, 0x73, 0x74, 0x61,
-            0x74, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69,
-            0x66, 0x28, 0x65, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x26, 0x26, 0x65, 0x2e, 0x73, 0x74, 0x61,
-            0x74, 0x65, 0x2e, 0x68, 0x74, 0x6d, 0x78, 0x29, 0x7b, 0x65, 0x6e, 0x28, 0x29, 0x3b, 0x69, 0x65,
-            0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x61,
-            0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72,
-            0x65, 0x64, 0x22, 0x2c, 0x7b, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x74, 0x65,
-            0x28, 0x29, 0x2c, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x3a,
-            0x61, 0x65, 0x7d, 0x29, 0x7d, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x69, 0x66, 0x28, 0x6e,
-            0x29, 0x7b, 0x6e, 0x28, 0x65, 0x29, 0x7d, 0x7d, 0x7d, 0x3b, 0x62, 0x28, 0x29, 0x2e, 0x73, 0x65,
-            0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
-            0x6e, 0x28, 0x29, 0x7b, 0x61, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x6c,
-            0x6f, 0x61, 0x64, 0x22, 0x2c, 0x7b, 0x7d, 0x29, 0x3b, 0x65, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d,
-            0x2c, 0x30, 0x29, 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x51, 0x7d, 0x28,
-            0x29, 0x3b
-        };
-
-        private const uint8[] GZIP_DATA = {
-            0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0xad, 0x7d, 0x69, 0x7b, 0xd3, 0x48,
-            0xb6, 0xf0, 0x5f, 0x49, 0x34, 0x3c, 0x89, 0xdd, 0x51, 0x9c, 0xd0, 0x33, 0x73, 0x67, 0xae, 0x8d,
-            0xe0, 0x85, 0x10, 0x9a, 0x74, 0x03, 0xa1, 0x49, 0xa0, 0x97, 0x90, 0xa6, 0x15, 0xbb, 0x1c, 0x0b,
-            0x1c, 0xc9, 0x2d, 0x95, 0xb3, 0xb4, 0xe3, 0xff, 0xfe, 0x9e, 0xa5, 0x96, 0x53, 0x92, 0x1c, 0xd2,
-            0x33, 0xf7, 0x03, 0xc4, 0xaa, 0x7d, 0x39, 0x75, 0xea, 0xec, 0x75, 0x99, 0x96, 0x6b, 0x13, 0x7d,
-            0x71, 0x9d, 0x8c, 0xe7, 0xf9, 0x50, 0x67, 0x45, 0xde, 0xe9, 0x2e, 0xa2, 0x79, 0xa5, 0xd6, 0x2a,
-            0x5d, 0x66, 0x43, 0x1d, 0x0d, 0x86, 0x45, 0x5e, 0xe9, 0xb5, 0x1f, 0x93, 0x45, 0x91, 0xbf, 0x2a,
-            0xd2, 0x51, 0x3f, 0x9f, 0x4f, 0xa7, 0xf1, 0xac, 0x2c, 0x86, 0xaa, 0xaa, 0xf8, 0xa3, 0xc8, 0xcd,
-            0xdf, 0xf1, 0x98, 0x7f, 0x40, 0xcd, 0xf3, 0x73, 0x55, 0xf2, 0x47, 0xfa, 0x39, 0xbd, 0xe6, 0x5f,
-            0xe3, 0x2c, 0x1f, 0xf9, 0x5f, 0x4f, 0xa7, 0x53, 0xfe, 0x18, 0x4e, 0x8b, 0x4a, 0x55, 0x9a, 0x3f,
-            0x2e, 0xd3, 0xe9, 0x5c, 0x55, 0x7d, 0x37, 0x18, 0x15, 0xeb, 0xee, 0x82, 0x87, 0x90, 0x27, 0x23,
-            0xfa, 0xbe, 0xbd, 0x8d, 0x66, 0x45, 0xa5, 0xa3, 0xee, 0xa0, 0x54, 0x7a, 0x5e, 0xe6, 0x6b, 0x79,
-            0x8f, 0x6b, 0x2d, 0xe3, 0x52, 0x5d, 0x14, 0x97, 0xca, 0xf4, 0x3b, 0x1a, 0xed, 0x4d, 0x53, 0x3b,
-            0x46, 0xce, 0x11, 0x09, 0xba, 0x38, 0x3f, 0x9f, 0x06, 0x09, 0xe9, 0x17, 0xf9, 0x59, 0x5d, 0xa5,
-            0x33, 0xfe, 0x35, 0x52, 0x30, 0x5c, 0xb5, 0x7f, 0xad, 0x55, 0x5e, 0x65, 0x76, 0xae, 0xdc, 0x5e,
-            0x2d, 0x71, 0x5a, 0x9c, 0xbb, 0x59, 0xc1, 0xef, 0x37, 0x45, 0xae, 0xdc, 0x87, 0x5b, 0x0f, 0x98,
-            0xcc, 0x38, 0x3b, 0xef, 0x2f, 0x26, 0x59, 0xa5, 0x8b, 0xf2, 0x66, 0x3f, 0x4f, 0xcf, 0xa6, 0x6a,
-            0xd4, 0xd7, 0xe5, 0x5c, 0xc5, 0x26, 0x6d, 0x2f, 0x1d, 0x4e, 0xd4, 0x51, 0xf6, 0xa7, 0xea, 0x3f,
-            0xdc, 0x85, 0x9e, 0xc6, 0xa5, 0xaa, 0x26, 0x87, 0xf9, 0x4b, 0xce, 0x7c, 0x9d, 0xc1, 0x10, 0xc7,
-            0xe9, 0xb4, 0x52, 0x38, 0xb2, 0x74, 0x3e, 0xd5, 0x47, 0x30, 0xd4, 0x23, 0x7d, 0x33, 0x55, 0xfd,
-            0x28, 0xcb, 0x73, 0x55, 0xbe, 0x3c, 0x7e, 0xfd, 0x2a, 0x92, 0x99, 0xcf, 0xd5, 0x34, 0xbd, 0xe9,
-            0xef, 0xba, 0x24, 0xa5, 0xf5, 0x54, 0x71, 0xe2, 0xb7, 0xbb, 0x71, 0x96, 0x0f, 0xa7, 0xf3, 0x91,
-            0x3a, 0xc8, 0x47, 0xd9, 0x30, 0x85, 0x1e, 0xa8, 0xa9, 0x8a, 0x07, 0x94, 0xd9, 0x44, 0x5e, 0x99,
-            0x08, 0x21, 0x65, 0xdb, 0x25, 0x46, 0x30, 0xb8, 0x3f, 0x60, 0xe1, 0xb5, 0xcc, 0x35, 0x49, 0x11,
-            0x6e, 0x80, 0x1a, 0xc9, 0x1c, 0x4a, 0x88, 0xe2, 0x0a, 0xbb, 0xcf, 0xf2, 0x73, 0x99, 0x65, 0xd3,
-            0x22, 0x5a, 0xf7, 0x59, 0x3d, 0xd7, 0xa4, 0x41, 0x9b, 0xd3, 0x69, 0x71, 0xb5, 0x0f, 0xdb, 0xcd,
-            0xc3, 0xa3, 0xcf, 0xa3, 0x61, 0x99, 0xcd, 0xf4, 0x71, 0x7a, 0xee, 0xc6, 0x0c, 0x2d, 0x29, 0x4e,
-            0x85, 0x2d, 0x18, 0xc2, 0xb2, 0x44, 0x36, 0x11, 0xa7, 0xe6, 0xd2, 0x52, 0x0d, 0x80, 0x7a, 0x36,
-            0xd7, 0xaa, 0x3a, 0x2e, 0x78, 0x4d, 0xfa, 0x27, 0xd1, 0x10, 0xfb, 0x8d, 0xe2, 0xa8, 0xc2, 0xa2,
-            0xf0, 0xf7, 0x2a, 0x1b, 0xe9, 0x09, 0xfc, 0x9d, 0xa8, 0xec, 0x7c, 0xa2, 0xa3, 0xd3, 0xf8, 0x2a,
-            0xd3, 0x93, 0xbd, 0x52, 0x8d, 0x54, 0xae, 0x33, 0xd8, 0x05, 0xb3, 0x15, 0x3a, 0xbb, 0x50, 0xc5,
-            0x5c, 0xc3, 0x22, 0x5f, 0x55, 0xef, 0x14, 0xec, 0x71, 0xae, 0x86, 0x9a, 0x97, 0x38, 0x1a, 0xc3,
-            0xb6, 0x6f, 0x7f, 0xce, 0xb4, 0x56, 0xb0, 0x62, 0x57, 0xd5, 0xb3, 0x2c, 0x4f, 0xcb, 0x9b, 0xe3,
-            0x9b, 0x19, 0x0c, 0xe2, 0x6c, 0x5a, 0x9c, 0xc1, 0x56, 0x65, 0x15, 0x02, 0xc1, 0x91, 0x9a, 0x42,
-            0xa5, 0xa2, 0xec, 0x47, 0x27, 0x93, 0xeb, 0x6d, 0x93, 0x78, 0x1a, 0xaf, 0x9d, 0x8c, 0x52, 0x9d,
-            0x6e, 0x8b, 0x24, 0x58, 0xa5, 0x61, 0x59, 0x4c, 0xa7, 0xcf, 0xd4, 0x24, 0xbd, 0xcc, 0xb0, 0x42,
-            0x06, 0x07, 0x24, 0xcd, 0xb5, 0xdb, 0xf5, 0x17, 0xc5, 0x70, 0x5e, 0x1d, 0x51, 0x21, 0x33, 0xc0,
-            0x73, 0xa5, 0x09, 0xac, 0x9e, 0xcd, 0x2b, 0x18, 0xc7, 0xdb, 0xb4, 0x4c, 0x2f, 0x6c, 0x0e, 0x8c,
-            0x21, 0x9d, 0x7e, 0xc8, 0xd4, 0xd5, 0x71, 0x99, 0x02, 0x34, 0xe3, 0xb9, 0xb3, 0xd3, 0xba, 0x50,
-            0x7a, 0x52, 0x8c, 0xaa, 0xe3, 0x49, 0xaa, 0xdf, 0x57, 0xea, 0x7d, 0x39, 0xa5, 0x8a, 0x15, 0xac,
-            0x13, 0xb4, 0x07, 0xab, 0x32, 0x82, 0x21, 0x6b, 0x05, 0xab, 0x52, 0xa9, 0xe9, 0xf8, 0x1d, 0xef,
-            0x7c, 0x75, 0x98, 0x4f, 0x6f, 0xcc, 0x56, 0x9c, 0xe7, 0x45, 0xa9, 0x8e, 0x33, 0x5c, 0x5a, 0x6e,
-            0x90, 0x07, 0x7e, 0x90, 0xeb, 0x02, 0x3b, 0x3c, 0xcc, 0x9f, 0x15, 0x70, 0x94, 0xb9, 0xb0, 0xc1,
-            0x1a, 0x47, 0x33, 0x35, 0xac, 0x68, 0xa8, 0xe6, 0xf8, 0xf1, 0xa4, 0x0f, 0xf2, 0x89, 0x2a, 0x33,
-            0x98, 0xe4, 0xd0, 0x36, 0x05, 0xa7, 0x62, 0x06, 0x23, 0x55, 0x2f, 0xd3, 0x7c, 0x84, 0xb0, 0xd3,
-            0x3f, 0x01, 0x44, 0x31, 0x82, 0x45, 0xfd, 0x76, 0xf7, 0x1f, 0x0c, 0x47, 0x5c, 0x70, 0x19, 0x9b,
-            0xf4, 0x93, 0x6f, 0xff, 0x7e, 0xda, 0xeb, 0x99, 0x2c, 0xec, 0xd2, 0xe7, 0xfc, 0xe3, 0x9f, 0x3e,
-            0x87, 0x5b, 0x57, 0x65, 0x09, 0x0b, 0x4b, 0xa5, 0x4e, 0x19, 0xce, 0xde, 0xc0, 0xdc, 0xd4, 0xe8,
-            0xb0, 0x38, 0xc3, 0x23, 0x55, 0x05, 0x07, 0xf6, 0x9d, 0xc2, 0x3f, 0xea, 0x69, 0xf5, 0xf2, 0xda,
-            0x2c, 0x02, 0x67, 0x97, 0x6a, 0x56, 0x94, 0xfa, 0x43, 0x3a, 0xcd, 0x46, 0x99, 0xbe, 0x39, 0x1c,
-            0xbf, 0x28, 0xca, 0x8b, 0xca, 0x8e, 0x6a, 0x96, 0x96, 0x15, 0x4c, 0x0b, 0x76, 0x03, 0xe1, 0xd9,
-            0xe0, 0x09, 0x38, 0x57, 0x88, 0x4e, 0xec, 0x8f, 0xf8, 0x93, 0x41, 0x8b, 0xaa, 0x24, 0x34, 0x13,
-            0x7d, 0xdb, 0xdb, 0xed, 0xfd, 0x3b, 0x5a, 0x0e, 0x7e, 0xec, 0x31, 0x3a, 0x4e, 0x3e, 0xc0, 0x4f,
-            0x83, 0x8d, 0x93, 0x17, 0x9a, 0xd2, 0x93, 0x6b, 0x85, 0x7f, 0xc7, 0xe3, 0xe4, 0x0c, 0x7f, 0x98,
-            0x75, 0x4d, 0x52, 0xfc, 0x40, 0x6c, 0x9c, 0xbc, 0xca, 0xe1, 0x17, 0xe2, 0xe0, 0x64, 0x6c, 0x7e,
-            0x00, 0xda, 0x4a, 0xae, 0xe1, 0xb7, 0xc1, 0xc5, 0xc9, 0x39, 0xfc, 0x66, 0x14, 0x97, 0x7c, 0xc2,
-            0x5a, 0x06, 0x97, 0x26, 0x3f, 0xb8, 0x74, 0xfe, 0xfe, 0x0e, 0xdb, 0xf7, 0x98, 0x34, 0xf9, 0x09,
-            0xbf, 0x2d, 0x22, 0x4d, 0x7e, 0x85, 0x2f, 0x5c, 0xd2, 0xe4, 0x4f, 0xec, 0xba, 0x86, 0x47, 0x93,
-            0x4f, 0xb9, 0x6b, 0xcc, 0x27, 0xfe, 0x89, 0x89, 0x8c, 0x47, 0x93, 0xcf, 0xfc, 0x13, 0xd1, 0x68,
-            0xf2, 0x00, 0xa7, 0x29, 0x17, 0x2c, 0x19, 0x41, 0xca, 0xa7, 0x44, 0x0d, 0xec, 0xe5, 0xb0, 0x80,
-            0x41, 0x1e, 0xf3, 0x54, 0x09, 0x22, 0x00, 0xdf, 0x1e, 0xe9, 0xf8, 0xac, 0x18, 0xdd, 0xec, 0x15,
-            0xb9, 0x4e, 0xe1, 0x84, 0xf4, 0x61, 0x5b, 0x87, 0x69, 0xfe, 0x74, 0x88, 0x8b, 0xf5, 0x0a, 0x56,
-            0x78, 0x7a, 0x04, 0xbb, 0x96, 0x9e, 0xab, 0xfe, 0xcf, 0x74, 0x23, 0x1d, 0xc3, 0x6e, 0xee, 0x4f,
-            0xd5, 0x05, 0x9c, 0xec, 0xfe, 0x91, 0x82, 0xa4, 0x29, 0x74, 0xf5, 0x81, 0x2f, 0xa4, 0x9b, 0x9c,
-            0x81, 0xe3, 0x4f, 0xd8, 0xf3, 0xb4, 0x7a, 0x6a, 0x31, 0x47, 0xbf, 0xc2, 0x83, 0xe5, 0x3e, 0xa9,
-            0x70, 0x3f, 0xa5, 0xc3, 0xc6, 0x2b, 0x59, 0xcb, 0xca, 0x95, 0xc8, 0x7b, 0x9d, 0xea, 0xe1, 0xa4,
-            0xff, 0x07, 0xa6, 0xec, 0x5f, 0xcf, 0x00, 0x9c, 0x71, 0x05, 0x3e, 0xc0, 0x24, 0xfb, 0xef, 0x72,
-            0x4c, 0x7c, 0xa9, 0xd2, 0x11, 0xec, 0x7b, 0xff, 0x82, 0xbe, 0x0e, 0xf2, 0xd9, 0x5c, 0x9b, 0xd1,
-            0x8c, 0x4c, 0x0a, 0x8c, 0x2f, 0x4f, 0xa7, 0xcf, 0x01, 0x3d, 0xf4, 0x0b, 0x6a, 0x99, 0xae, 0x02,
-            0x38, 0x40, 0xd9, 0x38, 0x33, 0x90, 0x74, 0x46, 0x45, 0x8f, 0xc5, 0xd9, 0xea, 0x57, 0x9a, 0x92,
-            0xd2, 0x12, 0xfe, 0xef, 0xef, 0xc3, 0x21, 0x87, 0x0d, 0x7b, 0x01, 0xeb, 0x40, 0x13, 0x7f, 0x0e,
-            0x67, 0x1e, 0x32, 0x0e, 0xcf, 0x3e, 0x03, 0x2e, 0xaa, 0xfa, 0x53, 0xce, 0x66, 0xf4, 0x78, 0x90,
-            0x8f, 0x8b, 0xfe, 0x51, 0x1e, 0x17, 0x7c, 0x06, 0xfa, 0xc7, 0x2a, 0x06, 0x60, 0x2f, 0x6f, 0x2c,
-            0xe2, 0x82, 0x6d, 0xec, 0x03, 0xd4, 0x57, 0x5c, 0xf8, 0xe2, 0x42, 0x8d, 0xb2, 0x54, 0x2b, 0x40,
-            0x06, 0xbf, 0xe8, 0xb8, 0x9a, 0x14, 0xf3, 0xe9, 0x68, 0x0f, 0xcf, 0xef, 0xb4, 0x3f, 0xd1, 0xf6,
-            0xb4, 0xef, 0x5f, 0x62, 0xa7, 0xa9, 0x3b, 0xfd, 0xfb, 0x78, 0xec, 0x38, 0x71, 0xac, 0x08, 0xd7,
-            0x3a, 0xd8, 0xa8, 0xfa, 0x1f, 0xf4, 0xd2, 0x6c, 0xf7, 0x48, 0x25, 0x16, 0x05, 0x11, 0x2d, 0x00,
-            0x7f, 0xe6, 0x02, 0x1f, 0xc1, 0x27, 0xae, 0x6d, 0x74, 0x6a, 0x8a, 0xbf, 0x4b, 0x46, 0xaa, 0x77,
-            0x91, 0xce, 0x3a, 0x9e, 0xae, 0xe8, 0x2e, 0x98, 0x7a, 0x20, 0x5c, 0x1b, 0x6d, 0xa9, 0xad, 0x48,
-            0x62, 0x5a, 0x4e, 0x88, 0x96, 0xdd, 0xde, 0xe7, 0x22, 0xcb, 0x3b, 0x51, 0xbc, 0x06, 0xe4, 0x86,
-            0xad, 0xbc, 0x36, 0xc2, 0xea, 0xd9, 0xb8, 0xa3, 0x92, 0x64, 0x9e, 0x33, 0x58, 0x8f, 0x6c, 0x7b,
-            0x6b, 0x2e, 0x65, 0x09, 0x43, 0x59, 0xd3, 0xc9, 0x9b, 0xf4, 0xcd, 0x00, 0xcb, 0xf6, 0xaa, 0x69,
-            0x36, 0x54, 0x9d, 0xed, 0x6f, 0xbb, 0x49, 0x12, 0x5d, 0x54, 0x51, 0x77, 0xa1, 0x13, 0x82, 0xe8,
-            0x17, 0xd3, 0x22, 0xd5, 0x2e, 0x7f, 0x37, 0x86, 0x12, 0xdd, 0xa5, 0x02, 0x14, 0xb1, 0x26, 0xab,
-            0x3d, 0xc4, 0x6a, 0x77, 0xd5, 0x7a, 0xd8, 0xed, 0x7e, 0xf3, 0x50, 0xfd, 0x7d, 0x45, 0xcd, 0x8b,
-            0xaf, 0xd7, 0xfc, 0xe6, 0x7f, 0x76, 0xa9, 0x72, 0xad, 0x5c, 0x77, 0x69, 0x26, 0x96, 0x55, 0x30,
-            0x95, 0x8e, 0xee, 0x3e, 0x71, 0x33, 0xec, 0xeb, 0xa5, 0x5b, 0x13, 0xa5, 0x98, 0x56, 0x33, 0x85,
-            0x61, 0x08, 0x74, 0x25, 0x0d, 0x55, 0x31, 0x5e, 0x33, 0x87, 0x6a, 0x63, 0x43, 0xf5, 0xe4, 0x69,
-            0x81, 0xb6, 0x7c, 0xfd, 0x4a, 0x56, 0x5f, 0x5f, 0x57, 0x3d, 0x79, 0xcc, 0x36, 0x36, 0x3a, 0x61,
-            0x02, 0x54, 0xbd, 0xbd, 0xad, 0x25, 0x45, 0xb4, 0x79, 0xd1, 0x96, 0xee, 0x8a, 0x66, 0xd3, 0x70,
-            0x54, 0x3c, 0x48, 0xa8, 0x8a, 0x3f, 0x7c, 0x05, 0x5f, 0x7e, 0x8e, 0x5b, 0xcb, 0x40, 0xa3, 0x13,
-            0x85, 0x28, 0x07, 0x06, 0x6e, 0xc6, 0x8f, 0xdb, 0xb8, 0x4e, 0xb3, 0xe0, 0xe4, 0x37, 0x70, 0x77,
-            0xc8, 0x69, 0x1e, 0x4d, 0xd2, 0x51, 0x71, 0xf5, 0xae, 0x28, 0x74, 0xd7, 0xf6, 0x27, 0x4a, 0x5a,
-            0x6a, 0x55, 0xac, 0x19, 0x0c, 0xda, 0x0d, 0x6d, 0x04, 0x37, 0x36, 0x76, 0xe2, 0x73, 0x6f, 0xc2,
-            0xa1, 0xe3, 0xd2, 0x61, 0xdb, 0xd8, 0xd6, 0x93, 0xe0, 0xab, 0x03, 0x03, 0xbe, 0x80, 0x63, 0x40,
-            0x1b, 0xd2, 0xed, 0x63, 0xab, 0xbe, 0x95, 0x3f, 0xb8, 0x95, 0xab, 0x49, 0x36, 0x85, 0x39, 0x6f,
-            0x6c, 0xac, 0xe3, 0x96, 0x76, 0x17, 0x2a, 0x99, 0x8b, 0xad, 0x55, 0xb7, 0xb7, 0x78, 0xcd, 0xf8,
-            0x5a, 0x05, 0xd6, 0x8a, 0x73, 0xbb, 0x14, 0x70, 0x79, 0x74, 0xf0, 0xd3, 0x1c, 0xa7, 0x82, 0x3e,
-            0x23, 0xa6, 0x48, 0x32, 0xbe, 0x98, 0xe1, 0x7c, 0x5c, 0x02, 0x2b, 0x91, 0xb9, 0x2c, 0x9f, 0x8e,
-            0xc0, 0xb8, 0x9e, 0x24, 0x9a, 0xce, 0x0c, 0xdc, 0x31, 0x44, 0x00, 0xf7, 0x9a, 0xf7, 0x3a, 0xe5,
-            0x67, 0xb0, 0xd7, 0x59, 0x02, 0x10, 0xfb, 0x4d, 0x74, 0x7b, 0x9b, 0xf5, 0xaa, 0xd9, 0x34, 0xd3,
-            0x9d, 0x08, 0x8e, 0x5f, 0x0f, 0x30, 0xb4, 0xba, 0x3e, 0x1c, 0x77, 0xf2, 0xee, 0xe3, 0x64, 0xb7,
-            0xeb, 0x16, 0xa6, 0x64, 0xa0, 0xb5, 0xbc, 0x00, 0x4e, 0x63, 0x09, 0xed, 0x14, 0xd0, 0x4e, 0x61,
-            0xdb, 0x29, 0xbe, 0xde, 0x4e, 0x34, 0x07, 0x52, 0x42, 0x47, 0xcb, 0xa5, 0x6b, 0xd6, 0x2d, 0x46,
-            0xae, 0x68, 0xf2, 0x0b, 0x3c, 0xcf, 0x65, 0x82, 0x3d, 0x0c, 0xfe, 0x80, 0x94, 0x26, 0x2e, 0x59,
-            0x5f, 0xef, 0x94, 0x49, 0x01, 0x59, 0x70, 0xae, 0x54, 0x17, 0xaa, 0x74, 0x97, 0x34, 0xfb, 0x12,
-            0x66, 0x6f, 0xda, 0x17, 0xc3, 0xf6, 0x1d, 0x4c, 0xee, 0x75, 0x74, 0x2e, 0x10, 0xa5, 0xa9, 0x2a,
-            0x38, 0x35, 0x4f, 0x25, 0xb8, 0xee, 0x3c, 0xea, 0x9c, 0xa4, 0xdb, 0x7f, 0x9e, 0x9e, 0xfc, 0xf6,
-            0x71, 0xe7, 0xe3, 0xee, 0xe3, 0x8f, 0xd7, 0xdf, 0xee, 0x7e, 0xd4, 0x1f, 0xcb, 0x8f, 0xf9, 0xc7,
-            0xf1, 0xe9, 0x37, 0xdd, 0x9d, 0xcc, 0x5d, 0x95, 0xba, 0xa7, 0xae, 0xd5, 0x10, 0xaa, 0xe2, 0xe0,
-            0x72, 0xd7, 0x71, 0x7e, 0xf2, 0xf0, 0x14, 0x6e, 0xf3, 0x57, 0xc5, 0x95, 0x2a, 0xf7, 0xd2, 0x0a,
-            0xc1, 0x48, 0x2c, 0x6d, 0x14, 0x89, 0x11, 0xbf, 0x32, 0x18, 0x30, 0x22, 0x4c, 0x81, 0x0c, 0xc7,
-            0xfb, 0xbc, 0x4a, 0xc7, 0x0a, 0x08, 0xd1, 0xb5, 0xe7, 0x06, 0x92, 0x5d, 0xbb, 0x36, 0xa1, 0x57,
-            0x2b, 0x8c, 0x00, 0x68, 0xc7, 0x9e, 0xab, 0xab, 0xb5, 0xe7, 0x87, 0xaf, 0xdf, 0x62, 0x89, 0xd2,
-            0x1d, 0x15, 0xae, 0xf1, 0xa2, 0x2c, 0x2e, 0x8e, 0xe0, 0x94, 0xe7, 0xe7, 0x78, 0x68, 0xb5, 0xba,
-            0xd6, 0x3b, 0xc0, 0x16, 0x4c, 0x23, 0xb1, 0x0e, 0x6f, 0x24, 0x94, 0xeb, 0xde, 0x10, 0xfe, 0x8e,
-            0xf0, 0x68, 0x54, 0xbd, 0xa9, 0xca, 0xcf, 0xf5, 0xe4, 0xf1, 0x2e, 0x80, 0x7c, 0x0f, 0xb8, 0x08,
-            0x95, 0x8f, 0x82, 0xfc, 0x93, 0xdd, 0xd3, 0xae, 0x98, 0x57, 0x29, 0xd7, 0x13, 0x0f, 0x52, 0x6f,
-            0x58, 0x2a, 0xb8, 0xc3, 0xcc, 0x36, 0x74, 0xa2, 0x8a, 0xd8, 0x0a, 0x04, 0x6a, 0x18, 0x7e, 0xcf,
-            0x73, 0x10, 0x01, 0x34, 0xe8, 0x5e, 0x25, 0xd1, 0x9c, 0xea, 0xe5, 0xe9, 0x05, 0x50, 0x94, 0xcc,
-            0xa6, 0x22, 0x4c, 0xe8, 0x1e, 0xce, 0x02, 0xe9, 0x12, 0x68, 0x14, 0xd0, 0x8c, 0xf8, 0x82, 0xbc,
-            0xb4, 0xba, 0xc9, 0x87, 0x09, 0x51, 0x89, 0x03, 0x79, 0x62, 0x1a, 0x8c, 0x0d, 0xf6, 0x94, 0xe3,
-            0x8f, 0x64, 0x75, 0x99, 0x65, 0x13, 0xed, 0x64, 0x1e, 0x62, 0xd7, 0x3c, 0x58, 0xb9, 0xa9, 0x11,
-            0xb2, 0xd5, 0xc0, 0x9e, 0xe0, 0xe9, 0xa1, 0xd5, 0xfe, 0x9c, 0x5e, 0xa6, 0x26, 0x17, 0xb1, 0xae,
-            0xcd, 0xbb, 0x28, 0x46, 0x73, 0xe0, 0x91, 0x64, 0x92, 0xdc, 0x93, 0x03, 0xec, 0xe6, 0x69, 0x59,
-            0xa6, 0x37, 0xbd, 0x31, 0xec, 0x20, 0x34, 0x1a, 0x10, 0x0b, 0x40, 0xe1, 0xf9, 0x3e, 0xbb, 0xbd,
-            0x31, 0x5c, 0xfb, 0x40, 0xf4, 0xc3, 0x9d, 0xfa, 0x98, 0xd0, 0x00, 0x61, 0x29, 0xbb, 0x13, 0xb8,
-            0x2d, 0x0e, 0x7a, 0x03, 0xa4, 0xaa, 0xcb, 0x9b, 0x45, 0x0e, 0xb3, 0x06, 0xa8, 0xd1, 0xcf, 0x14,
-            0x34, 0x82, 0x67, 0x15, 0xe1, 0x0a, 0x67, 0x85, 0x03, 0x78, 0x89, 0x50, 0x06, 0xb7, 0x15, 0x90,
-            0xf0, 0x37, 0x00, 0x02, 0x4c, 0x6f, 0x02, 0x64, 0x2f, 0x97, 0x62, 0xa8, 0xcf, 0x43, 0xac, 0x0f,
-            0x64, 0xfb, 0x34, 0x85, 0x33, 0xbc, 0xf3, 0x68, 0x02, 0x24, 0x58, 0xe7, 0x63, 0x75, 0xf2, 0xdb,
-            0x63, 0x38, 0x41, 0x4f, 0x1e, 0x9f, 0x7c, 0xac, 0x3e, 0x1e, 0x9d, 0x7e, 0xf3, 0xe4, 0xd1, 0xc7,
-            0x1d, 0xcc, 0x79, 0xbc, 0x93, 0xc5, 0x30, 0x65, 0x37, 0xb2, 0xa7, 0x70, 0x36, 0x07, 0x84, 0x25,
-            0xe8, 0x60, 0xe1, 0x82, 0x30, 0xa0, 0x2e, 0x4a, 0x06, 0x70, 0x73, 0x10, 0x2c, 0xb1, 0x65, 0x2a,
-            0x66, 0x09, 0x1e, 0xa7, 0xc1, 0x9b, 0x4e, 0x19, 0x67, 0x3d, 0x24, 0x58, 0x41, 0xb2, 0xd1, 0xd3,
-            0xc8, 0x34, 0x25, 0x19, 0xff, 0x75, 0x97, 0x3a, 0xb5, 0x89, 0x45, 0xee, 0xd3, 0xa6, 0xfe, 0x7a,
-            0x9b, 0x0b, 0x5f, 0x7a, 0xf3, 0x11, 0x16, 0x7b, 0xfc, 0x48, 0xab, 0x0b, 0x98, 0xbd, 0x56, 0x6b,
-            0xc4, 0x09, 0x27, 0x70, 0xa2, 0x99, 0xca, 0xdc, 0x26, 0x56, 0xfc, 0xaa, 0xc4, 0x43, 0x54, 0x46,
-            0x8f, 0x37, 0xb7, 0xf4, 0x56, 0xf4, 0x68, 0xc7, 0x96, 0x7e, 0xfc, 0x68, 0x87, 0xaa, 0xa3, 0x54,
-            0x06, 0x7a, 0x08, 0x76, 0xba, 0x13, 0xd9, 0x52, 0x80, 0x7d, 0x87, 0x06, 0xcc, 0x6b, 0xa3, 0xa1,
-            0xcb, 0xa3, 0x48, 0xca, 0x46, 0x4d, 0xcc, 0xe4, 0x3b, 0x04, 0x30, 0x7a, 0x21, 0xb6, 0x1e, 0x56,
-            0xa2, 0xec, 0x2e, 0x0a, 0xb7, 0xa3, 0xae, 0xc5, 0xa2, 0x47, 0x52, 0x90, 0x63, 0x80, 0x5c, 0xba,
-            0x09, 0xca, 0xf0, 0xde, 0xa9, 0xc9, 0x0c, 0xba, 0x8b, 0x03, 0x28, 0x61, 0x10, 0xdd, 0x1d, 0x10,
-            0x2a, 0x01, 0xd4, 0x83, 0x51, 0xb7, 0xed, 0xbe, 0x28, 0x95, 0xa5, 0x0f, 0x01, 0xe9, 0x74, 0x24,
-            0x7a, 0xd1, 0x01, 0xa2, 0x67, 0x1a, 0x1b, 0xb9, 0x37, 0x5d, 0xe0, 0x01, 0x02, 0xdc, 0xcb, 0x68,
-            0xae, 0x07, 0xac, 0xc9, 0x14, 0x6a, 0xe3, 0x66, 0x9f, 0x14, 0x54, 0x6a, 0x2d, 0xc2, 0xf5, 0x06,
-            0x8a, 0xd4, 0xb5, 0xf5, 0x56, 0x9c, 0x62, 0xac, 0x0d, 0x97, 0x05, 0x1d, 0x41, 0x5b, 0x40, 0x14,
-            0xfd, 0x22, 0x8b, 0x22, 0x0e, 0xe5, 0x9e, 0xe5, 0x61, 0x2d, 0x94, 0x3c, 0x02, 0x56, 0xce, 0x63,
-            0x76, 0x1e, 0xe9, 0xa4, 0x88, 0x00, 0x1b, 0x4e, 0xdf, 0x89, 0x3e, 0x25, 0x42, 0x08, 0xee, 0x0d,
-            0xfe, 0x4a, 0x16, 0x6e, 0x11, 0x72, 0xdf, 0xe0, 0xeb, 0x8e, 0x10, 0xdc, 0x9d, 0x50, 0x15, 0x48,
-            0x80, 0x45, 0xec, 0x60, 0x3b, 0x2a, 0xd9, 0x1d, 0xa8, 0x47, 0xda, 0x60, 0xe7, 0x81, 0xda, 0xda,
-            0x82, 0xd6, 0x7a, 0xb3, 0x79, 0x35, 0xe9, 0xe8, 0x13, 0x75, 0xda, 0x6d, 0x6b, 0x31, 0x33, 0xd7,
-            0xf0, 0x3d, 0x5a, 0xb2, 0x8d, 0xf8, 0xca, 0x2f, 0xc2, 0x13, 0x0e, 0xd4, 0xd3, 0xb3, 0x02, 0xe8,
-            0x58, 0x12, 0x34, 0x65, 0x00, 0x51, 0x20, 0xb3, 0xd1, 0x9d, 0xae, 0xb8, 0x21, 0x75, 0x31, 0x1b,
-            0x58, 0xe2, 0x47, 0xc3, 0x09, 0xd2, 0xba, 0xb8, 0x70, 0x02, 0xc7, 0x47, 0x57, 0x40, 0x44, 0x14,
-            0x57, 0x0c, 0x68, 0x2f, 0x49, 0x32, 0xb4, 0xb1, 0x51, 0x02, 0x39, 0x21, 0xe8, 0x59, 0x15, 0x60,
-            0xd9, 0x15, 0xe4, 0x1a, 0x8a, 0x17, 0x70, 0x9b, 0x9b, 0xd4, 0xdf, 0xb3, 0xa0, 0x3a, 0x80, 0xc5,
-            0x05, 0x5c, 0x46, 0x4c, 0xc5, 0xec, 0x7c, 0xac, 0xb6, 0x76, 0xc4, 0xde, 0x4d, 0x0d, 0xe9, 0x8d,
-            0x4b, 0x62, 0x26, 0x00, 0x24, 0xc4, 0x1a, 0xd3, 0x5b, 0x1a, 0x89, 0xe4, 0xc3, 0xab, 0xfc, 0x6d,
-            0x59, 0xc0, 0xb9, 0xd5, 0x37, 0x70, 0xdf, 0x03, 0x54, 0x9e, 0xe4, 0xa7, 0x89, 0x86, 0xff, 0xdc,
-            0x3a, 0x2b, 0xdf, 0xdc, 0x25, 0x5d, 0x61, 0x80, 0x57, 0x4d, 0xd6, 0xf7, 0x47, 0x87, 0x6f, 0xf8,
-            0x22, 0xee, 0xd4, 0x11, 0xeb, 0x20, 0xa0, 0xba, 0x5c, 0x0b, 0x3f, 0x77, 0xec, 0x5a, 0x2b, 0x06,
-            0x25, 0xe0, 0xbc, 0x89, 0xb9, 0x35, 0xfc, 0xf6, 0x31, 0xca, 0x07, 0x09, 0x75, 0x87, 0xe9, 0x78,
-            0x6d, 0x1e, 0x00, 0xae, 0x80, 0xe9, 0x40, 0xdb, 0xb5, 0x3c, 0x3e, 0x72, 0x9c, 0xed, 0x3a, 0xa6,
-            0x05, 0x74, 0x43, 0x32, 0x89, 0x2c, 0x5f, 0xf1, 0xc3, 0x79, 0x2f, 0xf7, 0x1e, 0x71, 0xe6, 0xfb,
-            0x77, 0xaf, 0xf0, 0x14, 0x4c, 0xb4, 0x9e, 0xf5, 0x77, 0x76, 0xae, 0x19, 0xbd, 0x68, 0x24, 0x8a,
-            0x91, 0xe2, 0xd0, 0x13, 0xbc, 0xae, 0xb7, 0xf0, 0x12, 0x4f, 0xcb, 0xe1, 0x64, 0xc9, 0xe4, 0x6b,
-            0xb4, 0x13, 0x61, 0x01, 0x71, 0x39, 0x7c, 0xdc, 0xd9, 0x7a, 0xb0, 0x83, 0xf8, 0xbf, 0x65, 0x0d,
-            0xe5, 0xe6, 0x1f, 0x02, 0x38, 0x22, 0x25, 0x81, 0xf8, 0x31, 0x16, 0x52, 0x76, 0x5b, 0x0b, 0xa8,
-            0x02, 0x5c, 0x58, 0xb1, 0xa1, 0x1f, 0xfc, 0xd9, 0xc1, 0xab, 0x1d, 0x4a, 0xf3, 0x2a, 0x02, 0x43,
-            0x06, 0xf2, 0xd3, 0x80, 0xd2, 0x80, 0x5b, 0x75, 0xa4, 0x40, 0xba, 0x31, 0xed, 0xa9, 0xa9, 0x46,
-            0xd2, 0xa2, 0x39, 0x96, 0xcf, 0xd0, 0x17, 0x09, 0x52, 0x50, 0x08, 0x24, 0x05, 0xeb, 0xe6, 0x30,
-            0x61, 0x47, 0xc5, 0xd4, 0x2c, 0x11, 0xfc, 0xc0, 0xa2, 0x78, 0x89, 0x42, 0xb6, 0x3c, 0x41, 0x0f,
-            0x64, 0x33, 0x21, 0xb7, 0x30, 0x66, 0xf8, 0xc3, 0x45, 0x34, 0x88, 0x08, 0x09, 0xde, 0x8a, 0x70,
-            0x59, 0x24, 0xa0, 0x38, 0xc4, 0xed, 0x3a, 0x20, 0x2f, 0xa1, 0x11, 0x5c, 0x25, 0xbc, 0xbb, 0x7d,
-            0xc3, 0xd7, 0xff, 0x49, 0xc3, 0x88, 0xb6, 0x6b, 0x6d, 0x5f, 0xb7, 0xb4, 0x7d, 0xe6, 0xb7, 0x80,
-            0x4f, 0xb3, 0xcf, 0xfa, 0xc4, 0xdd, 0xaa, 0xe4, 0xca, 0xd0, 0xc8, 0xf0, 0x71, 0x86, 0xc7, 0x0f,
-            0xa4, 0x26, 0x2c, 0xe7, 0xed, 0x88, 0x7d, 0xfc, 0x84, 0x85, 0x14, 0x2f, 0x49, 0x6c, 0x3b, 0x46,
-            0xee, 0xca, 0x4a, 0xca, 0x90, 0xd8, 0xec, 0x04, 0x7d, 0x0f, 0x03, 0xe4, 0xd0, 0x42, 0xef, 0x3f,
-            0x61, 0xe1, 0xa7, 0xaf, 0xf1, 0xe7, 0xaa, 0x0a, 0x48, 0x4e, 0xaf, 0xaa, 0xf4, 0xfd, 0x8a, 0x2b,
-            0xc2, 0x2c, 0x60, 0xa3, 0xfc, 0xec, 0x2b, 0xa3, 0x02, 0x4a, 0x4f, 0xa6, 0x5a, 0xd2, 0x63, 0x45,
-            0xb2, 0xa5, 0x48, 0x1a, 0xdd, 0xfc, 0x60, 0x81, 0x4f, 0x25, 0xb0, 0x10, 0xb8, 0xc6, 0xb4, 0xc8,
-            0xeb, 0xae, 0xf3, 0x25, 0xb3, 0x25, 0xab, 0x97, 0x9c, 0x5a, 0xf0, 0x8b, 0x9e, 0x9b, 0x45, 0x57,
-            0x3d, 0xa2, 0x59, 0x5e, 0x81, 0x50, 0x16, 0x19, 0x26, 0xf7, 0x81, 0xf2, 0x4b, 0x04, 0x09, 0x3f,
-            0x84, 0xef, 0xec, 0x10, 0x98, 0xa7, 0x0b, 0x86, 0x51, 0xde, 0x7b, 0x18, 0xdf, 0x01, 0x75, 0xa5,
-            0x91, 0xe0, 0x09, 0x87, 0x81, 0x34, 0x87, 0xef, 0x1c, 0x5a, 0x13, 0x23, 0x31, 0x84, 0x83, 0x66,
-            0xbe, 0x50, 0x64, 0xf0, 0xfd, 0x05, 0xbb, 0xb3, 0x8b, 0x15, 0xb8, 0x98, 0x90, 0x6d, 0xb0, 0x5a,
-            0x02, 0x0f, 0xa4, 0x9f, 0xc4, 0x4f, 0x01, 0x98, 0xca, 0xf9, 0xb2, 0x48, 0x36, 0xe0, 0x14, 0x7f,
-            0x0d, 0x61, 0x1a, 0xb9, 0x92, 0x40, 0xb8, 0xc1, 0x3c, 0x11, 0x24, 0x04, 0xf8, 0x85, 0xd6, 0x09,
-            0xd1, 0xca, 0x0f, 0x1d, 0xe6, 0x69, 0x65, 0x93, 0xe7, 0xb6, 0x49, 0xb9, 0x7c, 0xf2, 0xd6, 0x32,
-            0xd2, 0x64, 0x1c, 0x87, 0xbc, 0x28, 0xfc, 0xc5, 0x55, 0x93, 0x70, 0x54, 0xf3, 0x33, 0x06, 0x4d,
-            0x90, 0x4a, 0xd9, 0x15, 0xc1, 0xdb, 0x51, 0x5c, 0x8b, 0xbf, 0xac, 0xac, 0xa2, 0x4c, 0x85, 0xed,
-            0x15, 0x35, 0x67, 0x2a, 0x24, 0x01, 0xf8, 0x4a, 0xc5, 0x21, 0x4f, 0x51, 0x62, 0xf1, 0x08, 0x19,
-            0x9f, 0x5f, 0xf0, 0xd7, 0x0e, 0x10, 0xb1, 0xfe, 0xd8, 0x88, 0x1e, 0x1e, 0xba, 0x41, 0x81, 0x88,
-            0x2e, 0xc0, 0x2f, 0x5a, 0xec, 0xca, 0x05, 0xb4, 0x51, 0x1a, 0xd4, 0x5a, 0x3a, 0x61, 0x43, 0xc4,
-            0x5a, 0x16, 0x90, 0x3f, 0x98, 0x2d, 0xe6, 0x8a, 0x54, 0xd8, 0x48, 0xe2, 0xfe, 0x05, 0xab, 0x5b,
-            0x22, 0x7f, 0xa8, 0x61, 0x8f, 0xb4, 0x97, 0xb5, 0x00, 0xf1, 0xb4, 0x60, 0x51, 0xe2, 0xae, 0xa1,
-            0xc1, 0x76, 0x07, 0x21, 0xf5, 0x53, 0x06, 0xd4, 0x0f, 0xd7, 0x9b, 0x26, 0x25, 0xd0, 0x40, 0x34,
-            0x3d, 0x3c, 0xf2, 0x71, 0xb4, 0xb1, 0xa1, 0xb9, 0xeb, 0x82, 0xe9, 0xac, 0x52, 0xcc, 0x2c, 0x8f,
-            0x71, 0xf7, 0x80, 0x9c, 0xdb, 0x7a, 0x88, 0xdd, 0xea, 0x2c, 0x87, 0x6b, 0xd5, 0x56, 0x7d, 0x84,
-            0xa2, 0xc3, 0xad, 0x2d, 0xc7, 0x83, 0x50, 0xe2, 0x0e, 0xb4, 0xe7, 0x3b, 0xde, 0x7e, 0x08, 0xe4,
-            0xcf, 0x09, 0xd4, 0x3e, 0xc5, 0xbc, 0xc7, 0x58, 0x61, 0x7b, 0x9b, 0x88, 0xef, 0xdc, 0x95, 0x69,
-            0xef, 0x18, 0x29, 0x68, 0xcb, 0x83, 0x9c, 0x58, 0x71, 0x6d, 0x85, 0x3f, 0x99, 0x97, 0x2f, 0x04,
-            0x03, 0x6f, 0xc9, 0xb1, 0x19, 0x26, 0x57, 0x93, 0x6c, 0x0c, 0x14, 0x1b, 0xf3, 0x5b, 0x6a, 0x10,
-            0x2e, 0xb6, 0x01, 0x3c, 0xb7, 0xda, 0x2a, 0x39, 0x47, 0xf8, 0xd5, 0xdd, 0x18, 0xea, 0xda, 0xf5,
-            0xfe, 0x77, 0x57, 0xc8, 0x59, 0x45, 0x65, 0x54, 0x05, 0x88, 0x9a, 0xe3, 0xce, 0xac, 0x56, 0xf1,
-            0x9f, 0x41, 0x45, 0x9c, 0x71, 0x0e, 0xbc, 0x06, 0xf0, 0xc1, 0xee, 0xb7, 0x39, 0x53, 0x47, 0xd9,
-            0xd9, 0x94, 0x6f, 0x2a, 0x3a, 0x23, 0xba, 0xdb, 0x6b, 0x66, 0xb6, 0x8d, 0x00, 0x4b, 0xc9, 0xb1,
-            0x23, 0xe1, 0x1b, 0xf6, 0x1f, 0xaf, 0xaf, 0xe7, 0xb5, 0x31, 0x80, 0x02, 0x01, 0x74, 0x81, 0xf3,
-            0xca, 0x8e, 0xc3, 0x7e, 0xaf, 0x1c, 0x4b, 0x7b, 0x81, 0xb6, 0xf1, 0xd8, 0x92, 0x62, 0x4c, 0x17,
-            0xb5, 0x31, 0xfd, 0x6f, 0xeb, 0x98, 0x2c, 0x59, 0x4b, 0xbd, 0x3a, 0x1a, 0x37, 0x28, 0xc2, 0x77,
-            0x2f, 0x15, 0x30, 0xd7, 0x70, 0x90, 0x6d, 0x78, 0x5d, 0x5f, 0x9b, 0xc8, 0xa8, 0xb0, 0x4c, 0x09,
-            0x84, 0x35, 0x95, 0xb9, 0x81, 0x31, 0x35, 0x07, 0x31, 0x21, 0x63, 0x01, 0x22, 0xee, 0x24, 0x15,
-            0xde, 0xed, 0x61, 0x06, 0x1f, 0xe3, 0xca, 0x40, 0x66, 0x77, 0xc9, 0x18, 0x2c, 0xe3, 0x6f, 0xbc,
-            0xb3, 0x21, 0xa1, 0x6a, 0xc0, 0xa0, 0x4a, 0x2a, 0xab, 0x18, 0x70, 0xec, 0xff, 0x30, 0x99, 0x75,
-            0xec, 0x00, 0x00, 0xad, 0x70, 0x0b, 0xbd, 0x5e, 0xef, 0x75, 0x67, 0xd8, 0xa4, 0x4f, 0x14, 0x82,
-            0x90, 0x95, 0xab, 0x2f, 0x91, 0xf7, 0x3d, 0x57, 0x9e, 0x36, 0x63, 0xe2, 0xcb, 0xc3, 0x3b, 0xb5,
-            0x0b, 0xad, 0xb6, 0xb5, 0x73, 0x0f, 0x54, 0x50, 0x38, 0x54, 0x50, 0xf4, 0x90, 0xf5, 0x00, 0xb4,
-            0x6f, 0xef, 0xe8, 0xb7, 0x05, 0xeb, 0x7b, 0x01, 0x1e, 0x60, 0xa9, 0x70, 0x5d, 0x7a, 0xcf, 0x0f,
-            0xf7, 0xde, 0xbf, 0xde, 0x7f, 0x73, 0xfc, 0xe9, 0xed, 0xe1, 0xd1, 0xc1, 0xf1, 0xc1, 0xe1, 0x9b,
-            0x4f, 0x6f, 0xdf, 0xed, 0xef, 0xed, 0x3f, 0x3f, 0x78, 0xf3, 0x9d, 0x43, 0x5b, 0x05, 0x5c, 0x43,
-            0xc4, 0xb1, 0x5f, 0xfc, 0xf7, 0xa3, 0xf6, 0x38, 0x64, 0xa0, 0x1e, 0xe3, 0x1c, 0xb6, 0xb7, 0xff,
-            0xaf, 0x06, 0xfe, 0xe2, 0xf0, 0xd5, 0xab, 0xc3, 0x9f, 0x1a, 0x03, 0xf7, 0xc2, 0x7e, 0x75, 0x2f,
-            0xfa, 0xf2, 0x82, 0x4a, 0x81, 0xa4, 0x30, 0xc0, 0xf9, 0x17, 0x82, 0xaa, 0x57, 0x94, 0xeb, 0xef,
-            0x80, 0xab, 0x46, 0xbb, 0x49, 0x4b, 0xbb, 0x8c, 0x59, 0x6e, 0x6f, 0x2d, 0x68, 0x23, 0x7d, 0x2a,
-            0x7b, 0x90, 0x3c, 0xcc, 0x8d, 0x62, 0x8a, 0x25, 0x66, 0x69, 0xc6, 0x5b, 0xa8, 0x68, 0xdb, 0x59,
-            0x68, 0xd6, 0xe4, 0x89, 0xe1, 0x90, 0xfe, 0x0c, 0xa9, 0xbf, 0x78, 0x0a, 0xe4, 0x80, 0x02, 0x26,
-            0xb5, 0xaf, 0xe3, 0x62, 0xc6, 0x9a, 0xfd, 0x7c, 0x29, 0x7b, 0xb1, 0xb5, 0xf1, 0x02, 0x77, 0x15,
-            0xb5, 0xa8, 0x98, 0xbb, 0x8a, 0xa5, 0x24, 0x3e, 0xae, 0x89, 0x1b, 0x87, 0x9b, 0xae, 0x00, 0x2a,
-            0x21, 0x97, 0x54, 0x91, 0x3d, 0x22, 0x37, 0xbe, 0x04, 0x10, 0x27, 0xdc, 0x0d, 0x52, 0x62, 0xa4,
-            0xdd, 0x7b, 0x65, 0x9a, 0x87, 0x6b, 0x9b, 0x3a, 0x05, 0xe9, 0xa8, 0xed, 0x11, 0x7e, 0x9a, 0x1e,
-            0x91, 0xf0, 0xb0, 0xad, 0xbd, 0x85, 0xbb, 0xc2, 0x31, 0x37, 0x4f, 0xf2, 0xbe, 0x90, 0xb7, 0x9c,
-            0x99, 0x8e, 0xbe, 0x36, 0x10, 0x31, 0x0c, 0xa3, 0x76, 0xfe, 0xca, 0x48, 0x04, 0x3f, 0x85, 0xdd,
-            0x53, 0xaf, 0xdc, 0x28, 0xe8, 0xc5, 0xdb, 0xa4, 0xc3, 0x40, 0x1f, 0xa2, 0x1e, 0x52, 0xa8, 0x0a,
-            0xaf, 0x8c, 0xd0, 0xc2, 0x8e, 0xc5, 0xe8, 0x12, 0x0c, 0xa5, 0xc4, 0x3a, 0x44, 0x90, 0xb2, 0x82,
-            0xe6, 0xd9, 0xc1, 0xc5, 0xc9, 0x11, 0x97, 0x39, 0x95, 0x12, 0xba, 0x32, 0xb9, 0x20, 0xc1, 0xa6,
-            0xa3, 0x0a, 0x76, 0x3a, 0xbf, 0xdd, 0xc6, 0x5d, 0x90, 0x4d, 0x7e, 0xd3, 0x35, 0x9a, 0x16, 0xfa,
-            0xdd, 0x79, 0x00, 0xa9, 0x3b, 0x20, 0x50, 0xae, 0xb4, 0xe1, 0x5d, 0x8a, 0xae, 0x13, 0xf2, 0x01,
-            0x9e, 0x6e, 0x57, 0x5c, 0x10, 0xdc, 0x03, 0xcd, 0x5c, 0x75, 0xac, 0xe6, 0x62, 0xc9, 0xd4, 0x5c,
-            0x86, 0xc4, 0xa8, 0xc5, 0x64, 0x30, 0x97, 0x8c, 0x94, 0x1a, 0x24, 0x55, 0x0b, 0x28, 0xd6, 0x97,
-            0x9d, 0xcd, 0xe3, 0x09, 0xd8, 0x8c, 0x99, 0x43, 0xbe, 0x16, 0x6d, 0x82, 0x02, 0x75, 0x33, 0x5a,
-            0x83, 0x15, 0xd8, 0xdc, 0xca, 0xb7, 0xa2, 0x35, 0xee, 0x47, 0x8d, 0xd6, 0xf2, 0x62, 0xcd, 0x48,
-            0x9c, 0xd7, 0x9d, 0x05, 0xd7, 0xc9, 0xa5, 0x0a, 0xcf, 0x56, 0x19, 0xd0, 0xb9, 0x47, 0xa1, 0x6a,
-            0x91, 0x66, 0xa1, 0xda, 0x66, 0x91, 0x3a, 0x22, 0x75, 0x9d, 0x49, 0x72, 0xa9, 0x09, 0xdc, 0x57,
-            0xa1, 0x18, 0x80, 0x24, 0x00, 0xd7, 0xdb, 0x0c, 0x10, 0x4e, 0x04, 0x80, 0xff, 0x37, 0x76, 0x84,
-            0x47, 0x20, 0x4b, 0x07, 0xa3, 0x35, 0x68, 0x64, 0x29, 0xf7, 0x2b, 0x4f, 0x48, 0xa2, 0x46, 0x72,
-            0x60, 0x38, 0x94, 0x05, 0x9a, 0x8e, 0x78, 0xa2, 0xd2, 0x9e, 0xd4, 0xfa, 0x71, 0xf7, 0xa3, 0xdd,
-            0x93, 0x1c, 0xa2, 0x97, 0x5d, 0x36, 0x2c, 0x96, 0x7a, 0xc6, 0x7a, 0xab, 0x22, 0x31, 0xb7, 0xad,
-            0x7d, 0x68, 0x45, 0x65, 0xaa, 0x23, 0x04, 0xf0, 0x5a, 0xd4, 0xef, 0x06, 0xeb, 0x47, 0xf2, 0xbc,
-            0x50, 0x9b, 0xca, 0x4a, 0x0b, 0xa0, 0x89, 0xf7, 0xdc, 0x6f, 0x54, 0x37, 0xd4, 0x19, 0x13, 0x93,
-            0xb5, 0x5c, 0x12, 0x4f, 0x91, 0xaf, 0xd2, 0x88, 0x40, 0x07, 0x61, 0x3b, 0x77, 0x2a, 0x48, 0xa4,
-            0x2c, 0xe4, 0x25, 0x0b, 0xf4, 0xdd, 0xb2, 0x7e, 0x9f, 0x37, 0x2f, 0xbd, 0xbc, 0xe5, 0xd2, 0x03,
-            0xa6, 0x0c, 0xef, 0x0e, 0x14, 0x32, 0x31, 0x31, 0x53, 0x1d, 0xb0, 0x6a, 0x04, 0x0c, 0x17, 0x04,
-            0xf2, 0x64, 0x09, 0x52, 0x4d, 0x5d, 0xe0, 0x74, 0x26, 0x08, 0x09, 0x70, 0xa6, 0x8d, 0x49, 0x9d,
-            0x1f, 0xd4, 0x31, 0xee, 0x78, 0x11, 0x67, 0x08, 0x95, 0xa0, 0x27, 0xba, 0xbd, 0xc5, 0x1d, 0x35,
-            0xc4, 0x79, 0xf4, 0xb7, 0x68, 0x6b, 0xef, 0xe8, 0xa8, 0xa7, 0xaa, 0x61, 0x8a, 0x3c, 0x07, 0x10,
-            0xab, 0x71, 0x94, 0x8d, 0x22, 0x43, 0xaa, 0x56, 0xb2, 0xc5, 0x81, 0x43, 0x00, 0x30, 0x0a, 0x00,
-            0x37, 0xa1, 0xbc, 0x77, 0xc4, 0x57, 0x3f, 0xea, 0x22, 0xe1, 0x51, 0x25, 0x21, 0x7f, 0x14, 0x96,
-            0x20, 0xe2, 0x3d, 0x60, 0x86, 0x64, 0xee, 0xd6, 0x43, 0x03, 0xb0, 0xd0, 0xc8, 0xb2, 0x68, 0x32,
-            0x97, 0x13, 0x36, 0xb1, 0xdb, 0x06, 0xbb, 0x0e, 0x38, 0x08, 0x2d, 0x05, 0xac, 0x59, 0x84, 0x28,
-            0x25, 0xd1, 0x12, 0xf0, 0x8c, 0x28, 0x72, 0x33, 0x3c, 0xad, 0x25, 0xf7, 0x01, 0x1e, 0xca, 0x00,
-            0x08, 0x88, 0x89, 0x71, 0x22, 0xd6, 0x02, 0xd9, 0xc3, 0x5c, 0x11, 0x2d, 0x46, 0x7c, 0xcf, 0x20,
-            0xd0, 0xb8, 0xd5, 0xa5, 0x08, 0x1d, 0xd4, 0x9a, 0xb1, 0x02, 0x8f, 0x05, 0x2a, 0x8c, 0x44, 0xd7,
-            0x01, 0x3e, 0xaa, 0x98, 0x60, 0x0a, 0x28, 0x8e, 0xdc, 0x2a, 0x14, 0xcb, 0x64, 0xc1, 0x06, 0x27,
-            0x47, 0xd6, 0xd6, 0x2b, 0x36, 0xf7, 0x1c, 0x20, 0x0e, 0x6b, 0xea, 0x02, 0xd6, 0x24, 0xd8, 0x42,
-            0xca, 0x87, 0x1b, 0x05, 0x6c, 0x30, 0x35, 0x56, 0x22, 0x61, 0x35, 0xb0, 0x6e, 0xec, 0x1a, 0x45,
-            0xfe, 0x00, 0xc9, 0x14, 0x6e, 0x80, 0xe7, 0xe8, 0x1b, 0xef, 0x2e, 0xfe, 0x20, 0x76, 0xfe, 0x01,
-            0x8d, 0x23, 0xc6, 0x4b, 0x3a, 0xeb, 0x0e, 0xde, 0xa1, 0xdc, 0x1f, 0x16, 0x20, 0x43, 0xb1, 0x5c,
-            0x78, 0x14, 0xc2, 0xee, 0x9e, 0x8e, 0x01, 0x16, 0x6c, 0x6f, 0x4b, 0xbc, 0x70, 0xa4, 0x8e, 0x23,
-            0x90, 0x20, 0x15, 0x66, 0x13, 0xef, 0x28, 0x30, 0x00, 0xa5, 0xaa, 0x27, 0x03, 0x5c, 0x27, 0x64,
-            0x54, 0xf3, 0xa6, 0x60, 0x8b, 0x9f, 0x08, 0x8d, 0xde, 0x48, 0x07, 0xd3, 0x2f, 0x96, 0x6d, 0xb2,
-            0x4b, 0x1c, 0xbb, 0xbb, 0xaf, 0x00, 0x80, 0xfe, 0xb6, 0xcd, 0xaa, 0x1f, 0xb4, 0x50, 0x02, 0xd3,
-            0x2b, 0xb5, 0x3d, 0x03, 0x4b, 0xc3, 0xf2, 0x66, 0x7b, 0x3b, 0xb2, 0xd7, 0x98, 0x17, 0x3c, 0xc3,
-            0xcd, 0x34, 0x3e, 0x81, 0xab, 0x42, 0x39, 0x71, 0xc2, 0xa9, 0x3f, 0xba, 0xd8, 0x16, 0xa8, 0x31,
-            0x7a, 0xd9, 0x08, 0xc0, 0x55, 0x4e, 0x02, 0xa7, 0xe0, 0x94, 0x77, 0x39, 0x66, 0x3a, 0x35, 0x9d,
-            0xd4, 0xd8, 0x79, 0x9b, 0x06, 0x56, 0xb0, 0xa8, 0x0e, 0xca, 0x07, 0xc9, 0x80, 0xc7, 0x8e, 0x4d,
-            0xda, 0xf0, 0xb8, 0xb4, 0x28, 0x44, 0x76, 0xf6, 0x0a, 0x40, 0xd3, 0x10, 0x3a, 0x98, 0x5e, 0xea,
-            0x8f, 0x4b, 0x87, 0xd6, 0x58, 0x7c, 0x9f, 0x3f, 0xbb, 0x39, 0x18, 0x19, 0x49, 0x4d, 0xce, 0x17,
-            0x0a, 0xdf, 0xd8, 0x62, 0xbc, 0x0c, 0xd4, 0xf7, 0x5a, 0xa6, 0xc4, 0xb4, 0xe0, 0xf6, 0xc7, 0x68,
-            0x2d, 0x9f, 0x8e, 0x3e, 0x83, 0x38, 0x39, 0xd7, 0x88, 0x10, 0x3a, 0x51, 0x8a, 0xf0, 0x00, 0x30,
-            0x0e, 0x8c, 0xc5, 0xa3, 0x51, 0x76, 0xb9, 0x96, 0x8d, 0x92, 0xcd, 0x55, 0x0d, 0x6f, 0x82, 0xd2,
-            0x0d, 0xca, 0xa0, 0xce, 0xed, 0x6b, 0x23, 0x58, 0x06, 0x8b, 0x9c, 0xc7, 0x34, 0x14, 0x2b, 0x34,
-            0x0b, 0xc0, 0x89, 0x84, 0xdb, 0xe6, 0x84, 0x91, 0xc0, 0x54, 0x22, 0xe3, 0xa7, 0xaa, 0x33, 0x05,
-            0x10, 0x1f, 0xd2, 0xe2, 0xb7, 0xe9, 0x73, 0x4f, 0xb2, 0x51, 0xb0, 0xdc, 0x42, 0x07, 0xa4, 0x70,
-            0x73, 0x79, 0xbd, 0x71, 0x41, 0x37, 0x36, 0xf2, 0x16, 0xd6, 0x3e, 0x77, 0xe2, 0xf5, 0x68, 0x13,
-            0x96, 0xe0, 0xe3, 0xc7, 0xcd, 0xc8, 0x93, 0x3c, 0x20, 0xd7, 0x4a, 0xcf, 0xdf, 0xc0, 0x4d, 0xe1,
-            0x0b, 0xf5, 0xa9, 0x50, 0x3f, 0xf2, 0x74, 0xe2, 0xac, 0x33, 0xed, 0x3a, 0x1d, 0xa8, 0x42, 0x31,
-            0x60, 0x28, 0x75, 0x2e, 0xb6, 0x70, 0x90, 0xc9, 0x66, 0xb4, 0x55, 0x6e, 0x45, 0x9b, 0xa7, 0x3c,
-            0x1a, 0x30, 0x3a, 0xc9, 0x80, 0x02, 0x72, 0xc0, 0x51, 0x41, 0x5f, 0x1e, 0x3b, 0x75, 0x07, 0x74,
-            0x9f, 0xc2, 0xb1, 0x1e, 0xc2, 0x08, 0xaa, 0x2f, 0x86, 0x5b, 0x14, 0x94, 0x26, 0xe5, 0x23, 0xb9,
-            0x1a, 0x2e, 0xd7, 0x2b, 0x79, 0x89, 0x07, 0x72, 0x43, 0x15, 0xfb, 0x3b, 0xdd, 0x99, 0x49, 0x77,
-            0x07, 0x2f, 0x34, 0x53, 0x30, 0xa0, 0xb8, 0x55, 0x9d, 0x19, 0xfd, 0x10, 0xe8, 0x82, 0xc4, 0xff,
-            0xf2, 0x1c, 0xbc, 0x09, 0x95, 0x76, 0x27, 0xe9, 0x5c, 0x17, 0x63, 0xb4, 0xfc, 0x3d, 0x8d, 0x1c,
-            0x4c, 0xff, 0xd9, 0x61, 0xeb, 0x12, 0x90, 0xc2, 0x36, 0x05, 0xf0, 0x21, 0x6c, 0xe7, 0x3d, 0xaa,
-            0x1c, 0x1c, 0xb5, 0xa1, 0x67, 0x3b, 0x9e, 0xe2, 0x48, 0x88, 0x8c, 0x66, 0xd1, 0x4c, 0xde, 0x6e,
-            0x66, 0x61, 0x77, 0x0b, 0x5a, 0xcb, 0x4a, 0x30, 0x0d, 0xc7, 0x32, 0x2c, 0x3e, 0x2c, 0xba, 0xed,
-            0xb3, 0x56, 0xa1, 0xfe, 0xbe, 0x88, 0xf9, 0xcc, 0x15, 0x60, 0xdb, 0x30, 0x52, 0x68, 0x27, 0xbd,
-            0x6e, 0x38, 0xbc, 0xe3, 0xfd, 0x9f, 0x8f, 0x3f, 0xbd, 0x39, 0x7c, 0xbe, 0x8f, 0x9a, 0xe0, 0x7a,
-            0xe6, 0xde, 0xe1, 0x6b, 0xe2, 0xfe, 0x30, 0x1f, 0xa9, 0x56, 0xb1, 0x53, 0xaf, 0xb0, 0xef, 0x40,
-            0x99, 0x71, 0x60, 0x48, 0x4a, 0x2b, 0x4f, 0x33, 0x33, 0x7a, 0xa4, 0xdc, 0xed, 0xa5, 0x93, 0x8e,
-            0x7e, 0xf4, 0xe8, 0x9f, 0xdd, 0x6d, 0xbd, 0x85, 0xc8, 0x2c, 0x2d, 0xf7, 0xa0, 0x93, 0xa7, 0xba,
-            0x93, 0x03, 0x89, 0x71, 0xbb, 0xdb, 0x62, 0x55, 0xf1, 0x1c, 0xaf, 0x81, 0x45, 0xbb, 0x80, 0x4e,
-            0x52, 0x5e, 0xad, 0xb4, 0x8a, 0x2c, 0x60, 0x58, 0xde, 0xd2, 0x50, 0x43, 0xa0, 0x65, 0x3d, 0x40,
-            0x39, 0x0b, 0x91, 0x48, 0x88, 0x1c, 0xf9, 0x93, 0x32, 0x49, 0x45, 0xd3, 0xd4, 0x94, 0xbe, 0x55,
-            0xf2, 0xe0, 0x15, 0x56, 0xdc, 0x9c, 0x83, 0x26, 0xc9, 0x98, 0xc6, 0x56, 0x75, 0x05, 0xaa, 0xcc,
-            0x6b, 0xa7, 0xa6, 0x44, 0x01, 0x1c, 0x21, 0x31, 0x5d, 0xa5, 0x61, 0x99, 0x4a, 0xc1, 0x32, 0xb1,
-            0x09, 0xe6, 0x9a, 0x2c, 0x2f, 0x16, 0xfe, 0x4b, 0x00, 0xb2, 0x8e, 0x46, 0x86, 0xa3, 0xcd, 0xe2,
-            0x75, 0xc8, 0x9b, 0x82, 0xda, 0xcd, 0x0a, 0xdb, 0x7d, 0xfa, 0x92, 0x4a, 0xd9, 0x6e, 0xd0, 0x12,
-            0xb5, 0x22, 0x2c, 0x54, 0x4b, 0xab, 0x53, 0x9d, 0xc0, 0x4b, 0xa2, 0x08, 0x5f, 0xd1, 0x8f, 0x58,
-            0x59, 0x63, 0xe8, 0x80, 0xc9, 0x83, 0x23, 0xfb, 0x56, 0x19, 0xa9, 0xb8, 0xd1, 0xc9, 0x7f, 0x51,
-            0x37, 0x68, 0x68, 0xd5, 0x68, 0x0d, 0xc5, 0x03, 0x04, 0xd6, 0x07, 0x79, 0x06, 0x16, 0x3b, 0x60,
-            0xd5, 0x00, 0x73, 0x85, 0x43, 0x69, 0x26, 0x8d, 0x6a, 0x67, 0x89, 0x00, 0x8e, 0x6a, 0x17, 0xfe,
-            0x19, 0x41, 0xf8, 0x1e, 0xcc, 0x30, 0x9f, 0xcf, 0xcc, 0x2d, 0x03, 0x18, 0xe8, 0x8b, 0x72, 0x32,
-            0xf9, 0x56, 0x29, 0xfc, 0x51, 0x4d, 0x3f, 0xf8, 0x5a, 0x59, 0x61, 0x0b, 0x2f, 0x1d, 0x63, 0x45,
-            0xa4, 0x23, 0x9f, 0x1d, 0x3e, 0xff, 0xc5, 0xb3, 0x2d, 0x9f, 0x6d, 0xb9, 0x25, 0x1b, 0xa5, 0x78,
-            0x44, 0x6a, 0x25, 0x7a, 0x46, 0xe8, 0xe7, 0x10, 0xe6, 0xdc, 0x80, 0xca, 0x7a, 0xe6, 0x94, 0x20,
-            0x43, 0x60, 0xfa, 0xb8, 0x15, 0x3a, 0x94, 0xf6, 0x1a, 0x43, 0x2b, 0x0f, 0x7f, 0xc0, 0x0d, 0x23,
-            0x03, 0x44, 0x1d, 0xca, 0x2e, 0xad, 0x28, 0x31, 0x27, 0xea, 0x27, 0xe1, 0x3f, 0x3d, 0xb6, 0xa7,
-            0xee, 0xac, 0xe2, 0x3e, 0x97, 0x16, 0xaf, 0x94, 0x20, 0x4b, 0x76, 0xe6, 0x82, 0x65, 0x8b, 0x1a,
-            0x0a, 0x31, 0x15, 0xb5, 0x68, 0x85, 0x76, 0x25, 0x50, 0x67, 0xb2, 0xdf, 0x23, 0x9c, 0x85, 0xf6,
-            0x94, 0x83, 0xb7, 0x02, 0x50, 0x56, 0xef, 0x63, 0x79, 0x49, 0x54, 0x35, 0x8b, 0x79, 0x50, 0xa6,
-            0x50, 0xc2, 0x37, 0xcb, 0xcf, 0x49, 0x4e, 0x52, 0x2b, 0xf7, 0x73, 0x5b, 0xbb, 0xec, 0x55, 0x14,
-            0x94, 0x7b, 0xbf, 0xaa, 0x3d, 0x39, 0xfc, 0x5a, 0x9d, 0x0f, 0xca, 0x82, 0xc0, 0xc0, 0x1e, 0x9b,
-            0xb9, 0x57, 0x4b, 0x3a, 0x35, 0xc5, 0x4a, 0x5d, 0xe3, 0x67, 0x55, 0xb7, 0xe5, 0x94, 0x13, 0x1e,
-            0xe0, 0x48, 0xcb, 0xd8, 0xca, 0x24, 0x4a, 0x6b, 0x43, 0x17, 0x2c, 0x28, 0x76, 0x1f, 0x26, 0x0c,
-            0x42, 0xca, 0x33, 0xcc, 0x84, 0xf5, 0x2f, 0x1b, 0x25, 0xe4, 0x90, 0x1e, 0x18, 0xb8, 0x64, 0xe9,
-            0x51, 0x05, 0x56, 0xde, 0xc0, 0x7c, 0xe1, 0xd1, 0x07, 0xa3, 0xc3, 0x08, 0x0c, 0xda, 0x54, 0xd4,
-            0x37, 0x74, 0x37, 0xa5, 0x78, 0x7e, 0xa9, 0xff, 0x1a, 0x89, 0x17, 0x92, 0x28, 0xc9, 0x02, 0x44,
-            0x34, 0x9d, 0xa9, 0xf3, 0x2c, 0x8f, 0xfa, 0x2f, 0x5a, 0x4b, 0xf0, 0xc1, 0x33, 0x45, 0x9e, 0xdd,
-            0x51, 0x04, 0x49, 0xaf, 0xfe, 0xcf, 0xab, 0x7b, 0xa1, 0xfc, 0xf7, 0xad, 0xf9, 0xc6, 0xf6, 0xbc,
-            0x0f, 0x1b, 0xe6, 0x44, 0x55, 0x03, 0xe3, 0x8f, 0xd3, 0x67, 0xdb, 0xd8, 0x36, 0xe6, 0x35, 0x6b,
-            0x41, 0xb7, 0x55, 0x92, 0x59, 0xe6, 0xd5, 0x6a, 0x73, 0x2a, 0x60, 0xcf, 0x11, 0x9b, 0x32, 0xff,
-            0x6a, 0xe5, 0x6a, 0xa8, 0x8e, 0xa1, 0x73, 0xc2, 0x6c, 0x7e, 0x56, 0xd1, 0x5f, 0x48, 0xab, 0xe3,
-            0xf7, 0x69, 0x4b, 0x2f, 0xc3, 0x64, 0x6a, 0xee, 0x9a, 0xe1, 0x5d, 0x57, 0xed, 0xf0, 0x2b, 0x57,
-            0x6d, 0x51, 0xbb, 0x6a, 0x87, 0x74, 0xd5, 0x1a, 0xec, 0x51, 0xe7, 0xac, 0xad, 0x7c, 0xc5, 0x3b,
-            0xaa, 0x75, 0x17, 0x9f, 0xed, 0x72, 0x32, 0x16, 0x01, 0xe8, 0xf0, 0x46, 0xc2, 0x35, 0x0f, 0x37,
-            0x07, 0x35, 0xf2, 0x32, 0xff, 0x64, 0x09, 0x93, 0x05, 0xae, 0xb2, 0x4e, 0x1c, 0x57, 0x60, 0xd9,
-            0x55, 0xc9, 0x15, 0xb8, 0x34, 0xb6, 0xe1, 0xd4, 0x75, 0x14, 0x1f, 0xda, 0x89, 0x85, 0x3e, 0x3f,
-            0x68, 0xe9, 0x18, 0x28, 0x4d, 0x13, 0x8b, 0x0d, 0x03, 0x9e, 0x22, 0x64, 0x94, 0x71, 0xc6, 0x96,
-            0xc2, 0x3a, 0x76, 0x80, 0x6f, 0xa5, 0x45, 0xea, 0x6b, 0xdc, 0xb8, 0xba, 0x0f, 0x37, 0xbe, 0xf4,
-            0x82, 0x4a, 0xed, 0x48, 0x31, 0x61, 0x3c, 0xa0, 0x3a, 0x93, 0x78, 0x14, 0xcf, 0xe2, 0x73, 0x16,
-            0xf5, 0xc0, 0x9f, 0x73, 0xb4, 0xda, 0x42, 0xf0, 0xb8, 0x60, 0x83, 0x66, 0xa6, 0x5b, 0xdc, 0x4f,
-            0x95, 0x04, 0x86, 0x2a, 0x9d, 0xf3, 0xde, 0x99, 0xe3, 0x8b, 0xf7, 0x60, 0x65, 0xce, 0xd2, 0xe1,
-            0x97, 0xee, 0x60, 0x02, 0x8a, 0xca, 0x89, 0x17, 0x05, 0x9c, 0xb3, 0x71, 0x9f, 0xd3, 0x70, 0x3d,
-            0xb9, 0xe9, 0xd4, 0x93, 0x8c, 0xa0, 0x80, 0x64, 0xd5, 0x8e, 0x64, 0x77, 0xaa, 0x9d, 0x14, 0x7a,
-            0xbc, 0xb4, 0xd2, 0xd4, 0x01, 0xeb, 0x3c, 0x17, 0x4b, 0x90, 0x0b, 0x2c, 0x00, 0xdd, 0x03, 0xe7,
-            0x0e, 0x17, 0x41, 0x09, 0x7f, 0x9f, 0xa0, 0xa1, 0x10, 0xd2, 0xb0, 0x64, 0x1d, 0x84, 0x49, 0x84,
-            0x6a, 0xe1, 0x68, 0x86, 0x79, 0xfb, 0xc6, 0xdd, 0x74, 0xe9, 0x2e, 0xbe, 0xa3, 0x1c, 0xc7, 0x0b,
-            0x4b, 0x30, 0x23, 0xbf, 0x24, 0x02, 0x29, 0x6b, 0xe5, 0x6a, 0xec, 0x6f, 0x01, 0x1e, 0x27, 0x81,
-            0x75, 0xae, 0xb9, 0xdb, 0x78, 0x81, 0x9e, 0x77, 0x46, 0xc8, 0xa1, 0xb3, 0xa1, 0xe1, 0x39, 0xff,
-            0x05, 0xdb, 0x79, 0x63, 0xc3, 0x08, 0x0d, 0x9f, 0xf7, 0x9c, 0x4b, 0x18, 0xf9, 0x81, 0x21, 0xf9,
-            0x96, 0xd7, 0x8d, 0x1a, 0x11, 0x36, 0x4d, 0xb1, 0x6d, 0x98, 0xd9, 0x69, 0xec, 0xa0, 0x53, 0xa6,
-            0x46, 0xa0, 0x1a, 0x20, 0x1b, 0x84, 0x73, 0x33, 0xa5, 0xc3, 0xc3, 0x67, 0x5e, 0x96, 0x2b, 0x12,
-            0xad, 0x71, 0x3b, 0xea, 0xa2, 0xec, 0xa9, 0x47, 0x65, 0xb1, 0xf6, 0xb8, 0x45, 0x87, 0xb8, 0x45,
-            0x9f, 0xda, 0x3a, 0xc0, 0x40, 0x7d, 0x6b, 0x74, 0xa8, 0x09, 0x1a, 0x43, 0x0b, 0xb5, 0xb8, 0x90,
-            0x21, 0xfd, 0xcd, 0x2b, 0xfe, 0xa4, 0x94, 0xe9, 0xa1, 0x15, 0xb7, 0x00, 0x7a, 0x02, 0xdb, 0x71,
-            0x70, 0xcc, 0x25, 0x39, 0x96, 0x53, 0x88, 0x35, 0x26, 0x0e, 0xec, 0x3f, 0xdf, 0x5c, 0x43, 0x3a,
-            0x0b, 0xe0, 0x0c, 0x0b, 0x52, 0x34, 0x3c, 0x0b, 0xcb, 0x4f, 0x88, 0x03, 0xf0, 0xf7, 0x80, 0xd8,
-            0xfa, 0x3c, 0x16, 0x36, 0xa3, 0x4d, 0x9a, 0xce, 0x08, 0x30, 0x36, 0x36, 0x3e, 0x29, 0xff, 0x45,
-            0xd5, 0xbb, 0x81, 0x8d, 0x6f, 0x77, 0x20, 0x96, 0xcf, 0x2e, 0xc0, 0xfc, 0x2b, 0x62, 0x26, 0x92,
-            0x63, 0x36, 0x58, 0x5b, 0xd7, 0x4a, 0x30, 0x9a, 0x79, 0x20, 0x92, 0x22, 0xdb, 0xee, 0x3c, 0x99,
-            0x2f, 0xff, 0xa0, 0x2b, 0x00, 0x10, 0x99, 0x80, 0xb3, 0xb8, 0x71, 0x16, 0x26, 0x80, 0x08, 0x0a,
-            0x2b, 0x2b, 0x42, 0x42, 0x0e, 0x76, 0x1d, 0x1c, 0x34, 0x2a, 0xc5, 0x3f, 0x41, 0xf6, 0xaa, 0xcc,
-            0x4f, 0x23, 0x40, 0x34, 0x13, 0x18, 0xfb, 0x13, 0x53, 0x13, 0x56, 0xd4, 0xca, 0x9b, 0x8d, 0x48,
-            0x93, 0x05, 0xd2, 0x7b, 0xa8, 0xe3, 0x65, 0x8f, 0xd0, 0x19, 0x33, 0x7a, 0xfc, 0xb5, 0x2e, 0x9c,
-            0x98, 0x9e, 0xac, 0x07, 0x59, 0xfd, 0xf5, 0x3a, 0x22, 0x16, 0x7e, 0xa5, 0x24, 0x3c, 0x1b, 0x1b,
-            0x12, 0x94, 0x4e, 0xe6, 0xc6, 0xc6, 0x18, 0xe5, 0xba, 0x47, 0xf6, 0xfc, 0xbd, 0x4b, 0xf3, 0x73,
-            0x63, 0x4a, 0xd8, 0x92, 0x61, 0x6b, 0x81, 0x51, 0x05, 0x2c, 0xa0, 0x30, 0x2c, 0x04, 0xcc, 0x6e,
-            0x18, 0xd1, 0x14, 0xb6, 0x70, 0xd2, 0x34, 0x9e, 0x71, 0x83, 0x0a, 0x7c, 0x85, 0x69, 0xe3, 0x8a,
-            0xa6, 0xbc, 0x8d, 0x01, 0xc6, 0x5b, 0xe3, 0xd4, 0xed, 0x82, 0x7c, 0x6b, 0xd2, 0x2f, 0xb9, 0xbb,
-            0x14, 0x64, 0x7b, 0xea, 0x85, 0x74, 0xe7, 0xcc, 0xf1, 0x20, 0xaf, 0xc1, 0xda, 0x21, 0x00, 0x0c,
-            0x97, 0xed, 0x31, 0x23, 0x62, 0xd9, 0x59, 0x4f, 0xb8, 0xbf, 0x76, 0x17, 0x3f, 0xe7, 0x1d, 0x83,
-            0x38, 0xec, 0xa9, 0xc9, 0x25, 0x92, 0xa5, 0xc1, 0xd3, 0x45, 0x1a, 0x8c, 0x5e, 0xb1, 0x2d, 0x70,
-            0x77, 0xf9, 0x9f, 0x4c, 0xaf, 0xb1, 0x5e, 0x5f, 0x99, 0x21, 0x69, 0x14, 0x1a, 0x73, 0xa4, 0x23,
-            0x04, 0x14, 0xf8, 0xa4, 0x28, 0xbd, 0x5c, 0x90, 0x4c, 0x7e, 0xf0, 0x3c, 0xbb, 0x2c, 0x2b, 0x0c,
-            0x04, 0x04, 0x11, 0xf8, 0xf8, 0x76, 0x16, 0xe0, 0xe4, 0x3c, 0xfc, 0xd2, 0x8f, 0x68, 0xb7, 0xa3,
-            0xf8, 0xcc, 0x39, 0x2d, 0xa3, 0xb8, 0x22, 0x42, 0x99, 0xc9, 0x7e, 0x6e, 0x67, 0x36, 0x0b, 0x96,
-            0x94, 0xc6, 0xe3, 0x17, 0x15, 0x72, 0x2e, 0xba, 0x4b, 0x83, 0xbe, 0xbd, 0x0f, 0x3b, 0x0a, 0x1d,
-            0x6a, 0x36, 0x5a, 0x79, 0x1c, 0x94, 0x30, 0x84, 0x45, 0x8e, 0x28, 0xc1, 0x5c, 0x2b, 0x6e, 0x4d,
-            0x5a, 0xbd, 0x9f, 0xb9, 0x8f, 0x9a, 0xe1, 0x2c, 0x20, 0x37, 0x5b, 0x20, 0x62, 0x79, 0x73, 0xcf,
-            0xa7, 0x2c, 0x57, 0x5d, 0x82, 0x46, 0x37, 0x80, 0xa7, 0x64, 0x63, 0x23, 0x45, 0x91, 0xb8, 0x64,
-            0x05, 0x7d, 0x9f, 0xe1, 0xb2, 0x83, 0xb1, 0x0e, 0x2b, 0x8e, 0xa1, 0xf7, 0x8b, 0xac, 0x52, 0xec,
-            0x40, 0x64, 0x4e, 0x29, 0x98, 0xde, 0x38, 0x04, 0x40, 0x8b, 0x1a, 0x8e, 0x5e, 0x88, 0x60, 0xc0,
-            0xd6, 0xd5, 0x34, 0xd0, 0x09, 0x23, 0x2a, 0x5c, 0x80, 0xe3, 0x6c, 0x4e, 0x3c, 0x97, 0x13, 0x95,
-            0x0d, 0x82, 0x3b, 0xff, 0xae, 0x0e, 0xa4, 0xe4, 0x2b, 0xeb, 0x38, 0xca, 0x03, 0xa5, 0xc9, 0x4b,
-            0xa3, 0x6f, 0x99, 0x3d, 0xa1, 0xc3, 0x49, 0xab, 0xbf, 0xb1, 0x31, 0xf3, 0x1f, 0x2d, 0x9b, 0xa5,
-            0x62, 0x91, 0x6f, 0x85, 0x92, 0xb8, 0x55, 0x0e, 0x23, 0x8c, 0xfd, 0xb2, 0x61, 0x41, 0x12, 0x67,
-            0x87, 0xeb, 0x85, 0xb0, 0x01, 0x18, 0x57, 0x4f, 0xca, 0xe2, 0x2a, 0xd0, 0x9b, 0x7f, 0xdf, 0xc2,
-            0xfd, 0xa0, 0x15, 0x88, 0xf5, 0x1d, 0x27, 0x17, 0x5b, 0x67, 0x8e, 0xe7, 0x2e, 0xbc, 0x85, 0xbd,
-            0xf0, 0xec, 0x52, 0x5e, 0x22, 0x4b, 0xe3, 0xe5, 0xdc, 0x19, 0x1a, 0x58, 0x17, 0x74, 0xfa, 0x8a,
-            0x3a, 0x9c, 0x64, 0x5d, 0x2b, 0x15, 0x2e, 0x4e, 0x32, 0x22, 0xaf, 0xbf, 0x90, 0x33, 0x0b, 0x6a,
-            0x68, 0x58, 0x87, 0x10, 0xa0, 0x5c, 0x9b, 0x08, 0x7a, 0x79, 0x9e, 0x7a, 0xb2, 0x20, 0xd9, 0x4e,
-            0x1f, 0xa6, 0x91, 0xe2, 0xad, 0x98, 0xb1, 0x18, 0x56, 0x28, 0x17, 0x2b, 0xe0, 0x77, 0x5b, 0xee,
-            0x7c, 0xa6, 0xf4, 0x43, 0xf1, 0x0d, 0xb5, 0x80, 0x02, 0x1b, 0x73, 0xb1, 0xc7, 0x27, 0x64, 0x17,
-            0xcf, 0xed, 0xfc, 0xa0, 0x12, 0xb0, 0x25, 0xdf, 0x31, 0x30, 0xb0, 0x9f, 0xec, 0x80, 0x7f, 0x4b,
-            0x7c, 0x6a, 0xbf, 0xbf, 0x83, 0xdc, 0x93, 0x4f, 0x0f, 0xc0, 0xa3, 0xec, 0xe9, 0xf6, 0xaf, 0x2e,
-            0xf5, 0x27, 0x99, 0xba, 0xbb, 0xfd, 0xbf, 0x2e, 0xe3, 0x57, 0x70, 0xc9, 0xdd, 0x8c, 0x36, 0x63,
-            0x12, 0xdc, 0xee, 0x38, 0xd7, 0xdb, 0x3d, 0x28, 0xfe, 0xdb, 0xc7, 0xca, 0x15, 0xfb, 0x05, 0xeb,
-            0x2f, 0x3a, 0xee, 0xfb, 0x47, 0xfc, 0x5e, 0x76, 0xe1, 0xdb, 0x1b, 0x4f, 0x6b, 0x29, 0x23, 0x02,
-            0x53, 0xb0, 0xd5, 0x52, 0x3a, 0x58, 0xdc, 0xef, 0x94, 0xf1, 0x66, 0x23, 0x29, 0x1d, 0x4a, 0xe8,
-            0xc0, 0xb6, 0x86, 0x38, 0x01, 0x10, 0x5a, 0x99, 0x2a, 0x3f, 0x35, 0xca, 0x80, 0x4a, 0x0c, 0xb7,
-            0x04, 0xcc, 0xda, 0xb4, 0xb1, 0xf5, 0x11, 0x74, 0x0d, 0x98, 0xef, 0x61, 0xbe, 0xd3, 0xc6, 0xfd,
-            0xea, 0x49, 0x21, 0xd9, 0x0b, 0x6c, 0x23, 0xf8, 0xce, 0x3a, 0x10, 0x11, 0x59, 0x03, 0xdb, 0x3d,
-            0x74, 0xd0, 0x18, 0x35, 0x99, 0xa6, 0xda, 0x92, 0xd0, 0x46, 0x61, 0x91, 0xb8, 0x4d, 0x43, 0x8a,
-            0xf4, 0xe3, 0xc7, 0x88, 0x87, 0x77, 0x8f, 0x21, 0x3a, 0x9a, 0x50, 0x8e, 0xc0, 0xd4, 0xc9, 0xba,
-            0xd4, 0x42, 0x8b, 0xef, 0xa9, 0xae, 0x89, 0x22, 0x1a, 0xeb, 0x08, 0xbe, 0x91, 0x30, 0xd4, 0x75,
-            0xab, 0x9d, 0x34, 0xbf, 0x89, 0x80, 0xb7, 0x1f, 0xa4, 0x25, 0xe7, 0xdf, 0x20, 0xd0, 0x47, 0xb8,
-            0x8e, 0x7a, 0x42, 0x4d, 0x0a, 0xe4, 0x54, 0x89, 0x6a, 0x52, 0x3e, 0x27, 0x40, 0x5d, 0x92, 0x43,
-            0x4b, 0x84, 0x2c, 0xa3, 0x31, 0xdf, 0x33, 0x94, 0xe7, 0x43, 0x83, 0x95, 0xad, 0x9d, 0xc0, 0x9a,
-            0x47, 0x31, 0xd1, 0x56, 0xb6, 0x05, 0x35, 0x5c, 0x46, 0x24, 0x59, 0x95, 0x55, 0x36, 0x82, 0x55,
-            0x82, 0xbd, 0xe1, 0xd1, 0xab, 0xb0, 0xcb, 0x53, 0x34, 0xff, 0xda, 0xde, 0xb6, 0xda, 0xd6, 0x5d,
-            0x1a, 0x4f, 0xee, 0x98, 0x37, 0xd0, 0x3b, 0x6e, 0xf1, 0x1c, 0x97, 0x7e, 0x60, 0x7a, 0x2b, 0x01,
-            0xbe, 0xaa, 0x1b, 0x05, 0x4c, 0x38, 0x98, 0xf2, 0x97, 0x2d, 0x26, 0xfc, 0x2f, 0xbc, 0xba, 0x03,
-            0xf0, 0x56, 0x4b, 0x01, 0xf6, 0xf3, 0x18, 0x4c, 0x7b, 0x55, 0x31, 0x2f, 0xc1, 0x5d, 0x4f, 0x5b,
-            0x9c, 0x39, 0x0d, 0x90, 0x5c, 0x5d, 0x75, 0x07, 0x7e, 0x80, 0x1a, 0x82, 0xe7, 0x28, 0xc6, 0x77,
-            0x0b, 0x0e, 0x49, 0x01, 0x6c, 0x10, 0x35, 0x82, 0xbe, 0xbe, 0xa1, 0xff, 0x85, 0x83, 0xd7, 0xca,
-            0xae, 0x33, 0xa0, 0x00, 0xa2, 0x2c, 0x35, 0xe8, 0x26, 0x01, 0x91, 0xe0, 0xad, 0x05, 0xd3, 0xea,
-            0xf0, 0xa2, 0xf6, 0xa2, 0xad, 0x0a, 0x96, 0x76, 0xed, 0xc9, 0x5a, 0xf8, 0xdd, 0x5f, 0xeb, 0x18,
-            0xf7, 0x16, 0x4e, 0xe8, 0x46, 0xd6, 0x2d, 0x5c, 0x6f, 0x55, 0x4b, 0x54, 0xdc, 0x9a, 0x35, 0x92,
-            0x3c, 0xf8, 0xa1, 0x94, 0xa7, 0x47, 0x91, 0xd9, 0x19, 0xe5, 0x76, 0x06, 0x1d, 0x8f, 0x8d, 0x55,
-            0x0a, 0xba, 0x5c, 0x22, 0x6c, 0x23, 0x2b, 0x61, 0x1a, 0x6a, 0x8a, 0xb0, 0x4b, 0xed, 0x35, 0xc6,
-            0x74, 0x3a, 0x7c, 0x43, 0xbf, 0xa8, 0xa0, 0x21, 0xe5, 0xb7, 0x2c, 0xc1, 0x51, 0xfc, 0x08, 0x86,
-            0xf7, 0x86, 0x89, 0xf1, 0x1d, 0x98, 0x09, 0x60, 0xfe, 0x7e, 0xd7, 0x9f, 0x06, 0x73, 0x74, 0x35,
-            0xca, 0x23, 0xc0, 0x70, 0x27, 0x5e, 0xc3, 0x8b, 0x1b, 0x18, 0xfc, 0x34, 0x36, 0xa6, 0x2c, 0x91,
-            0xc7, 0x4a, 0x99, 0xae, 0xdf, 0x24, 0xce, 0x5e, 0x15, 0xce, 0x3e, 0x1a, 0x39, 0x0f, 0x46, 0xc5,
-            0xe2, 0x10, 0xd4, 0x17, 0x7b, 0xf6, 0x56, 0x9d, 0x26, 0x16, 0x34, 0x1d, 0x4b, 0x84, 0xf9, 0x3b,
-            0x27, 0xf1, 0xc7, 0x13, 0x44, 0x89, 0xcc, 0x0a, 0xad, 0x93, 0xdf, 0x24, 0x79, 0x62, 0xe0, 0xbe,
-            0xc1, 0xa5, 0x56, 0xa2, 0xc9, 0xa3, 0x65, 0x56, 0x16, 0x36, 0x9a, 0x92, 0xc9, 0x59, 0x0e, 0x4c,
-            0x1f, 0xf3, 0xde, 0x8c, 0xc9, 0x2c, 0x13, 0x0f, 0xa3, 0x13, 0xb6, 0xdd, 0xb5, 0xe5, 0x58, 0xf4,
-            0x94, 0x6b, 0x32, 0x59, 0x88, 0xe8, 0xce, 0x8c, 0xac, 0x71, 0xcf, 0x9c, 0xef, 0xd0, 0x17, 0x24,
-            0x9a, 0x4d, 0xb2, 0xa5, 0x31, 0xf6, 0x99, 0x07, 0x88, 0x65, 0xec, 0xc7, 0x30, 0x5c, 0xde, 0xd9,
-            0xdc, 0xb8, 0xd6, 0x9c, 0x19, 0x41, 0xfd, 0x98, 0x82, 0xfa, 0x06, 0xf6, 0x6e, 0x9d, 0xcc, 0x92,
-            0xed, 0x44, 0x53, 0x0f, 0x57, 0xd8, 0x58, 0x8a, 0x4b, 0x01, 0x88, 0x08, 0x18, 0x05, 0xe0, 0x64,
-            0xa0, 0x61, 0xf3, 0x3b, 0xa1, 0xa3, 0x64, 0x01, 0x9d, 0x4a, 0xa1, 0x97, 0x2b, 0x15, 0x21, 0x4f,
-            0xd8, 0x66, 0x3e, 0xb6, 0x0f, 0xb4, 0x0c, 0xb7, 0xc2, 0xbf, 0x5b, 0x4a, 0x8d, 0x90, 0xfa, 0x88,
-            0x78, 0x64, 0xf8, 0xdd, 0x0f, 0xd0, 0xd4, 0xb8, 0x47, 0xf9, 0x66, 0x91, 0xf7, 0xc5, 0xdd, 0x40,
-            0x95, 0xd1, 0xbc, 0x66, 0x65, 0x5d, 0x28, 0x64, 0x41, 0xb6, 0x60, 0x90, 0xc5, 0x25, 0x84, 0x3b,
-            0x5c, 0x3b, 0x95, 0x3e, 0x27, 0x70, 0xd3, 0x0e, 0x6b, 0x19, 0x23, 0x66, 0xb0, 0xe7, 0xa5, 0x4f,
-            0x34, 0x4b, 0xb6, 0xbf, 0x8d, 0xbd, 0x71, 0x15, 0xd8, 0xfd, 0xca, 0x3e, 0x79, 0x4d, 0x27, 0xdc,
-            0x07, 0xb6, 0x38, 0x11, 0x38, 0xb2, 0x02, 0x1c, 0x00, 0xfe, 0x84, 0x93, 0x25, 0x71, 0x5a, 0x30,
-            0xf4, 0xa4, 0x0a, 0xa7, 0x63, 0xac, 0x9c, 0x56, 0x2f, 0x06, 0x17, 0x10, 0x33, 0xf0, 0x55, 0x81,
-            0x02, 0x23, 0x2e, 0xe2, 0x8e, 0xca, 0xa6, 0xc8, 0xaa, 0xc5, 0x04, 0xd6, 0x7b, 0x7e, 0x57, 0x7d,
-            0xca, 0x37, 0x8b, 0x15, 0xd6, 0x24, 0x43, 0xe0, 0x95, 0x15, 0x4f, 0xd2, 0xd3, 0x15, 0x23, 0x86,
-            0xf0, 0x5a, 0xc5, 0x74, 0x74, 0x77, 0x4d, 0xd1, 0x1f, 0xa2, 0x6a, 0xd5, 0x8e, 0xa2, 0x75, 0xf1,
-            0x45, 0xe5, 0x7d, 0x8f, 0x21, 0xbb, 0xe6, 0x08, 0xd8, 0x83, 0x35, 0x66, 0x11, 0x68, 0xe1, 0x8d,
-            0xe7, 0xa6, 0xdd, 0xff, 0xa4, 0x39, 0x73, 0xa2, 0xcc, 0x70, 0xd1, 0xb8, 0x5f, 0x58, 0xc4, 0xb3,
-            0xdb, 0x4a, 0x8e, 0xae, 0x99, 0x65, 0x8b, 0x7b, 0x6a, 0xa5, 0x1b, 0x56, 0x10, 0x68, 0xd9, 0xc6,
-            0x27, 0x3c, 0xb2, 0x66, 0x4c, 0xce, 0x65, 0xd3, 0x62, 0x3b, 0xc7, 0x31, 0x35, 0xe2, 0x34, 0x01,
-            0x27, 0x81, 0x3a, 0x1b, 0xe8, 0x0f, 0x22, 0x36, 0x30, 0x96, 0x64, 0x4b, 0x6a, 0xa9, 0xe1, 0x77,
-            0x28, 0xde, 0x2e, 0x3e, 0xaa, 0xa5, 0x23, 0x20, 0x5d, 0x2f, 0xbc, 0xb7, 0xc5, 0x89, 0xc7, 0x75,
-            0x40, 0xe9, 0x5c, 0x40, 0xf0, 0x88, 0xe5, 0x69, 0x50, 0x7e, 0x93, 0xd0, 0xf4, 0x09, 0x79, 0x9b,
-            0x47, 0x20, 0x0c, 0xd5, 0xc0, 0x37, 0x81, 0x70, 0x57, 0xa6, 0x9a, 0x8a, 0xa7, 0x9b, 0x6d, 0xad,
-            0x0e, 0xc1, 0x56, 0xfd, 0x4b, 0xbd, 0xd1, 0x42, 0xb7, 0x16, 0x25, 0x7c, 0x63, 0xcb, 0xde, 0xd1,
-            0x94, 0x70, 0x67, 0xa1, 0x85, 0x25, 0x9d, 0x26, 0x70, 0xed, 0x18, 0xe8, 0x66, 0x6a, 0x11, 0x96,
-            0xd7, 0xa7, 0x37, 0x6e, 0x11, 0xd6, 0x81, 0x96, 0x56, 0xd1, 0x99, 0xac, 0x76, 0x37, 0x42, 0xc4,
-            0x80, 0x85, 0x61, 0xad, 0x7d, 0xfb, 0xa8, 0x29, 0x43, 0xeb, 0x29, 0x12, 0xec, 0xce, 0x90, 0xf5,
-            0x55, 0xf1, 0xcf, 0x1a, 0xa5, 0xc8, 0x7d, 0xbc, 0x1e, 0xfa, 0x76, 0x5f, 0xe3, 0x85, 0xd8, 0x37,
-            0x30, 0xea, 0xb5, 0xe6, 0x50, 0x4b, 0xa4, 0x83, 0x29, 0xcc, 0x8b, 0x1b, 0xda, 0x12, 0x5c, 0x99,
-            0x82, 0xbb, 0x45, 0xc6, 0x47, 0xd1, 0x42, 0x6f, 0x67, 0xa3, 0x54, 0x91, 0x25, 0x7d, 0xce, 0x2a,
-            0x48, 0xe5, 0x3e, 0x48, 0x7c, 0x85, 0xc0, 0x05, 0x11, 0xec, 0xa2, 0x6e, 0xf8, 0x15, 0x88, 0x16,
-            0x61, 0x0a, 0x42, 0x58, 0x3d, 0x96, 0x3d, 0x9c, 0x4b, 0x4b, 0x89, 0x5a, 0x98, 0x34, 0x19, 0xe5,
-            0x45, 0x93, 0x4a, 0x84, 0x57, 0x41, 0xd7, 0xdd, 0xe3, 0x9e, 0x92, 0x80, 0xc2, 0x45, 0xd2, 0x40,
-            0xb5, 0x32, 0x06, 0x39, 0xd0, 0x16, 0x8d, 0xe1, 0xfd, 0x0b, 0x6c, 0xba, 0xf8, 0xfc, 0x84, 0xe1,
-            0xcc, 0x50, 0xfe, 0x1a, 0x28, 0x57, 0x5f, 0x1c, 0xbe, 0x7b, 0x0d, 0x27, 0xcd, 0x86, 0xa2, 0x20,
-            0x7b, 0x16, 0x0e, 0x90, 0x86, 0x01, 0x0c, 0x82, 0xc0, 0x19, 0x78, 0xb7, 0x41, 0xf0, 0x23, 0xf0,
-            0x96, 0x44, 0x32, 0xde, 0x1a, 0x80, 0xd2, 0x4e, 0x71, 0x80, 0x80, 0xb8, 0x18, 0xd4, 0x75, 0xb7,
-            0x4f, 0xc9, 0xa7, 0x9f, 0xa2, 0x1a, 0x0d, 0x0a, 0x63, 0x2e, 0xc3, 0xab, 0x55, 0xa3, 0xf2, 0x83,
-            0x8e, 0xd1, 0xdd, 0xfe, 0x49, 0x16, 0xf6, 0xde, 0x0f, 0x1b, 0x49, 0xd9, 0x1f, 0x5c, 0xea, 0x6f,
-            0x21, 0x24, 0x0a, 0x87, 0x6b, 0x58, 0x14, 0x89, 0xdf, 0x45, 0xe8, 0x6c, 0x69, 0xbd, 0x26, 0xcc,
-            0x05, 0xe0, 0xed, 0x4b, 0xa3, 0x27, 0x78, 0x50, 0x8b, 0xa4, 0x10, 0x1e, 0xb0, 0x4f, 0x4e, 0x7e,
-            0xfb, 0xdb, 0xe9, 0x16, 0x3b, 0xc1, 0x82, 0x89, 0x91, 0x75, 0x91, 0x97, 0xf2, 0xa9, 0x73, 0x1d,
-            0xe8, 0x58, 0x64, 0x38, 0xc7, 0xa1, 0xd5, 0xfe, 0x8f, 0x89, 0x9d, 0x02, 0x25, 0xa3, 0xd3, 0x9b,
-            0x2d, 0x27, 0x8a, 0x58, 0x87, 0x1c, 0xed, 0x6a, 0x71, 0x67, 0x8d, 0x6b, 0x94, 0xd4, 0x22, 0x4e,
-            0xb4, 0xb3, 0xb2, 0xf7, 0x01, 0x28, 0xcc, 0xf1, 0x07, 0x66, 0xa4, 0xb1, 0x73, 0x21, 0x35, 0xee,
-            0x2d, 0x2d, 0x6d, 0x55, 0x3e, 0xd1, 0x7e, 0x78, 0xda, 0xf9, 0xaf, 0x6d, 0xb6, 0x21, 0x98, 0x78,
-            0x8d, 0x11, 0xd0, 0xa6, 0xb7, 0x67, 0x42, 0x6c, 0x86, 0x7f, 0x6b, 0x83, 0x09, 0x3b, 0xf6, 0x26,
-            0x1f, 0xb6, 0xf9, 0x28, 0x15, 0x46, 0x4e, 0x3b, 0xbf, 0xfd, 0xad, 0xb7, 0xb5, 0x43, 0xe2, 0x08,
-            0x3c, 0xe7, 0xb8, 0x27, 0x40, 0x3b, 0x17, 0x4c, 0x3f, 0x94, 0x61, 0xfc, 0x24, 0x03, 0x1e, 0x75,
-            0x63, 0xd6, 0xc0, 0x0d, 0xda, 0x07, 0xad, 0x0a, 0x83, 0x0f, 0x30, 0x9a, 0x32, 0x80, 0x09, 0x87,
-            0xf3, 0x2b, 0x87, 0x46, 0xd7, 0x96, 0x89, 0xce, 0xcf, 0x50, 0x97, 0xd3, 0x1f, 0xd4, 0x0d, 0x1e,
-            0x13, 0x00, 0xc7, 0x14, 0x7e, 0x8a, 0x33, 0x39, 0xd3, 0x4d, 0xc9, 0x8b, 0xa0, 0x0e, 0x8d, 0xb6,
-            0x59, 0xf8, 0x99, 0x97, 0x2c, 0xea, 0xc4, 0x2a, 0x06, 0xa9, 0x79, 0xe6, 0xc8, 0xf9, 0x83, 0x18,
-            0x0e, 0xaa, 0xcd, 0xd0, 0x51, 0x34, 0xbe, 0x8a, 0x65, 0x2a, 0x96, 0xa1, 0xe7, 0xf8, 0x8a, 0xa5,
-            0x02, 0x98, 0x45, 0xd5, 0x84, 0x8a, 0xe7, 0xf1, 0x58, 0xd0, 0xa7, 0x0a, 0x4d, 0xcb, 0x1c, 0x4b,
-            0x32, 0x27, 0xd2, 0x09, 0xb9, 0xc7, 0x0b, 0x28, 0x6d, 0xbe, 0x2c, 0xa3, 0x71, 0x32, 0x3d, 0x5d,
-            0x52, 0x19, 0x43, 0xb6, 0x32, 0x7a, 0xee, 0x44, 0x20, 0x78, 0xe5, 0x18, 0x6e, 0x18, 0x28, 0x27,
-            0x85, 0x8d, 0x4b, 0x7b, 0x2e, 0x89, 0xc4, 0x75, 0x3f, 0xa9, 0xf4, 0xcb, 0xeb, 0x74, 0x06, 0x2c,
-            0x7f, 0xdb, 0x61, 0x22, 0x73, 0x55, 0x5f, 0x03, 0x25, 0x4f, 0x40, 0xab, 0x07, 0xad, 0xe0, 0xdd,
-            0xd1, 0x99, 0xc7, 0xa2, 0x2d, 0x10, 0xf4, 0x8a, 0xec, 0x73, 0xcc, 0xa6, 0x1b, 0xa6, 0x23, 0x43,
-            0xd2, 0x2c, 0x43, 0x5d, 0x68, 0xe6, 0x39, 0xe9, 0x7a, 0xff, 0x95, 0x22, 0xf5, 0x72, 0xd6, 0xea,
-            0x43, 0x31, 0x77, 0x06, 0x36, 0x95, 0x3b, 0xca, 0x50, 0x69, 0x84, 0x0b, 0xaa, 0xba, 0xd2, 0xb1,
-            0x76, 0x7c, 0x7b, 0x4b, 0x07, 0x38, 0x23, 0x16, 0xce, 0xe8, 0x27, 0x9e, 0xb3, 0x96, 0x81, 0xf5,
-            0x21, 0x33, 0x9c, 0x47, 0x50, 0x2d, 0x34, 0x1b, 0xd2, 0x92, 0x12, 0x49, 0xe6, 0x03, 0x13, 0xec,
-            0x00, 0x95, 0xe4, 0x23, 0x08, 0xb4, 0xe8, 0xb8, 0x7b, 0x99, 0x76, 0x72, 0xba, 0xac, 0x15, 0x73,
-            0x37, 0xd1, 0xb4, 0xfb, 0x68, 0x37, 0x2c, 0xcd, 0x24, 0xdb, 0xb4, 0xcb, 0xbb, 0x6d, 0x58, 0x07,
-            0x62, 0x38, 0x21, 0x38, 0x04, 0x8a, 0xfb, 0xd2, 0xf3, 0x94, 0xaf, 0x66, 0xde, 0x6b, 0xbe, 0x3f,
-            0x50, 0xbc, 0xc3, 0xbf, 0x78, 0xbd, 0x26, 0x64, 0xd2, 0x67, 0x93, 0x62, 0x5b, 0xcc, 0xcf, 0x8a,
-            0x2b, 0x17, 0x36, 0x00, 0x56, 0x6a, 0xa7, 0x05, 0x7a, 0x67, 0x4a, 0x33, 0xc5, 0x08, 0xb2, 0x6a,
-            0x99, 0x7c, 0x4a, 0x6a, 0x90, 0xe6, 0xe3, 0xe4, 0x18, 0x8b, 0x65, 0x6f, 0xc2, 0x45, 0xbb, 0xed,
-            0x83, 0x78, 0x35, 0xc0, 0x62, 0x60, 0xe5, 0x99, 0x80, 0x89, 0x11, 0xf9, 0x63, 0x2a, 0xc9, 0xa3,
-            0xbc, 0x4f, 0x74, 0x41, 0xa0, 0x93, 0x1b, 0x0a, 0x2f, 0x65, 0xbe, 0x88, 0xba, 0x95, 0x76, 0x5b,
-            0x3e, 0x9d, 0x4b, 0x59, 0x9a, 0x5f, 0x42, 0xc0, 0xdc, 0xa5, 0x3e, 0xde, 0xb5, 0xa0, 0xed, 0xcb,
-            0xa5, 0xa8, 0x1e, 0xe4, 0x83, 0xed, 0x49, 0xd3, 0x21, 0x81, 0xd1, 0xc0, 0x97, 0xbb, 0x83, 0x5a,
-            0x12, 0x85, 0xd8, 0x3d, 0xdb, 0xf7, 0xd7, 0xf5, 0xa2, 0x92, 0x39, 0x0f, 0x14, 0x47, 0xe0, 0xc6,
-            0x7c, 0x57, 0xa3, 0xab, 0x47, 0x85, 0x1d, 0x8c, 0x84, 0x08, 0xfb, 0xae, 0xa2, 0xcb, 0xa5, 0x11,
-            0x6a, 0x48, 0xd3, 0x35, 0x0b, 0xb0, 0xf5, 0x64, 0x80, 0xd9, 0x5a, 0x12, 0x03, 0xa6, 0xa3, 0x45,
-            0xfd, 0xa1, 0x73, 0x4e, 0x5b, 0x15, 0x06, 0x65, 0xce, 0x50, 0x79, 0xd3, 0xf4, 0xb8, 0x92, 0x67,
-            0x74, 0xc9, 0xa6, 0x61, 0x17, 0xda, 0x84, 0x9b, 0xc2, 0x8f, 0x1b, 0xcd, 0xc2, 0x35, 0xef, 0xea,
-            0xa5, 0x99, 0xf8, 0x5c, 0xbf, 0x01, 0x90, 0x86, 0x5c, 0xb1, 0x1e, 0x50, 0x91, 0x40, 0x70, 0x60,
-            0x24, 0x46, 0x8d, 0xce, 0x22, 0x56, 0x06, 0x45, 0x31, 0xd4, 0x5d, 0x5d, 0x08, 0x38, 0x30, 0x88,
-            0x76, 0xcc, 0x85, 0x2a, 0x13, 0xd8, 0x12, 0xc3, 0x62, 0x84, 0xc4, 0xef, 0x85, 0xa6, 0x0e, 0x4d,
-            0x60, 0x2c, 0x73, 0x01, 0xb4, 0xd8, 0x20, 0x7b, 0x6e, 0xe6, 0x9b, 0x64, 0x13, 0x11, 0x4b, 0x0a,
-            0xe7, 0x79, 0x53, 0x68, 0xd9, 0xdb, 0x72, 0x6b, 0x6a, 0xe6, 0x33, 0xcd, 0x36, 0x77, 0xcb, 0xf8,
-            0xdb, 0xdd, 0xdd, 0x20, 0x6c, 0x84, 0x76, 0x88, 0xd0, 0x85, 0x10, 0x9c, 0x60, 0xd4, 0x63, 0x6e,
-            0x08, 0x09, 0xdd, 0x17, 0x1c, 0x61, 0x2f, 0xf4, 0x71, 0x69, 0x96, 0x8c, 0x8d, 0xd7, 0xc7, 0xa0,
-            0xc5, 0x1a, 0x32, 0x03, 0xf3, 0xc2, 0x97, 0x69, 0x35, 0xb1, 0xd6, 0x83, 0xbe, 0x79, 0x6b, 0x36,
-            0xd2, 0x5c, 0x44, 0xaf, 0xc8, 0x7b, 0xcb, 0xf1, 0x60, 0xd1, 0x56, 0x27, 0x8a, 0x43, 0xe8, 0x0d,
-            0xdb, 0x8a, 0x17, 0x14, 0x0b, 0x99, 0xc5, 0x93, 0x52, 0x9c, 0x77, 0xa9, 0xbd, 0xdd, 0xaf, 0x45,
-            0x17, 0xe1, 0x66, 0x80, 0xbf, 0x10, 0xda, 0x23, 0xe3, 0xc9, 0xb7, 0xbf, 0x98, 0xbc, 0x15, 0x5a,
-            0x45, 0x0f, 0xf7, 0xb4, 0x9a, 0x04, 0xf4, 0x65, 0x8b, 0x06, 0x88, 0x6c, 0x00, 0xd8, 0xb7, 0x21,
-            0x30, 0x3e, 0xbe, 0x72, 0x64, 0x3d, 0xc2, 0x65, 0xe6, 0x77, 0x7e, 0x24, 0xdc, 0xbf, 0xd8, 0x21,
-            0xb2, 0x32, 0x51, 0x07, 0xc1, 0xac, 0xbb, 0xeb, 0x87, 0x9c, 0x8a, 0xd4, 0x41, 0xc6, 0xe3, 0xcb,
-            0x29, 0xc4, 0x4b, 0x52, 0xc0, 0x0f, 0x90, 0xa7, 0x9d, 0x25, 0xe5, 0xa0, 0x9d, 0x70, 0x3d, 0xd2,
-            0xc6, 0x56, 0xe7, 0xbf, 0x23, 0x5e, 0x09, 0x88, 0x1c, 0xd5, 0x91, 0x09, 0xdb, 0x50, 0x14, 0x8e,
-            0xfb, 0x28, 0x2c, 0xce, 0x34, 0x95, 0x04, 0x19, 0x6e, 0x8b, 0x16, 0x78, 0xf8, 0x06, 0xe7, 0x58,
-            0x36, 0x8f, 0xc9, 0x01, 0xf0, 0x8c, 0x6c, 0xc4, 0xcb, 0x20, 0x46, 0xa8, 0xa8, 0x4a, 0x41, 0x9b,
-            0x2a, 0x8a, 0xee, 0xe4, 0x96, 0x61, 0x61, 0xd0, 0x0d, 0xca, 0x47, 0x28, 0x64, 0x16, 0xfc, 0x4d,
-            0xe6, 0x38, 0x48, 0x93, 0xb6, 0xe4, 0x56, 0xac, 0x24, 0x84, 0x6c, 0xba, 0xec, 0x47, 0x18, 0x34,
-            0xd4, 0x97, 0x71, 0x6e, 0xfb, 0x48, 0x6a, 0x1c, 0xd8, 0x5e, 0x61, 0x66, 0x87, 0x67, 0xe4, 0x7d,
-            0x20, 0x2c, 0x3d, 0xbf, 0x12, 0xae, 0xc9, 0x11, 0xdc, 0xc6, 0x1a, 0x2d, 0x27, 0x67, 0x2d, 0xdb,
-            0x20, 0x9a, 0x1f, 0xb2, 0xde, 0x54, 0x4c, 0x6d, 0x70, 0x06, 0x42, 0xda, 0x2f, 0x00, 0xb1, 0x64,
-            0x04, 0xd7, 0x2b, 0xb8, 0x4b, 0xb3, 0x30, 0xb8, 0x5c, 0xf4, 0xcb, 0x2c, 0x99, 0x5b, 0x28, 0x10,
-            0x41, 0x37, 0x8d, 0x77, 0xe9, 0xbe, 0xf6, 0xeb, 0xc7, 0x46, 0xf6, 0x96, 0x9b, 0x46, 0xdb, 0x48,
-            0xe4, 0xa6, 0x39, 0xf2, 0x0e, 0x99, 0x21, 0x95, 0xc4, 0x31, 0x5f, 0x06, 0x5d, 0x58, 0xc4, 0x2f,
-            0xb6, 0x44, 0xf2, 0xcf, 0x8f, 0x89, 0xb0, 0xc0, 0x14, 0x98, 0x0d, 0x43, 0xe1, 0xd0, 0xd7, 0xb7,
-            0x5e, 0xbf, 0x62, 0x93, 0xc5, 0x19, 0xd8, 0x0f, 0xa4, 0x35, 0x0e, 0xea, 0xd6, 0x75, 0x2d, 0xdc,
-            0x91, 0xe7, 0x5a, 0xbc, 0x25, 0xf9, 0xbd, 0xdd, 0xe4, 0xc8, 0xb8, 0x9c, 0x43, 0x61, 0x94, 0x74,
-            0x60, 0x30, 0xd4, 0x34, 0xb0, 0xbf, 0xf4, 0x69, 0x11, 0x97, 0x4c, 0xa3, 0xcf, 0xed, 0x96, 0x22,
-            0xdb, 0xd1, 0x9d, 0xdc, 0x88, 0xd1, 0x09, 0x82, 0x71, 0x3d, 0x42, 0xcd, 0xcf, 0x6f, 0xe1, 0x24,
-            0x62, 0x34, 0xf7, 0x39, 0x46, 0x93, 0x77, 0xde, 0xb4, 0x2e, 0x16, 0x72, 0x67, 0xb3, 0xb7, 0xb3,
-            0xf3, 0xcd, 0xc9, 0xff, 0xfb, 0xe6, 0x64, 0x8d, 0xd4, 0xd0, 0xd5, 0x36, 0x06, 0x04, 0xee, 0xe0,
-            0x60, 0x41, 0x93, 0xb9, 0xe6, 0x06, 0xba, 0x06, 0x1e, 0xa7, 0xad, 0x05, 0x82, 0xa1, 0x43, 0xa9,
-            0xcd, 0xad, 0xcd, 0x3b, 0x5a, 0xda, 0xbe, 0x57, 0x4b, 0x58, 0xea, 0x14, 0xc4, 0x4b, 0xfe, 0x7e,
-            0x3c, 0xf4, 0x8c, 0xe8, 0x3e, 0x47, 0x57, 0x35, 0xca, 0x37, 0xf6, 0xe5, 0x70, 0x5b, 0xb3, 0x07,
-            0x96, 0x2e, 0x3c, 0x59, 0xda, 0x45, 0x11, 0x4e, 0xd4, 0xd8, 0xdc, 0x02, 0x85, 0x96, 0x01, 0xc4,
-            0x40, 0xfe, 0x1b, 0x85, 0xe7, 0xbe, 0xeb, 0xdb, 0x29, 0xa5, 0x2b, 0xeb, 0xcb, 0xba, 0x82, 0x14,
-            0x21, 0xee, 0xae, 0x10, 0x3c, 0x61, 0x6c, 0x30, 0xf4, 0x47, 0x17, 0xbe, 0x1b, 0xe0, 0xbe, 0x82,
-            0x04, 0x9d, 0x73, 0x60, 0x35, 0xd3, 0x69, 0xd1, 0x19, 0x1e, 0x6b, 0x67, 0x71, 0x52, 0xbf, 0x76,
-            0xfd, 0x29, 0x86, 0x58, 0xc9, 0x78, 0x03, 0x13, 0x67, 0x79, 0xba, 0x96, 0x0a, 0xd3, 0x4b, 0x9f,
-            0x94, 0xfa, 0x12, 0xf8, 0x11, 0x16, 0x88, 0x06, 0x42, 0xc1, 0x52, 0x53, 0xb9, 0x7f, 0xce, 0x3d,
-            0x63, 0xf2, 0x39, 0x37, 0xea, 0xf5, 0x0a, 0xe9, 0x54, 0x3b, 0x96, 0xca, 0x5a, 0x81, 0x86, 0xa9,
-            0x1d, 0x67, 0x30, 0x6d, 0xa2, 0xcc, 0x79, 0x2d, 0x38, 0x6a, 0x6e, 0x1b, 0x54, 0xc4, 0x3b, 0xf4,
-            0x5a, 0x8e, 0xd7, 0x90, 0xa3, 0x87, 0x19, 0x10, 0xef, 0xbb, 0xc9, 0xec, 0x3c, 0x10, 0x12, 0x11,
-            0x38, 0x34, 0xe3, 0x0c, 0x60, 0x93, 0xa4, 0x69, 0xa9, 0xf9, 0xf4, 0x04, 0x86, 0xcc, 0xb4, 0x49,
-            0x70, 0x15, 0xf5, 0xc6, 0x60, 0xd7, 0x06, 0x37, 0x20, 0x06, 0xa4, 0x86, 0x68, 0x82, 0x18, 0x5c,
-            0x1a, 0xcc, 0xe2, 0x4c, 0x40, 0x09, 0x34, 0xdb, 0x72, 0x06, 0x15, 0x52, 0xf4, 0x28, 0x25, 0x8d,
-            0xef, 0x02, 0x00, 0x78, 0xaa, 0x3d, 0x7f, 0xe1, 0xfc, 0x7e, 0xde, 0x68, 0x1f, 0xdf, 0x35, 0x27,
-            0x42, 0xff, 0x19, 0x89, 0x2b, 0xf6, 0x90, 0x7d, 0xc7, 0xbb, 0x5a, 0xfa, 0xd3, 0x05, 0xcd, 0xb9,
-            0x9a, 0xe8, 0xdc, 0xda, 0x52, 0xb3, 0x16, 0xec, 0xed, 0x69, 0x28, 0xaf, 0x63, 0x0f, 0x6c, 0x23,
-            0x9c, 0x0d, 0x44, 0xb3, 0x6e, 0xfd, 0x64, 0xdc, 0xc1, 0x57, 0x3a, 0x88, 0x18, 0x84, 0xeb, 0x7d,
-            0x7b, 0x7b, 0xee, 0x45, 0xc3, 0xc2, 0xd9, 0x69, 0xf5, 0x9c, 0x03, 0x7c, 0xe8, 0x8e, 0xdb, 0x2b,
-            0x6d, 0x9d, 0x19, 0x9c, 0x92, 0x7b, 0xe9, 0x85, 0x1f, 0xd2, 0xc4, 0xfe, 0x40, 0xb3, 0xe1, 0x52,
-            0x93, 0xa6, 0x62, 0x61, 0x47, 0xfc, 0x0e, 0x83, 0x4d, 0xb5, 0x64, 0x93, 0x99, 0x1a, 0x98, 0x94,
-            0xdf, 0x5d, 0xa0, 0xc0, 0xd0, 0xe4, 0x7f, 0xc8, 0xc8, 0x49, 0xcf, 0x75, 0x3d, 0x5a, 0x86, 0x73,
-            0xd2, 0x59, 0x0f, 0x2d, 0xb9, 0x4b, 0xe9, 0xb3, 0x83, 0xd0, 0xeb, 0x3f, 0x91, 0x31, 0x40, 0x1c,
-            0x52, 0x38, 0x1b, 0x1e, 0x49, 0xbe, 0x60, 0xd4, 0xb9, 0x38, 0x24, 0xd9, 0xc6, 0x5a, 0x38, 0x3e,
-            0xe3, 0x95, 0xbf, 0x5e, 0xa0, 0x40, 0x0f, 0x31, 0xb1, 0xd3, 0x60, 0x1b, 0x85, 0x1e, 0x4a, 0x81,
-            0x0b, 0x2b, 0x8f, 0x21, 0x42, 0x78, 0xd0, 0x16, 0xbb, 0x01, 0x7d, 0xe2, 0xe4, 0x90, 0x0c, 0x63,
-            0xc2, 0x61, 0x24, 0x94, 0x67, 0x47, 0x32, 0xe9, 0xbd, 0xf2, 0x16, 0x87, 0xb1, 0x20, 0x1f, 0xa5,
-            0xbf, 0xe6, 0x26, 0x95, 0xd7, 0xdd, 0xa4, 0xf8, 0xda, 0x5a, 0xe1, 0x43, 0x65, 0x98, 0x5d, 0xba,
-            0xd4, 0x72, 0x73, 0x63, 0xf1, 0x85, 0x95, 0xcb, 0x0b, 0x2b, 0xea, 0x4a, 0x97, 0x35, 0x27, 0x96,
-            0xa6, 0x9c, 0xad, 0xbf, 0xbb, 0xa5, 0xcd, 0x4d, 0x9c, 0x9b, 0x22, 0x2e, 0xc0, 0xee, 0x82, 0xd4,
-            0x9d, 0x48, 0x2d, 0x6c, 0x63, 0x90, 0x6a, 0xab, 0x31, 0xe2, 0x89, 0xb8, 0x92, 0xa6, 0x1c, 0x06,
-            0xb9, 0x22, 0x17, 0xed, 0x85, 0x09, 0x86, 0x08, 0x87, 0xdd, 0xc7, 0x52, 0xc2, 0xcc, 0x6d, 0x91,
-            0xd9, 0x87, 0x5c, 0xd3, 0xc0, 0xc3, 0x6e, 0x58, 0x8c, 0x7c, 0x3b, 0xdb, 0x8b, 0xfe, 0xb3, 0xbb,
-            0x34, 0x20, 0x55, 0x86, 0x21, 0xc2, 0xbe, 0xd0, 0x5a, 0xa7, 0x2c, 0x4b, 0xf6, 0x66, 0x67, 0x92,
-            0x41, 0xf0, 0x28, 0x83, 0x61, 0xd0, 0x45, 0xb8, 0xd1, 0xfe, 0xab, 0x4c, 0x1c, 0x29, 0x6e, 0x43,
-            0xa4, 0x21, 0x66, 0x51, 0x86, 0xbc, 0x26, 0xbc, 0x4d, 0x16, 0x53, 0xd6, 0x91, 0xdd, 0x09, 0xe4,
-            0xbd, 0x4d, 0x82, 0x29, 0xeb, 0x78, 0x02, 0x3c, 0x70, 0xf7, 0xa3, 0xbb, 0xc1, 0x24, 0x94, 0xa8,
-            0xe8, 0xba, 0xc0, 0x9c, 0xa4, 0xba, 0x14, 0xcb, 0x1d, 0x9a, 0x46, 0x14, 0xc3, 0x43, 0x70, 0x22,
-            0x60, 0xea, 0xd2, 0x6a, 0x98, 0x0e, 0x28, 0x0c, 0x59, 0xde, 0x42, 0x00, 0x3a, 0xb6, 0x45, 0xc7,
-            0x2b, 0x78, 0x28, 0xe9, 0x7a, 0xe5, 0xd8, 0xbf, 0x4e, 0x5b, 0x84, 0xbc, 0x6e, 0x2b, 0x55, 0x66,
-            0x59, 0x3b, 0xbb, 0xd0, 0xcf, 0x9b, 0x8c, 0x1e, 0x5a, 0xd0, 0x74, 0x17, 0x5f, 0x8c, 0x60, 0xcb,
-            0xa6, 0x82, 0x05, 0x91, 0xa4, 0xa5, 0xda, 0xa5, 0x95, 0x2f, 0x18, 0x7b, 0xb9, 0x60, 0x85, 0x63,
-            0xa6, 0x41, 0x8e, 0x7c, 0x98, 0xcc, 0x65, 0x48, 0x2a, 0xbc, 0x0e, 0x88, 0x14, 0x45, 0xb2, 0x3f,
-            0xba, 0xda, 0xeb, 0x86, 0xa5, 0x2d, 0x2d, 0xb5, 0x55, 0x67, 0xdb, 0x54, 0x22, 0x4a, 0xe2, 0xb7,
-            0xda, 0xb8, 0x55, 0x7c, 0x91, 0xf8, 0xee, 0x59, 0x88, 0xe5, 0x9d, 0x02, 0x81, 0xe2, 0x95, 0xa3,
-            0x11, 0x59, 0xb7, 0x73, 0x82, 0x46, 0x66, 0xdd, 0x9d, 0xf3, 0x38, 0x7a, 0xf0, 0x70, 0xfb, 0xc1,
-            0xb7, 0x51, 0x4d, 0xa1, 0x22, 0x7c, 0xad, 0x42, 0x39, 0x36, 0x62, 0xaf, 0x3d, 0x78, 0xd3, 0xa6,
-            0xb8, 0x20, 0xdc, 0x04, 0x79, 0x8b, 0xb3, 0xf9, 0xd9, 0x99, 0x7b, 0xc1, 0x88, 0x15, 0x65, 0xa8,
-            0x37, 0x32, 0xdf, 0x32, 0xf6, 0x6a, 0xcc, 0xb1, 0x33, 0xd1, 0x94, 0x46, 0x28, 0xa0, 0x9c, 0xc9,
-            0x60, 0xca, 0xbf, 0x80, 0x34, 0x33, 0x82, 0x64, 0xbd, 0xa4, 0xf8, 0x27, 0xde, 0x9f, 0x2b, 0x98,
-            0x97, 0x89, 0xf7, 0xdc, 0x02, 0x40, 0xc2, 0x9b, 0xcb, 0x49, 0xc5, 0x61, 0x95, 0xd0, 0x1d, 0x08,
-            0x0c, 0xf2, 0xe0, 0x2b, 0x0c, 0xea, 0x09, 0x32, 0x71, 0xdd, 0x88, 0xb5, 0x1a, 0x46, 0xc5, 0xe8,
-            0x88, 0x78, 0x9d, 0x34, 0xb6, 0x20, 0xfe, 0x47, 0xaa, 0x7c, 0x88, 0x45, 0x0b, 0x16, 0xb9, 0x95,
-            0x2f, 0xe5, 0xe8, 0xfa, 0x41, 0x1e, 0x74, 0x89, 0x47, 0x9e, 0x3f, 0x6b, 0x17, 0x97, 0xc6, 0x06,
-            0xf9, 0x04, 0xb5, 0xc3, 0x7b, 0xbe, 0x31, 0x6c, 0x8a, 0xd5, 0x0f, 0x12, 0x8f, 0x46, 0xbd, 0xe2,
-            0xd0, 0xec, 0x4f, 0xc9, 0xf9, 0x07, 0xf2, 0x77, 0x7a, 0x36, 0x24, 0x37, 0xa2, 0x26, 0xa4, 0xb6,
-            0x40, 0x91, 0x47, 0xef, 0x73, 0xf0, 0x8e, 0x95, 0xde, 0x08, 0xf5, 0x99, 0xbd, 0xb2, 0x0b, 0x76,
-            0xc8, 0xd6, 0x9e, 0xda, 0x83, 0x01, 0x66, 0xe0, 0x67, 0xca, 0x1b, 0x06, 0x3e, 0x18, 0x49, 0x81,
-            0x8c, 0x5b, 0xd8, 0x12, 0xc8, 0xb3, 0x3e, 0x18, 0x0f, 0xea, 0x60, 0x41, 0xa9, 0x30, 0x79, 0x80,
-            0x72, 0x39, 0xd4, 0x4f, 0x43, 0xeb, 0x74, 0x8e, 0x60, 0x96, 0xa5, 0xb5, 0x6e, 0x7f, 0xcb, 0x52,
-            0x68, 0x94, 0x5a, 0x0a, 0x22, 0x0c, 0x47, 0xfd, 0x59, 0x7b, 0x72, 0xff, 0x01, 0x6d, 0xfa, 0x67,
-            0x5c, 0x3d, 0x18, 0x29, 0xc4, 0xba, 0xed, 0xae, 0x0a, 0x63, 0xcb, 0x28, 0x7b, 0x38, 0x2f, 0xd1,
-            0x65, 0x68, 0x1b, 0xc5, 0x0e, 0xdb, 0x80, 0x8e, 0xac, 0x93, 0x47, 0x44, 0x8c, 0x1e, 0xb4, 0xe6,
-            0x14, 0x70, 0x2e, 0xf6, 0xac, 0x4b, 0xe1, 0x10, 0xb4, 0x82, 0xd7, 0xf8, 0xa4, 0x45, 0x70, 0x86,
-            0xa6, 0x00, 0xec, 0xfe, 0xbe, 0x25, 0x03, 0xff, 0xf4, 0x83, 0x0f, 0x47, 0xe3, 0x3d, 0x86, 0x34,
-            0x47, 0x5d, 0x41, 0x44, 0x47, 0x33, 0xac, 0xd1, 0x56, 0x3f, 0x68, 0x8f, 0xcf, 0x4a, 0x1e, 0x07,
-            0xbb, 0xc0, 0xd8, 0xab, 0xd4, 0x88, 0xfa, 0x58, 0xfa, 0xf7, 0x4b, 0x10, 0xc6, 0xbe, 0xfe, 0xc8,
-            0xd9, 0x23, 0x34, 0xc8, 0x5b, 0x1d, 0xec, 0x97, 0x17, 0xd1, 0x0e, 0x7e, 0x88, 0xb5, 0xdc, 0xe8,
-            0x21, 0x54, 0xe2, 0x7b, 0x7f, 0x4b, 0x65, 0x60, 0xa5, 0x5b, 0x6b, 0xe7, 0x3c, 0xd8, 0x89, 0x5a,
-            0x23, 0x40, 0x0c, 0x18, 0x0e, 0x63, 0x95, 0x37, 0x1e, 0x5e, 0xf3, 0x48, 0x4a, 0xcc, 0x4b, 0x0c,
-            0x7a, 0x88, 0x2c, 0x1e, 0xd9, 0xdd, 0x22, 0x84, 0xc5, 0x0f, 0x9d, 0x10, 0xc2, 0x82, 0xe8, 0x02,
-            0x8a, 0x41, 0x9c, 0x2d, 0x1b, 0x5d, 0x03, 0x58, 0x2a, 0x7a, 0xf8, 0xaa, 0x34, 0x8f, 0x5e, 0x81,
-            0xf6, 0x89, 0x6e, 0x99, 0x9a, 0xda, 0xca, 0x0c, 0x0a, 0x87, 0xb9, 0x47, 0xfc, 0x2f, 0x0a, 0x1a,
-            0x80, 0x0d, 0xbc, 0x00, 0x21, 0x2e, 0x0d, 0xd4, 0xc8, 0x71, 0x09, 0xdb, 0x56, 0xd6, 0x98, 0xca,
-            0x8e, 0xf3, 0xf1, 0xca, 0x65, 0xa5, 0xc1, 0x1a, 0xbb, 0x91, 0x5a, 0x9d, 0x5d, 0xc6, 0x31, 0x77,
-            0x42, 0x6d, 0xb8, 0x56, 0x31, 0x05, 0x81, 0x66, 0xdb, 0xd3, 0x6c, 0x4c, 0x36, 0xce, 0x66, 0xf6,
-            0x77, 0xd9, 0x2f, 0xca, 0x21, 0x19, 0xa3, 0x6d, 0xf0, 0xf1, 0x84, 0xc7, 0x05, 0xfb, 0x2a, 0x98,
-            0x5a, 0x8b, 0x3d, 0xe1, 0xf7, 0xda, 0x44, 0x63, 0x92, 0xe0, 0xc7, 0x76, 0x8e, 0xc1, 0x9e, 0xe7,
-            0xff, 0x07, 0x7b, 0x9e, 0xd7, 0xf7, 0x3c, 0x0f, 0xf6, 0xdc, 0xbd, 0x8e, 0xa1, 0x7c, 0xb8, 0xec,
-            0x5a, 0x40, 0xdb, 0x80, 0x35, 0x71, 0x3b, 0x22, 0x1f, 0xc7, 0x13, 0xaf, 0x17, 0xd4, 0xc3, 0xde,
-            0x58, 0x87, 0xa7, 0x1e, 0xbe, 0x44, 0xd3, 0x1e, 0x7d, 0xd5, 0x16, 0xe1, 0xb3, 0x6c, 0xec, 0x20,
-            0x46, 0xdb, 0x67, 0x37, 0x14, 0xf0, 0xa3, 0x2e, 0xbb, 0x6e, 0x73, 0x19, 0x34, 0x55, 0x22, 0x81,
-            0xd9, 0xf2, 0x9e, 0x73, 0xc2, 0x14, 0x81, 0x71, 0x25, 0x7e, 0xf9, 0x64, 0x2d, 0x74, 0x75, 0xf2,
-            0x59, 0x3b, 0x64, 0x07, 0xac, 0xf5, 0x5d, 0x0b, 0xbe, 0x12, 0xdd, 0x61, 0x60, 0x53, 0x70, 0x87,
-            0xf8, 0x2a, 0xb6, 0x0b, 0xc3, 0xb1, 0x84, 0xe8, 0x6d, 0x53, 0xa0, 0x37, 0x6b, 0x8b, 0xbc, 0x96,
-            0x35, 0x91, 0x9c, 0xc8, 0xdb, 0x74, 0x3c, 0x60, 0xcb, 0xe1, 0x63, 0x72, 0xd8, 0xbc, 0xac, 0x78,
-            0x94, 0x5e, 0x02, 0xa4, 0x2f, 0x70, 0x5c, 0x70, 0x8c, 0xed, 0xfb, 0x8c, 0x53, 0x32, 0x92, 0x19,
-            0x18, 0x8c, 0xb8, 0x6c, 0xc1, 0x64, 0xe6, 0x09, 0xc7, 0xae, 0xf9, 0xb4, 0xe4, 0x0d, 0xb8, 0x26,
-            0x42, 0x77, 0x0b, 0x23, 0x09, 0xc7, 0xd7, 0xe6, 0x3c, 0x9e, 0x8c, 0x03, 0xa3, 0x0b, 0x71, 0x73,
-            0xff, 0xa4, 0xeb, 0x7e, 0xa8, 0x2d, 0x0f, 0xf7, 0xd5, 0x02, 0x91, 0x17, 0xe5, 0xf9, 0xc7, 0x1e,
-            0x76, 0xf3, 0xb1, 0x47, 0x50, 0xbe, 0x7d, 0x46, 0x45, 0x93, 0x93, 0xdf, 0x36, 0x4e, 0xbf, 0xd9,
-            0x78, 0x42, 0xe6, 0x19, 0x64, 0x85, 0x88, 0xd7, 0xf3, 0x06, 0xf2, 0x40, 0xf4, 0xeb, 0x09, 0xf3,
-            0x12, 0xc1, 0x43, 0x50, 0xcb, 0xbb, 0xe6, 0x67, 0x9f, 0xac, 0x24, 0x54, 0xd4, 0x9c, 0x5d, 0x44,
-            0x17, 0x1a, 0xdd, 0x8e, 0x22, 0xec, 0x70, 0x63, 0x3e, 0x7f, 0x75, 0xd1, 0xa8, 0xd9, 0x41, 0xad,
-            0xd9, 0x5f, 0xb4, 0x89, 0x00, 0xa4, 0xda, 0xbc, 0xa5, 0xfc, 0xa3, 0x5c, 0x92, 0x66, 0xfa, 0x51,
-            0xd7, 0xe3, 0xc0, 0xff, 0xfc, 0xfa, 0xd5, 0x4b, 0x88, 0x01, 0x6f, 0x5c, 0x35, 0xfd, 0x4b, 0x72,
-            0x55, 0xeb, 0x83, 0x9a, 0x95, 0x78, 0x49, 0x53, 0x38, 0x17, 0xf5, 0x77, 0x97, 0xee, 0x22, 0x64,
-            0xd8, 0x51, 0xf1, 0xf5, 0xa4, 0x0c, 0x21, 0x08, 0x4f, 0x12, 0x35, 0xc0, 0xd6, 0x57, 0xc8, 0x4d,
-            0x83, 0xb7, 0x08, 0xb0, 0xdb, 0xdf, 0xed, 0x1f, 0x47, 0xd6, 0xba, 0xa5, 0xed, 0x96, 0x6c, 0xbe,
-            0x2c, 0x68, 0xa2, 0xa7, 0x99, 0x2f, 0xe3, 0xc0, 0x12, 0xbd, 0xfc, 0x79, 0xfb, 0x9d, 0x7d, 0x78,
-            0xd3, 0x30, 0x61, 0xcb, 0x15, 0xe5, 0x0c, 0xb4, 0x6f, 0x9b, 0xa6, 0x1b, 0xf5, 0x06, 0x2b, 0xea,
-            0xed, 0x99, 0x83, 0x0d, 0xd1, 0xf3, 0xa3, 0x1a, 0xfc, 0xe2, 0x74, 0x72, 0x94, 0x91, 0xd7, 0x94,
-            0x44, 0xe8, 0x1f, 0x80, 0x1e, 0x44, 0x7a, 0x5e, 0x3d, 0x4e, 0x40, 0x91, 0x06, 0x76, 0x24, 0x3e,
-            0xe5, 0xd1, 0x3f, 0x76, 0x4d, 0xac, 0x6b, 0xf6, 0xc5, 0x49, 0x28, 0xcf, 0x7e, 0xdd, 0x71, 0x55,
-            0xd2, 0x71, 0xc0, 0x67, 0x50, 0x5f, 0x91, 0x54, 0x1e, 0xe8, 0xc7, 0x3f, 0x31, 0x60, 0x81, 0x5f,
-            0xee, 0xd8, 0x37, 0x0a, 0x7c, 0xe4, 0x22, 0x74, 0xc8, 0xea, 0x07, 0x25, 0x43, 0x6f, 0x5d, 0xa3,
-            0x09, 0x43, 0x68, 0x2b, 0x09, 0x3f, 0x75, 0xef, 0x18, 0x86, 0x59, 0x3f, 0x8b, 0x31, 0xcc, 0x95,
-            0x46, 0xcf, 0xb3, 0x12, 0x6f, 0xc1, 0x5a, 0x10, 0xeb, 0x69, 0xd4, 0xf7, 0x63, 0x5a, 0x7a, 0x33,
-            0xd2, 0xfb, 0xcc, 0xd0, 0xdc, 0x9c, 0xa5, 0x51, 0xa0, 0xdd, 0x63, 0x5d, 0x28, 0x72, 0x19, 0x81,
-            0x09, 0xbc, 0x76, 0x24, 0x95, 0x09, 0x8a, 0xaf, 0x15, 0x44, 0xeb, 0x70, 0xf0, 0xef, 0x8f, 0x8b,
-            0x75, 0xf2, 0xbd, 0x10, 0x0a, 0xfe, 0xa7, 0xe7, 0xc4, 0xd2, 0x41, 0xda, 0x90, 0x85, 0xcd, 0x73,
-            0x43, 0x64, 0xcf, 0xdd, 0x07, 0xe7, 0xeb, 0x2b, 0xf0, 0x12, 0x98, 0x7f, 0x5a, 0x80, 0x3a, 0x54,
-            0x68, 0xe7, 0x29, 0xfc, 0x15, 0xa0, 0x60, 0xba, 0x4d, 0x9b, 0x77, 0x72, 0xfe, 0x2a, 0x38, 0x38,
-            0xdf, 0x7e, 0x79, 0x9c, 0xdb, 0x5e, 0xf1, 0x65, 0xc6, 0xca, 0xac, 0x77, 0xa9, 0xf0, 0xfc, 0x30,
-            0x49, 0xc0, 0xd5, 0x7f, 0x64, 0xa5, 0xa9, 0x70, 0xd9, 0xf1, 0x51, 0xf4, 0x92, 0x2b, 0x1b, 0x91,
-            0xd2, 0x3f, 0xc6, 0xcb, 0xdb, 0xe3, 0x9d, 0x5a, 0x90, 0x5e, 0x69, 0x44, 0x38, 0xa8, 0x9b, 0xd0,
-            0x58, 0x1a, 0x05, 0x1e, 0x43, 0xc1, 0x88, 0x47, 0xc1, 0xf7, 0xed, 0xed, 0x2e, 0x84, 0x0e, 0x1c,
-            0xd4, 0x1c, 0x66, 0xcd, 0xe3, 0x34, 0x3e, 0x31, 0x6e, 0x25, 0x78, 0x04, 0xa1, 0x21, 0x34, 0x08,
-            0x79, 0xdb, 0x14, 0x1c, 0x3d, 0x03, 0x9c, 0x49, 0x73, 0x16, 0xff, 0x57, 0x93, 0xa8, 0x69, 0xe3,
-            0x2d, 0x41, 0x44, 0x97, 0x63, 0xab, 0xae, 0xbe, 0x4e, 0x66, 0x51, 0xd1, 0xd6, 0x59, 0x95, 0x46,
-            0x37, 0x9c, 0x19, 0x6f, 0xf4, 0x21, 0x8a, 0xbf, 0xba, 0xff, 0xc5, 0x90, 0x1f, 0x76, 0xb7, 0x1f,
-            0x32, 0xd9, 0xa7, 0xee, 0x68, 0x85, 0x04, 0x48, 0x41, 0x43, 0xec, 0xa3, 0xdf, 0xf0, 0x00, 0xbe,
-            0xf7, 0x96, 0x2d, 0x5b, 0x62, 0x62, 0xdc, 0xb3, 0xcf, 0x3b, 0x48, 0xce, 0x95, 0x31, 0x2c, 0x1a,
-            0x2b, 0x1c, 0x0a, 0x39, 0x28, 0xa6, 0x74, 0x7e, 0x1f, 0xdd, 0x71, 0xe9, 0x74, 0xc7, 0x18, 0xe8,
-            0xf3, 0x08, 0x10, 0x19, 0xd1, 0xd7, 0xf9, 0xfd, 0x2c, 0x23, 0xab, 0x60, 0x9e, 0x8a, 0xe7, 0x68,
-            0xcc, 0x99, 0xd9, 0x32, 0x98, 0x3f, 0xd8, 0x70, 0x56, 0x5b, 0x3b, 0xe4, 0x11, 0x2a, 0x2a, 0x50,
-            0xc2, 0x98, 0xa9, 0xe9, 0x08, 0xe0, 0xe7, 0xc4, 0xa6, 0x9f, 0x46, 0x75, 0x31, 0x20, 0x4b, 0x2e,
-            0x8d, 0x01, 0xa5, 0xb1, 0x5b, 0x27, 0xe3, 0xe2, 0xd0, 0x50, 0xb4, 0x66, 0x6f, 0x9c, 0x5d, 0x00,
-            0x75, 0x5d, 0x4f, 0xc4, 0xd8, 0x7e, 0x8d, 0x92, 0x10, 0x5a, 0x49, 0x45, 0x77, 0xf5, 0x09, 0x68,
-            0x71, 0xf8, 0xe5, 0xac, 0xb8, 0x0e, 0x7a, 0x2d, 0xd3, 0x51, 0x56, 0x08, 0xeb, 0xd4, 0x1e, 0x95,
-            0x82, 0x87, 0x4b, 0xe5, 0x9a, 0x79, 0xeb, 0xf6, 0x5c, 0x06, 0x9d, 0xe2, 0x88, 0x26, 0xe4, 0xfa,
-            0xe7, 0x02, 0x23, 0x86, 0x9a, 0x0b, 0xb5, 0x52, 0xc2, 0x9b, 0xbb, 0x87, 0xf8, 0x58, 0xb5, 0xc0,
-            0xce, 0xd9, 0x41, 0xa2, 0x8c, 0x40, 0x97, 0x77, 0x7c, 0xdc, 0x6b, 0xd7, 0xaf, 0x0b, 0x5a, 0x67,
-            0x83, 0x88, 0xa3, 0x61, 0x2c, 0x3d, 0xfc, 0x32, 0x68, 0x8c, 0x24, 0x37, 0x74, 0xae, 0x09, 0x40,
-            0x05, 0x2a, 0x37, 0x2f, 0xe8, 0x57, 0x68, 0xf5, 0x67, 0x1d, 0x6f, 0x65, 0x11, 0xf2, 0x69, 0x44,
-            0xbf, 0x0d, 0x0e, 0xeb, 0xd3, 0xd1, 0xe6, 0x38, 0x42, 0x56, 0x29, 0x87, 0x2a, 0xaf, 0xd7, 0xb9,
-            0xf3, 0xc8, 0xaf, 0x5b, 0xd3, 0x32, 0x03, 0x23, 0x1f, 0x73, 0x04, 0x71, 0x53, 0x36, 0xf3, 0x06,
-            0x71, 0xf0, 0x5e, 0x56, 0x5b, 0x3c, 0x45, 0x0e, 0x84, 0xdd, 0x37, 0x1b, 0x83, 0x66, 0xe6, 0xed,
-            0xaf, 0xd8, 0xae, 0x19, 0x4b, 0xce, 0x25, 0x9b, 0x72, 0xd4, 0xbb, 0xa7, 0xb7, 0x83, 0x45, 0xef,
-            0x08, 0x2f, 0x55, 0xd0, 0x35, 0xa7, 0x2c, 0x6b, 0xad, 0x79, 0x99, 0xa8, 0xd9, 0x04, 0x00, 0x80,
-            0xc2, 0x86, 0xad, 0x36, 0x76, 0xe4, 0x39, 0x2f, 0x43, 0x60, 0xa6, 0x28, 0x44, 0xcb, 0x20, 0xf9,
-            0xcf, 0xc5, 0x5b, 0x7e, 0x64, 0xbe, 0x0e, 0x68, 0x1f, 0x4f, 0x14, 0xfa, 0x9a, 0x80, 0xa9, 0x69,
-            0x4c, 0xcb, 0x66, 0xe3, 0x8b, 0x01, 0x9b, 0x86, 0xd8, 0xb4, 0x64, 0x56, 0xa4, 0x31, 0x13, 0x7c,
-            0x41, 0xdb, 0x85, 0x01, 0x23, 0x7c, 0xab, 0xf8, 0xab, 0x11, 0x15, 0x41, 0x8b, 0x3d, 0x7e, 0x4c,
-            0xae, 0xdc, 0xb9, 0x0d, 0x34, 0x6c, 0x3b, 0x6c, 0x19, 0xac, 0xec, 0x1f, 0x62, 0x79, 0xa0, 0x6a,
-            0x0c, 0x7a, 0xc4, 0x17, 0x96, 0xd1, 0x5c, 0xba, 0x09, 0xcd, 0xd6, 0x00, 0x5d, 0x8e, 0x13, 0x6c,
-            0x90, 0x29, 0xf0, 0xa4, 0x43, 0x21, 0x6e, 0x71, 0xdc, 0x19, 0x0a, 0x0c, 0xd9, 0xd3, 0x9a, 0x69,
-            0x91, 0x62, 0x23, 0x98, 0xab, 0x6c, 0x3a, 0xa5, 0xa7, 0xc3, 0x81, 0x23, 0x32, 0x8e, 0xdc, 0x4c,
-            0x70, 0x5c, 0x72, 0x22, 0x02, 0x86, 0xf9, 0x69, 0x5e, 0xc8, 0x5b, 0xcf, 0xf9, 0x08, 0xdb, 0x07,
-            0xc7, 0x91, 0x5b, 0x67, 0x7a, 0xa9, 0xa5, 0xea, 0x18, 0xe4, 0xa8, 0x24, 0x6b, 0xba, 0x00, 0x6e,
-            0x1e, 0x1f, 0xc1, 0x26, 0xf3, 0x50, 0x93, 0xfb, 0x9a, 0xd3, 0xe2, 0x4b, 0xd3, 0x92, 0xcd, 0x84,
-            0x9f, 0xcb, 0x2e, 0xf9, 0x72, 0x5a, 0x5f, 0x66, 0x71, 0x93, 0xb4, 0xbc, 0x75, 0x8e, 0x87, 0x3d,
-            0xcc, 0xe8, 0x74, 0xad, 0x3b, 0x33, 0x59, 0xd3, 0xe4, 0xf1, 0x5f, 0xee, 0x5e, 0x22, 0x87, 0x49,
-            0x4e, 0x51, 0x4a, 0x6b, 0x11, 0x68, 0x01, 0x7e, 0x29, 0x80, 0x1f, 0xba, 0x99, 0xfa, 0xf3, 0xdb,
-            0xea, 0xa0, 0x10, 0xeb, 0x06, 0x3e, 0x1a, 0x34, 0xbd, 0x51, 0x47, 0xb5, 0x1d, 0x72, 0x9e, 0x9f,
-            0xfc, 0x06, 0xa3, 0x05, 0x91, 0x81, 0x0c, 0xbc, 0x50, 0x4b, 0x0c, 0x9e, 0x37, 0x71, 0x77, 0x69,
-            0xd5, 0xd4, 0xaf, 0x73, 0x04, 0x98, 0x96, 0x0c, 0x94, 0x33, 0xaf, 0x52, 0xc7, 0x23, 0x16, 0x9c,
-            0x26, 0x77, 0x9d, 0x16, 0x02, 0xc8, 0xc2, 0xc2, 0x93, 0x31, 0xb0, 0xbf, 0xbd, 0xb5, 0xee, 0x5f,
-            0x1e, 0x90, 0x9c, 0x16, 0x6f, 0xc5, 0xf8, 0x00, 0xe5, 0x26, 0x80, 0x80, 0x5b, 0x72, 0x48, 0x7b,
-            0xff, 0xa6, 0xde, 0xc7, 0x92, 0xd1, 0x36, 0x7b, 0x94, 0xc0, 0x4e, 0xe5, 0x14, 0xe8, 0x27, 0x8b,
-            0x49, 0xf3, 0x1f, 0xa3, 0x6f, 0x51, 0x4e, 0xe1, 0xbf, 0x20, 0xcc, 0x41, 0x3c, 0x5d, 0xb5, 0x28,
-            0xf4, 0xc6, 0xa8, 0x08, 0x73, 0xf8, 0xfe, 0xf8, 0xf8, 0xf0, 0x4d, 0x54, 0x4b, 0x3d, 0x78, 0xf3,
-            0xf6, 0xfd, 0x71, 0x64, 0x1d, 0x8d, 0x1a, 0x0a, 0x41, 0xef, 0x52, 0xdb, 0xde, 0xc1, 0xc0, 0x7a,
-            0xbb, 0x42, 0xfd, 0xb9, 0xc4, 0x50, 0x63, 0xb0, 0xec, 0xe5, 0x70, 0x9b, 0x85, 0x35, 0xe6, 0x19,
-            0x4a, 0x02, 0x9c, 0x1c, 0x64, 0x38, 0x9c, 0xd8, 0x30, 0xc0, 0x42, 0x6e, 0x66, 0xac, 0x92, 0xe0,
-            0xd9, 0xad, 0x07, 0x8e, 0x6f, 0x19, 0xc7, 0x79, 0x6d, 0xa2, 0xfe, 0xa2, 0x46, 0x40, 0x06, 0xab,
-            0xc4, 0x36, 0x85, 0x13, 0xf4, 0x46, 0x77, 0x41, 0xe8, 0x58, 0xd7, 0x52, 0xf5, 0xb3, 0x78, 0x6c,
-            0x20, 0x0f, 0x24, 0xcf, 0x97, 0xfc, 0x5e, 0xfc, 0x97, 0x3c, 0x0c, 0xc0, 0x37, 0x93, 0xef, 0xbf,
-            0x29, 0xe3, 0x80, 0xac, 0xc0, 0x2d, 0x74, 0x23, 0xc2, 0xed, 0x3a, 0xb2, 0x8f, 0xf3, 0xc8, 0x07,
-            0x28, 0x39, 0x32, 0x26, 0xba, 0xd2, 0x43, 0x10, 0xf6, 0x50, 0x1a, 0x2c, 0xc2, 0x6e, 0xab, 0x7c,
-            0x08, 0x94, 0xd7, 0xfb, 0x77, 0x07, 0xa8, 0x5e, 0x05, 0x39, 0x67, 0x4e, 0xc1, 0x08, 0xa0, 0xe9,
-            0x96, 0x0c, 0xdd, 0xdd, 0x8a, 0x12, 0xb0, 0x87, 0x69, 0x79, 0xb3, 0xee, 0x9c, 0xc5, 0x39, 0xc9,
-            0xf3, 0xdc, 0x5a, 0x4a, 0x91, 0x57, 0xf9, 0xca, 0x13, 0x9c, 0xcc, 0x70, 0x79, 0x56, 0x9e, 0xdf,
-            0x8b, 0xbc, 0xee, 0x8b, 0xb2, 0x90, 0x12, 0x93, 0x3e, 0x03, 0x7c, 0x8c, 0x69, 0xc7, 0x46, 0x3f,
-            0xdd, 0x67, 0x28, 0xc2, 0x38, 0x4a, 0x32, 0x7d, 0x1b, 0x81, 0xcd, 0x66, 0x32, 0x88, 0x70, 0x36,
-            0xbb, 0xcc, 0xf6, 0x53, 0x1b, 0xe4, 0x38, 0xae, 0x8b, 0x4c, 0xfa, 0xa1, 0x9f, 0xd5, 0x60, 0x2f,
-            0x37, 0x00, 0x34, 0x21, 0x11, 0x0b, 0x30, 0xed, 0x44, 0xb7, 0x51, 0x08, 0x2c, 0x0a, 0xca, 0x1b,
-            0xbc, 0x2d, 0x7f, 0x82, 0xcd, 0x61, 0x2c, 0x17, 0x78, 0x8b, 0xf4, 0x34, 0x21, 0x3d, 0x6c, 0xe0,
-            0xc1, 0x63, 0x8b, 0x3c, 0xe3, 0x4f, 0x28, 0x63, 0x22, 0x1a, 0x34, 0xfd, 0x3f, 0x6f, 0x0c, 0xce,
-            0x6c, 0x3c, 0x85, 0x30, 0x43, 0xd9, 0x62, 0xd5, 0x78, 0x0a, 0x81, 0x02, 0x32, 0x06, 0xfa, 0x56,
-            0x8b, 0xda, 0x9c, 0x72, 0x5f, 0xf3, 0x43, 0xdb, 0x2d, 0x5e, 0x9e, 0x5a, 0xbc, 0x6a, 0x54, 0xf8,
-            0x47, 0x8d, 0x28, 0x70, 0x2b, 0xcb, 0x1d, 0xff, 0xd1, 0x15, 0xb1, 0x4c, 0x42, 0x69, 0x9e, 0x7f,
-            0xa5, 0xcb, 0xa1, 0xf1, 0x70, 0x83, 0x83, 0x07, 0x32, 0x02, 0xa4, 0xcb, 0x1d, 0xb4, 0xb4, 0xcb,
-            0x11, 0xfb, 0x45, 0x98, 0x33, 0x7a, 0xf7, 0x80, 0xd4, 0x9c, 0xb9, 0x27, 0x22, 0x5b, 0xe9, 0xd6,
-            0xb2, 0x46, 0xb7, 0xfa, 0x91, 0x94, 0xcb, 0xf0, 0x11, 0x72, 0xf9, 0x4e, 0x4a, 0xf0, 0x3e, 0xf8,
-            0x3d, 0x3d, 0x22, 0x83, 0x97, 0x44, 0xcf, 0x6a, 0x97, 0x0f, 0xf0, 0x87, 0x6e, 0xcb, 0x50, 0x32,
-            0x22, 0x82, 0xf1, 0x0b, 0x89, 0x4c, 0x00, 0x1d, 0x4f, 0x84, 0x7c, 0xa6, 0xbf, 0x3a, 0xb8, 0xa2,
-            0x97, 0xdc, 0xb4, 0x95, 0xa1, 0x9c, 0x40, 0xa2, 0xd3, 0x28, 0xe5, 0xf3, 0x96, 0x81, 0x30, 0x33,
-            0x8c, 0x08, 0x75, 0x98, 0x13, 0x94, 0x82, 0x83, 0x49, 0xe8, 0x83, 0xb6, 0x7e, 0xcd, 0x94, 0x22,
-            0x85, 0xd7, 0xbf, 0x02, 0x00, 0x2e, 0x66, 0x91, 0x79, 0x83, 0xcf, 0x5e, 0x9c, 0xcf, 0x4c, 0xd8,
-            0x7f, 0x19, 0x70, 0xfa, 0xae, 0xf0, 0x37, 0x3e, 0x3c, 0x9d, 0x79, 0x0b, 0xcd, 0x2f, 0x33, 0x4e,
-            0xb6, 0xef, 0x9e, 0x63, 0xf3, 0x11, 0x88, 0xc0, 0x2d, 0x7d, 0xea, 0x1f, 0xda, 0xf2, 0x26, 0x38,
-            0xa2, 0x26, 0x4d, 0x53, 0xd6, 0xf5, 0xf3, 0x16, 0xb5, 0xff, 0xd5, 0x5e, 0xdb, 0xc7, 0x8c, 0x12,
-            0x2d, 0xf8, 0xc4, 0xc4, 0x56, 0x7f, 0xf8, 0xd0, 0x5f, 0xc5, 0x6d, 0xed, 0x88, 0xe0, 0x62, 0xa2,
-            0x21, 0x91, 0xea, 0x5b, 0xfa, 0xf6, 0xee, 0x96, 0x8c, 0x58, 0x2e, 0x0c, 0x79, 0x34, 0x4c, 0xfc,
-            0x3c, 0xcc, 0xe3, 0xcc, 0x43, 0x1f, 0x34, 0xd0, 0x82, 0xdc, 0x1c, 0xdc, 0x41, 0x67, 0xc5, 0xac,
-            0x63, 0xa3, 0x4c, 0xf8, 0x18, 0x0f, 0x4f, 0x0a, 0x63, 0xd0, 0x08, 0x85, 0x29, 0x0a, 0x23, 0x18,
-            0x8a, 0x71, 0x47, 0xe0, 0xaa, 0x65, 0x7f, 0x32, 0xd6, 0x84, 0x40, 0x11, 0x6d, 0xa3, 0x02, 0x18,
-            0xa8, 0x8d, 0x69, 0x9c, 0xf8, 0x9d, 0x31, 0x63, 0x1a, 0x37, 0xc7, 0x94, 0xfe, 0xb5, 0x31, 0x21,
-            0xa8, 0xa5, 0xe6, 0xc7, 0x5d, 0xe3, 0x21, 0x53, 0xbe, 0xed, 0xd6, 0xb5, 0x9a, 0xb8, 0x71, 0xd5,
-            0x4a, 0xd9, 0x38, 0x45, 0xd0, 0xbc, 0x08, 0xab, 0x97, 0x4c, 0x1a, 0xbb, 0xa1, 0x04, 0x14, 0x72,
-            0x54, 0xca, 0x29, 0x63, 0x94, 0x97, 0x9d, 0xe8, 0x7d, 0xfe, 0x25, 0x2f, 0xae, 0xe0, 0x12, 0x2b,
-            0x46, 0x19, 0xc8, 0x1a, 0x30, 0x22, 0xf2, 0x9a, 0x39, 0xfa, 0x7d, 0xb0, 0x1c, 0x9d, 0x92, 0xc5,
-            0x57, 0x13, 0xcd, 0x5f, 0x4a, 0xf6, 0xd0, 0x21, 0x0c, 0xba, 0x86, 0xe9, 0x15, 0x2a, 0x7a, 0xc1,
-            0x9d, 0xb8, 0x50, 0x30, 0x77, 0xde, 0x41, 0x9a, 0x81, 0xdf, 0x79, 0x06, 0xbf, 0x3c, 0x4f, 0xa0,
-            0x58, 0x1c, 0x05, 0xd5, 0x3c, 0x3d, 0xd5, 0x56, 0x4b, 0x38, 0x6d, 0x38, 0x7e, 0x9d, 0xcd, 0x3d,
-            0x68, 0x9d, 0x3f, 0xa0, 0x85, 0x71, 0x8d, 0x41, 0x73, 0xa1, 0xa4, 0xd1, 0x24, 0x84, 0xc9, 0x03,
-            0xd2, 0x6e, 0x29, 0xb4, 0xf2, 0x37, 0x8f, 0x28, 0x9a, 0x10, 0x8e, 0x85, 0xe5, 0xf6, 0x43, 0xcb,
-            0x58, 0xc8, 0x81, 0x59, 0x0a, 0x29, 0x0f, 0xb2, 0x03, 0xe2, 0x16, 0x88, 0x9f, 0xe7, 0xce, 0x51,
-            0xc2, 0x59, 0xa8, 0x32, 0x29, 0x24, 0xfc, 0x30, 0xc4, 0x3a, 0x2d, 0x28, 0x00, 0x5f, 0x1f, 0x4c,
-            0x72, 0x30, 0x1a, 0x5d, 0x9f, 0x34, 0xbe, 0xde, 0x12, 0xbf, 0xce, 0xa6, 0x61, 0x88, 0x21, 0x47,
-            0xf7, 0x9c, 0xb8, 0xf7, 0x27, 0x1f, 0x72, 0xe4, 0x04, 0x03, 0xe2, 0x6c, 0x8e, 0x6c, 0x96, 0x41,
-            0xa4, 0x1f, 0x1b, 0x17, 0xc1, 0x02, 0x6d, 0xfa, 0xe7, 0xc8, 0xa1, 0xd5, 0x72, 0x4c, 0x4c, 0x48,
-            0x73, 0x66, 0x12, 0x46, 0x87, 0x60, 0xc6, 0x92, 0x03, 0xcf, 0xcd, 0x8e, 0xd8, 0x70, 0x0f, 0x40,
-            0x2c, 0x52, 0x53, 0xa9, 0x98, 0xc1, 0x9d, 0x51, 0xab, 0xc1, 0xaf, 0x56, 0x63, 0xa5, 0x52, 0x54,
-            0x2a, 0x83, 0x4a, 0xf6, 0x37, 0xbf, 0x62, 0xbd, 0xf4, 0x4f, 0x96, 0xc9, 0x86, 0xf2, 0xf9, 0xc5,
-            0x19, 0xda, 0xec, 0xdd, 0xf1, 0x16, 0x6a, 0x60, 0xf0, 0x71, 0x5c, 0xd0, 0x0b, 0x9e, 0x66, 0x05,
-            0x96, 0xf1, 0xae, 0xb5, 0xde, 0xc3, 0x43, 0xd6, 0xb2, 0x22, 0xee, 0xe8, 0x59, 0x79, 0x8e, 0x4c,
-            0xab, 0x97, 0xa9, 0xbd, 0x1a, 0xc8, 0x4f, 0x04, 0x2e, 0xfd, 0x3a, 0x2a, 0xb7, 0x74, 0x78, 0xb4,
-            0xbf, 0xb6, 0x70, 0x5f, 0x0d, 0x53, 0x58, 0xbb, 0xc4, 0x9e, 0x99, 0xf4, 0x65, 0xad, 0x93, 0xaf,
-            0xad, 0x75, 0xa3, 0x1f, 0x7a, 0xe4, 0xe3, 0x1e, 0xbd, 0xc8, 0x47, 0xa1, 0x72, 0x72, 0x19, 0x42,
-            0xee, 0xa9, 0x62, 0xe3, 0x14, 0x7b, 0x84, 0x32, 0xb4, 0xe9, 0x62, 0xd7, 0xfd, 0xe0, 0xa0, 0x64,
-            0x2e, 0x40, 0x6b, 0x8a, 0x55, 0x6d, 0xc0, 0x68, 0x5e, 0xe4, 0xa9, 0xa5, 0x82, 0x58, 0x1e, 0x5f,
-            0xb8, 0xd7, 0x88, 0xe6, 0x79, 0xa5, 0x84, 0xdb, 0x3a, 0x71, 0x98, 0x61, 0x40, 0xd8, 0xcf, 0xe9,
-            0x65, 0x0a, 0x23, 0xcd, 0x66, 0xba, 0x1f, 0x84, 0x86, 0xb5, 0x37, 0xd7, 0x40, 0x27, 0x35, 0x2f,
-            0x7b, 0x5f, 0xb5, 0x6a, 0xa9, 0xf2, 0x77, 0x57, 0x23, 0x2c, 0xbc, 0xe0, 0xe8, 0x10, 0xb4, 0xcf,
-            0x0b, 0xb0, 0x77, 0xdd, 0x8a, 0x96, 0x11, 0x31, 0xbb, 0xb9, 0x21, 0x52, 0xf3, 0x46, 0x4c, 0x2e,
-            0xa4, 0x0e, 0x9a, 0x91, 0xb9, 0xac, 0x5d, 0x73, 0xe4, 0xe2, 0x88, 0x61, 0x63, 0xdd, 0xa8, 0xcb,
-            0xb2, 0x71, 0xf2, 0x85, 0x94, 0x68, 0xc2, 0x57, 0x5c, 0x51, 0x01, 0x5d, 0x03, 0x17, 0x4e, 0x78,
-            0x99, 0x5c, 0x92, 0x7a, 0xda, 0x49, 0x21, 0x86, 0x88, 0xa4, 0x99, 0xbd, 0xca, 0xeb, 0xf1, 0x01,
-            0x87, 0x5d, 0x63, 0x58, 0x34, 0x3c, 0x75, 0xdb, 0x87, 0xbf, 0x73, 0xf8, 0x4f, 0xa0, 0x72, 0xd8,
-            0x6c, 0x84, 0x68, 0x44, 0x60, 0x6e, 0xcf, 0x45, 0xbc, 0x2d, 0xc9, 0xc1, 0x85, 0x31, 0xab, 0xd1,
-            0xa1, 0xc6, 0x0b, 0x75, 0x3b, 0xcd, 0x98, 0x35, 0xe8, 0x84, 0xf2, 0x1c, 0x64, 0xd5, 0x58, 0x58,
-            0x19, 0xf5, 0xa2, 0x20, 0xaa, 0x85, 0x95, 0x61, 0x5e, 0x8b, 0x11, 0xe7, 0x78, 0x16, 0x38, 0xc1,
-            0xc0, 0xb0, 0x90, 0x9a, 0x33, 0x0f, 0xde, 0x04, 0x3e, 0xbe, 0xa3, 0xca, 0xd4, 0xf1, 0x38, 0x61,
-            0x9d, 0x77, 0x79, 0x60, 0xd1, 0x09, 0x96, 0x4a, 0xdc, 0x71, 0x37, 0xe6, 0xd6, 0xa4, 0xc5, 0xe5,
-            0x1f, 0x52, 0x1a, 0x8c, 0xcf, 0x04, 0x18, 0x3d, 0x11, 0x9a, 0x4c, 0x36, 0xd5, 0xd6, 0xe4, 0xa6,
-            0xec, 0x2c, 0x94, 0x5a, 0x0b, 0xb4, 0xf0, 0xa5, 0xe8, 0x42, 0xd6, 0x56, 0x76, 0x2b, 0x02, 0x46,
-            0xee, 0x60, 0xfb, 0x29, 0x84, 0x2d, 0xdd, 0xa7, 0x5a, 0xde, 0x87, 0x53, 0x9e, 0xd2, 0xa7, 0xb9,
-            0xe5, 0x9e, 0x9c, 0xc6, 0x17, 0xf8, 0x3f, 0x1e, 0xa3, 0x7f, 0x06, 0x90, 0x5f, 0xa1, 0x0f, 0x8b,
-            0x38, 0x46, 0xd8, 0xeb, 0x63, 0x95, 0x7d, 0x85, 0xfe, 0x2e, 0x3b, 0xab, 0xb3, 0x74, 0x64, 0xd5,
-            0xcc, 0xef, 0x4b, 0xf0, 0xb5, 0x65, 0x43, 0x34, 0xd9, 0x74, 0x88, 0x47, 0x8e, 0x83, 0xf5, 0xb6,
-            0x71, 0xd9, 0x0c, 0xf7, 0x13, 0x86, 0xc6, 0x44, 0x21, 0x9a, 0xf0, 0xd6, 0x70, 0xab, 0x4f, 0x3c,
-            0x94, 0x34, 0xd0, 0x35, 0xf1, 0x1c, 0x56, 0x3c, 0xd9, 0x00, 0x6a, 0x07, 0xbe, 0x55, 0xca, 0xb6,
-            0x87, 0x30, 0x27, 0xfc, 0x40, 0x23, 0x45, 0xf1, 0xa6, 0xff, 0xcc, 0xa3, 0x94, 0x87, 0xa0, 0x3f,
-            0x2f, 0xb3, 0x91, 0x82, 0xc7, 0x29, 0x4b, 0xb0, 0x5a, 0xb9, 0x04, 0xe6, 0x98, 0x2a, 0x98, 0x98,
-            0xa6, 0xd6, 0x6f, 0xd5, 0xc5, 0xe7, 0x46, 0x63, 0xd7, 0x52, 0x7a, 0x85, 0x94, 0xce, 0x27, 0x7f,
-            0x1d, 0x64, 0x5d, 0x36, 0x78, 0x04, 0x7e, 0xc1, 0x3f, 0x2c, 0xcb, 0x09, 0xa4, 0x1f, 0xb8, 0x74,
-            0xf6, 0xd5, 0x66, 0x38, 0x22, 0xdf, 0x3d, 0x74, 0xb2, 0xe0, 0xe8, 0x00, 0x25, 0xea, 0x8b, 0xf9,
-            0x57, 0x6c, 0xd8, 0x77, 0x4c, 0xe1, 0x5f, 0x56, 0xe8, 0x62, 0xde, 0x68, 0xa9, 0xe2, 0xda, 0x64,
-            0x98, 0xcf, 0x72, 0x9f, 0x4c, 0xf4, 0xc5, 0x1c, 0x6f, 0x0e, 0xbf, 0xe8, 0x47, 0xcb, 0x4c, 0x63,
-            0x94, 0x9a, 0xf6, 0xd9, 0x7f, 0x29, 0x36, 0xe6, 0x32, 0x64, 0x55, 0x40, 0xbf, 0x62, 0x17, 0x0e,
-            0xdc, 0xb5, 0x01, 0xbf, 0x97, 0xdd, 0x90, 0x33, 0x6d, 0xae, 0x74, 0xeb, 0x8a, 0x0a, 0xaf, 0x9b,
-            0xbc, 0xe6, 0x6a, 0x66, 0x02, 0xfb, 0x09, 0xfb, 0x6f, 0x34, 0x25, 0x08, 0xc3, 0xe2, 0xb7, 0xb8,
-            0x8e, 0x1d, 0x34, 0x24, 0x30, 0xee, 0x08, 0x78, 0x5b, 0x92, 0x19, 0xb8, 0xe7, 0x17, 0xc3, 0x02,
-            0x43, 0x52, 0x47, 0xe9, 0x19, 0x10, 0x18, 0xfd, 0xe8, 0x49, 0x20, 0x35, 0xe9, 0x1b, 0x2a, 0xa3,
-            0x00, 0x61, 0x4c, 0x96, 0xfb, 0xa0, 0x29, 0xf7, 0x6b, 0x81, 0x6b, 0x85, 0x6d, 0x38, 0xe9, 0x2c,
-            0xc6, 0xc3, 0x29, 0x6d, 0x62, 0xc0, 0xbb, 0x42, 0x28, 0x20, 0x83, 0x08, 0xaa, 0xc3, 0x7c, 0x7a,
-            0xc3, 0x56, 0x89, 0x59, 0x4d, 0xdb, 0x66, 0xa7, 0x2c, 0x6c, 0xa0, 0xad, 0x48, 0x95, 0x8e, 0x24,
-            0xda, 0x90, 0xe3, 0xa9, 0x84, 0x8b, 0x06, 0x8e, 0xf5, 0x4b, 0xe0, 0x78, 0xc1, 0xf6, 0x31, 0x34,
-            0x26, 0x7f, 0xde, 0xaa, 0x3d, 0xb2, 0xb4, 0x6c, 0xd7, 0xe2, 0x86, 0x81, 0xb4, 0x60, 0x72, 0xf2,
-            0x0e, 0xe9, 0xdf, 0x07, 0x57, 0x8f, 0x75, 0xd3, 0xab, 0x5d, 0x3d, 0x39, 0x5f, 0x3d, 0xea, 0x24,
-            0x3f, 0x75, 0x11, 0x86, 0xf1, 0xc3, 0x8a, 0x3b, 0x48, 0x97, 0x68, 0xc6, 0x83, 0xc4, 0x95, 0xc8,
-            0x0a, 0x24, 0x21, 0xf6, 0x25, 0x3e, 0x7e, 0x22, 0xcc, 0xb3, 0xb9, 0xa2, 0x49, 0x8a, 0xcc, 0x47,
-            0x22, 0x43, 0xa0, 0x89, 0xd6, 0xa9, 0x4b, 0x31, 0xab, 0x67, 0x10, 0x75, 0xb9, 0x1b, 0xb4, 0x53,
-            0x13, 0x29, 0x62, 0xf9, 0xae, 0x53, 0xd0, 0xf8, 0xde, 0x30, 0xd9, 0xdf, 0x91, 0x02, 0xc0, 0xde,
-            0x92, 0x30, 0x34, 0x56, 0x81, 0xa0, 0x0a, 0x26, 0x7e, 0x7d, 0x83, 0x2e, 0x01, 0x18, 0xea, 0x4a,
-            0x3e, 0x54, 0xdc, 0x78, 0x9b, 0xd7, 0x52, 0xb8, 0xb6, 0x61, 0x23, 0x2f, 0xa0, 0x3c, 0xa6, 0xeb,
-            0x7d, 0x9e, 0x95, 0x30, 0xd8, 0x7c, 0x3c, 0x07, 0x51, 0xf3, 0x9d, 0xaf, 0xe0, 0x8c, 0x38, 0xd9,
-            0x51, 0x11, 0xdb, 0x67, 0x30, 0x0c, 0x99, 0x0d, 0x3d, 0xd5, 0x96, 0xbd, 0xf9, 0x60, 0x18, 0x16,
-            0xc2, 0x06, 0xa6, 0xf8, 0xa4, 0x32, 0x60, 0x13, 0x72, 0xee, 0xc4, 0x08, 0x2b, 0x56, 0x2c, 0x56,
-            0xe0, 0x8d, 0x75, 0xa7, 0xcc, 0xaa, 0x30, 0x32, 0x2b, 0xec, 0x19, 0x5a, 0x83, 0xed, 0xc7, 0x36,
-            0x5d, 0x18, 0xba, 0x87, 0xfe, 0x3a, 0x80, 0xf4, 0xfa, 0x5b, 0xc7, 0xf4, 0xae, 0xd1, 0x12, 0x65,
-            0x3f, 0x7d, 0x29, 0x78, 0x25, 0x07, 0x03, 0x0c, 0x33, 0x97, 0x07, 0x23, 0x51, 0xf7, 0x19, 0x49,
-            0x18, 0x87, 0x47, 0x1c, 0x03, 0x90, 0x55, 0x17, 0x2d, 0x9b, 0x58, 0xd4, 0x36, 0xb1, 0xf6, 0xc0,
-            0x32, 0x71, 0x05, 0xd5, 0xcd, 0xc5, 0x59, 0x31, 0x8d, 0x3c, 0x8e, 0x79, 0xa7, 0xc6, 0x88, 0x08,
-            0x29, 0x8e, 0x89, 0x32, 0xcf, 0x8a, 0xc9, 0x8b, 0xe8, 0xce, 0x45, 0x77, 0x61, 0x89, 0x78, 0xe1,
-            0x0b, 0xb1, 0xf0, 0xcb, 0xfa, 0x6b, 0xb5, 0xee, 0xd9, 0xd8, 0x02, 0xe1, 0xd8, 0x35, 0xd7, 0xe9,
-            0x26, 0x8f, 0xcd, 0x8b, 0x52, 0x18, 0x1e, 0x68, 0x1f, 0x9e, 0xe3, 0xcb, 0x20, 0x94, 0x56, 0xc1,
-            0xbc, 0x83, 0x3f, 0xa8, 0xee, 0xdc, 0xe8, 0xd3, 0xfb, 0x0e, 0xab, 0xc0, 0x47, 0x1c, 0xda, 0x46,
-            0xb6, 0xf4, 0x0f, 0x6c, 0x06, 0x3a, 0xf1, 0x3c, 0x78, 0xb0, 0xd7, 0x3e, 0x5d, 0x6b, 0x45, 0xcc,
-            0xee, 0x08, 0xe7, 0x6d, 0x30, 0x91, 0xd7, 0x01, 0xe2, 0x6d, 0xee, 0x63, 0xc5, 0x55, 0xe1, 0xd9,
-            0xca, 0xc3, 0xd3, 0x95, 0xb7, 0xbd, 0xa8, 0xcd, 0x38, 0x53, 0x5b, 0x98, 0x31, 0xef, 0x21, 0x7b,
-            0x94, 0xb4, 0x0a, 0x1f, 0xfd, 0x47, 0xc8, 0xa8, 0x8e, 0x89, 0xd6, 0xfe, 0x12, 0x1e, 0x6a, 0x43,
-            0x42, 0xdd, 0xc0, 0x42, 0x22, 0xe6, 0x59, 0x58, 0x24, 0xfb, 0x15, 0x10, 0xb5, 0x2b, 0xa1, 0x84,
-            0x62, 0x32, 0x68, 0x0d, 0x44, 0x3d, 0x10, 0x48, 0xab, 0xea, 0xb7, 0x28, 0xf9, 0x2d, 0x38, 0x9b,
-            0x22, 0x9d, 0x16, 0xd0, 0xc2, 0xf1, 0xc6, 0x48, 0x6d, 0x78, 0xac, 0xff, 0x5c, 0x31, 0xa7, 0x06,
-            0x5c, 0x66, 0x38, 0xb4, 0x5a, 0xab, 0xab, 0x6a, 0xb5, 0x77, 0x43, 0xfe, 0xe2, 0xe2, 0xd8, 0x4e,
-            0xdc, 0x6b, 0xdf, 0xc0, 0xa9, 0x7c, 0x61, 0x16, 0xb3, 0xf2, 0x0f, 0xca, 0x4c, 0x0d, 0xbb, 0x9f,
-            0x64, 0x2c, 0xca, 0x79, 0x92, 0xf5, 0x39, 0x2a, 0x05, 0xc6, 0x91, 0x12, 0x14, 0xc8, 0xdd, 0x81,
-            0xef, 0x59, 0x74, 0xa0, 0xee, 0x08, 0x6c, 0x0f, 0x2f, 0xdc, 0x0e, 0xa6, 0x18, 0xd8, 0x3e, 0xe4,
-            0x86, 0x13, 0xef, 0xe3, 0xc2, 0xc7, 0xe3, 0x35, 0x3c, 0x5f, 0x66, 0x28, 0xb8, 0xdb, 0xdb, 0x0f,
-            0x96, 0x0c, 0x78, 0x01, 0xa9, 0x4c, 0x3b, 0x81, 0x88, 0xc0, 0x88, 0x27, 0x50, 0x1b, 0x5b, 0x92,
-            0x88, 0xa9, 0x53, 0x79, 0x0a, 0xdd, 0xe9, 0x01, 0xb3, 0x5e, 0x48, 0xde, 0xdd, 0xde, 0x02, 0xd7,
-            0xb6, 0xcf, 0x71, 0x28, 0x38, 0xa4, 0x2f, 0xdb, 0x49, 0xc0, 0x8f, 0xcb, 0x30, 0x94, 0x3d, 0xd7,
-            0xb3, 0x7e, 0x11, 0x36, 0x08, 0xbc, 0x32, 0xe1, 0x15, 0xdc, 0x4b, 0xd3, 0x14, 0xdb, 0x7e, 0x2a,
-            0x7a, 0xc6, 0xe5, 0x9c, 0xa3, 0x0a, 0xd9, 0x39, 0x4e, 0x8d, 0x93, 0x79, 0x53, 0xa3, 0x69, 0x9e,
-            0xe7, 0xe0, 0x12, 0x4f, 0x51, 0xa9, 0x39, 0x66, 0xa9, 0x9e, 0x0c, 0x07, 0xf8, 0xd4, 0xbd, 0xfd,
-            0x98, 0x3c, 0x35, 0x53, 0x7a, 0x25, 0x8a, 0xba, 0x20, 0x83, 0x50, 0xf4, 0x95, 0xb0, 0xf4, 0x19,
-            0x89, 0x77, 0xa7, 0x5f, 0x85, 0x7c, 0x00, 0x39, 0x08, 0xbc, 0xb2, 0xc8, 0x22, 0x58, 0x32, 0x8b,
-            0x9a, 0xd2, 0xc4, 0xcd, 0x92, 0x68, 0x2c, 0x14, 0x34, 0x52, 0x98, 0xfc, 0x24, 0xd0, 0x79, 0x99,
-            0x18, 0xf5, 0x49, 0xcb, 0x41, 0x08, 0x80, 0x0d, 0xb4, 0x2a, 0x5d, 0x6b, 0x4a, 0xfa, 0x5d, 0x62,
-            0x17, 0x72, 0x18, 0x53, 0xb0, 0x8e, 0x98, 0x2c, 0x4b, 0xf3, 0x18, 0x43, 0xbd, 0x80, 0x65, 0xa9,
-            0xf1, 0x3e, 0x85, 0x23, 0x48, 0x9e, 0x60, 0x7d, 0xb8, 0x8b, 0xf4, 0x10, 0x54, 0xa6, 0x60, 0x8d,
-            0x39, 0x57, 0xd6, 0x08, 0xf8, 0x87, 0x98, 0xfe, 0xa2, 0x84, 0x3e, 0xb5, 0x06, 0xa7, 0x76, 0xd3,
-            0xec, 0x80, 0xe3, 0xef, 0x50, 0x86, 0xc1, 0xaf, 0x19, 0x35, 0xe6, 0x89, 0x3b, 0x04, 0xb1, 0x77,
-            0x09, 0xf0, 0x47, 0x7e, 0xb2, 0x10, 0xdc, 0x75, 0x68, 0xe2, 0xab, 0xce, 0xfc, 0xc9, 0x78, 0x66,
-            0xc3, 0xda, 0xc0, 0xb2, 0xda, 0x49, 0xbf, 0x49, 0x46, 0x4d, 0xb9, 0xf6, 0x41, 0xf2, 0x26, 0x7c,
-            0xa0, 0xe7, 0x40, 0x3c, 0x54, 0x3e, 0x49, 0x8e, 0xc2, 0x6e, 0x78, 0x07, 0x26, 0x46, 0x2a, 0x56,
-            0xc6, 0x07, 0x80, 0x18, 0x46, 0x49, 0xe7, 0x0d, 0xbf, 0xd3, 0x33, 0x82, 0x53, 0x1e, 0xb9, 0x38,
-            0xd9, 0x04, 0x4d, 0xfc, 0x30, 0xd2, 0x88, 0x62, 0x21, 0x97, 0x24, 0x31, 0x9b, 0xf7, 0xc0, 0x8e,
-            0x1d, 0xff, 0x00, 0x25, 0x5d, 0x6a, 0x34, 0x6d, 0x73, 0xc1, 0x46, 0x6b, 0x33, 0xb6, 0x28, 0x97,
-            0x6a, 0x53, 0x69, 0x0e, 0xa1, 0x42, 0x2d, 0xb4, 0x96, 0x5e, 0x3c, 0x33, 0xb1, 0xcb, 0x82, 0xaa,
-            0x86, 0x97, 0x89, 0xc8, 0xdc, 0x65, 0x62, 0xdd, 0x71, 0xb9, 0x3d, 0x5f, 0xd2, 0x8b, 0x87, 0x38,
-            0x54, 0x70, 0x20, 0x8b, 0xff, 0xc9, 0x2f, 0x1d, 0x68, 0x1b, 0x07, 0xb3, 0xa4, 0xf3, 0x13, 0x4f,
-            0x19, 0x0f, 0x88, 0x9b, 0xb2, 0x89, 0x99, 0x46, 0xa3, 0xa3, 0x5f, 0x6e, 0x8a, 0x2b, 0xbb, 0xa6,
-            0x67, 0x2d, 0x12, 0x7f, 0x06, 0x0a, 0xdb, 0xe3, 0x73, 0x5c, 0x3d, 0x8e, 0xb2, 0xfc, 0x7c, 0x63,
-            0xe3, 0xb9, 0x8c, 0x4a, 0x57, 0xfb, 0xe4, 0xd0, 0xc5, 0xdd, 0xc5, 0x2c, 0x69, 0x49, 0xa6, 0x21,
-            0xb9, 0x0e, 0x66, 0x09, 0x0f, 0xd8, 0x0c, 0x94, 0x4a, 0x8c, 0x2c, 0x1b, 0x62, 0x0b, 0x35, 0xd2,
-            0x39, 0xbc, 0xdd, 0x2c, 0xb1, 0xaf, 0x54, 0xd2, 0x26, 0x86, 0x65, 0x02, 0x2a, 0xa0, 0x91, 0x59,
-            0x7f, 0xd8, 0x56, 0x1e, 0x34, 0x79, 0xb7, 0x52, 0x17, 0x20, 0x40, 0x8a, 0xfe, 0xdb, 0x36, 0x78,
-            0x57, 0xda, 0x66, 0x32, 0xf8, 0xcb, 0x0d, 0xd7, 0x8f, 0x21, 0x6f, 0xcf, 0x79, 0x9b, 0xab, 0x07,
-            0x6d, 0x7d, 0x72, 0x3e, 0x10, 0x1b, 0x9f, 0x3c, 0x33, 0xe7, 0xec, 0x42, 0x3a, 0x31, 0x70, 0x41,
-            0x3a, 0xac, 0xb2, 0xac, 0x3b, 0xb2, 0xf5, 0x41, 0x5a, 0xfb, 0xc4, 0x15, 0xcb, 0xee, 0x9f, 0x28,
-            0x50, 0x49, 0xa3, 0x88, 0x8d, 0x37, 0x4d, 0x8f, 0x9f, 0x98, 0xc1, 0xfc, 0xec, 0xd1, 0xc7, 0x8c,
-            0xb5, 0xff, 0x04, 0x68, 0x3f, 0xf3, 0x4d, 0x78, 0x93, 0x70, 0x22, 0x7c, 0x63, 0xea, 0x4d, 0x62,
-            0x6f, 0x9b, 0x75, 0x81, 0xb2, 0x4c, 0x3d, 0x70, 0x53, 0xa0, 0x1f, 0xfd, 0x1b, 0x1b, 0xfb, 0x77,
-            0xb8, 0x74, 0xd7, 0xda, 0x45, 0x47, 0x2e, 0x1c, 0xa2, 0x3c, 0x20, 0x95, 0xbe, 0x30, 0xab, 0x6b,
-            0x50, 0x5e, 0x27, 0x5d, 0x51, 0x1a, 0x91, 0xd8, 0x75, 0x72, 0x81, 0xfc, 0xd7, 0x30, 0xbe, 0xb1,
-            0x0f, 0xde, 0xd9, 0x08, 0xb2, 0xeb, 0x97, 0xa4, 0x83, 0x59, 0x5c, 0x9f, 0x44, 0xe6, 0x45, 0xb5,
-            0x6d, 0x7c, 0x4a, 0x10, 0x0d, 0x14, 0x90, 0x7a, 0xcd, 0x98, 0x37, 0xdf, 0xb9, 0xde, 0xbe, 0xba,
-            0xba, 0xda, 0x26, 0x7d, 0x12, 0xb0, 0xc9, 0xca, 0x88, 0xd7, 0x96, 0x44, 0x20, 0x18, 0xb9, 0x0a,
-            0xb4, 0x91, 0x00, 0x1b, 0x7d, 0x1d, 0xfb, 0x14, 0xb3, 0xc5, 0xef, 0x93, 0x11, 0xf6, 0xae, 0x19,
-            0xb7, 0x9e, 0x25, 0xef, 0xd9, 0x23, 0xd9, 0x3a, 0xdd, 0x7d, 0x80, 0x84, 0xb1, 0x33, 0x0c, 0xc0,
-            0x16, 0x59, 0x30, 0x03, 0x10, 0x94, 0x77, 0x3e, 0xa0, 0x92, 0xc8, 0xa5, 0xd8, 0x16, 0x3f, 0xa3,
-            0xe5, 0xc9, 0x3b, 0xb6, 0xaf, 0xb1, 0xf8, 0xf7, 0x32, 0xa1, 0xe2, 0x9f, 0xb9, 0x97, 0xab, 0x04,
-            0xec, 0x28, 0x2e, 0x8d, 0xb5, 0xc6, 0x5d, 0xce, 0x5a, 0x40, 0xd1, 0x24, 0xce, 0xfa, 0xe9, 0x8a,
-            0xa2, 0x27, 0x46, 0xe0, 0xb1, 0x45, 0x0e, 0x5b, 0x81, 0xbf, 0x16, 0xf8, 0x01, 0xa1, 0x01, 0x11,
-            0x59, 0x8f, 0xd8, 0xa7, 0xd4, 0xd8, 0xd7, 0xda, 0xee, 0x6a, 0x6e, 0xac, 0x09, 0xf3, 0x5a, 0xcc,
-            0x5e, 0x1e, 0xdf, 0x51, 0x42, 0xfa, 0x81, 0x88, 0x62, 0xcc, 0xb1, 0x61, 0x8b, 0x1d, 0xfa, 0x03,
-            0x26, 0x17, 0xac, 0xaa, 0x9d, 0x26, 0xb0, 0xef, 0x1d, 0x15, 0xf9, 0x9a, 0xaf, 0x8e, 0x27, 0xa9,
-            0x7e, 0x4f, 0x22, 0x44, 0x1a, 0x78, 0xe5, 0xf0, 0xac, 0x46, 0x83, 0x04, 0xf7, 0x9e, 0xcb, 0xc2,
-            0xb4, 0xd2, 0x7f, 0x10, 0xcf, 0x45, 0xe9, 0xfe, 0xbe, 0x37, 0x3c, 0xba, 0x8a, 0x67, 0x4e, 0x93,
-            0x87, 0xc6, 0x47, 0x57, 0x10, 0xf7, 0x32, 0x67, 0xdb, 0x5a, 0x8a, 0xac, 0xc9, 0xa5, 0x2e, 0x45,
-            0xe2, 0xdb, 0xa0, 0xfc, 0x65, 0xd7, 0x89, 0xd5, 0xae, 0xcd, 0x3d, 0xee, 0xae, 0x75, 0x73, 0x93,
-            0x1b, 0x6b, 0xa7, 0xb3, 0x18, 0xe3, 0x34, 0x81, 0xe3, 0xec, 0x08, 0x20, 0x0b, 0x02, 0x2e, 0x83,
-            0xfd, 0x13, 0x86, 0x91, 0xb2, 0x5f, 0xb7, 0xb7, 0x47, 0xe1, 0xa7, 0x9b, 0x73, 0xad, 0x5a, 0x6c,
-            0xc2, 0x6f, 0x43, 0x75, 0xf3, 0x0b, 0xab, 0xba, 0x9f, 0x3e, 0xf8, 0x39, 0xa7, 0x58, 0xb2, 0xa2,
-            0x41, 0x4f, 0x10, 0xbd, 0xb0, 0x5e, 0x27, 0x18, 0xce, 0x9d, 0x8f, 0xd5, 0x5e, 0xfb, 0x21, 0x82,
-            0xe0, 0x50, 0x24, 0xf3, 0x05, 0x2d, 0xc8, 0x1e, 0x85, 0xa5, 0x1b, 0x5c, 0xc3, 0x0f, 0xb3, 0x06,
-            0x83, 0x2b, 0x84, 0x46, 0x2c, 0x60, 0xd7, 0x08, 0x9c, 0x6f, 0x21, 0xdb, 0x00, 0xf9, 0x3e, 0xfc,
-            0x94, 0x1b, 0x81, 0x23, 0x38, 0xdb, 0xd8, 0x38, 0x13, 0x28, 0x47, 0x8c, 0x47, 0x58, 0x80, 0x4e,
-            0xd2, 0x29, 0x79, 0x1b, 0xef, 0x11, 0x89, 0x59, 0x1f, 0x12, 0x6f, 0xf7, 0x27, 0x8c, 0x67, 0xc2,
-            0xd7, 0xe9, 0xdf, 0x1c, 0x38, 0xfd, 0x99, 0x7c, 0xf2, 0xba, 0xcf, 0x43, 0xf8, 0x78, 0xc8, 0x6f,
-            0xf4, 0xbc, 0x4c, 0x48, 0x74, 0x06, 0x6f, 0x82, 0xbe, 0x4c, 0xfe, 0xb4, 0xcf, 0x02, 0x25, 0xeb,
-            0x57, 0xc6, 0x1a, 0x93, 0x1e, 0x89, 0x85, 0x3f, 0x23, 0x10, 0xb3, 0x63, 0xb9, 0x5f, 0x09, 0xbf,
-            0xbc, 0xf4, 0xd7, 0x39, 0x78, 0x24, 0x62, 0x0c, 0xd6, 0x97, 0x60, 0x88, 0xf6, 0xc4, 0x3c, 0x3a,
-            0xf2, 0x92, 0x8d, 0xd2, 0xe0, 0xcf, 0x39, 0x82, 0x11, 0x56, 0x3b, 0xe4, 0x12, 0xf0, 0xf6, 0xd8,
-            0xe1, 0x92, 0x70, 0xd5, 0xfa, 0x01, 0xc2, 0xfd, 0x4b, 0x5a, 0x5b, 0x41, 0x5f, 0x67, 0x39, 0xcd,
-            0x15, 0x63, 0x8c, 0xd9, 0x39, 0x4e, 0x6b, 0x73, 0x3c, 0x67, 0x2f, 0x3c, 0x14, 0x65, 0xbf, 0x07,
-            0xee, 0xce, 0x90, 0xb0, 0xd0, 0x14, 0xfb, 0xe3, 0x41, 0xb6, 0xa1, 0xea, 0x5f, 0xc3, 0xb6, 0x23,
-            0xda, 0xea, 0xd0, 0x53, 0x91, 0x3b, 0xd0, 0x3e, 0x5c, 0x7d, 0x83, 0x06, 0x14, 0xc1, 0x4e, 0xd4,
-            0x52, 0x06, 0x0e, 0x64, 0x20, 0xcf, 0xfc, 0xc2, 0x49, 0x1c, 0x81, 0x31, 0xe6, 0x4b, 0x8b, 0xd7,
-            0x8c, 0x86, 0xc6, 0x89, 0xf0, 0xde, 0xa2, 0x64, 0xe0, 0x9a, 0x56, 0xe7, 0xba, 0x2e, 0xc2, 0x7b,
-            0xeb, 0x4c, 0xa9, 0x7f, 0x49, 0xae, 0x4f, 0xde, 0x9e, 0x0e, 0x40, 0x23, 0x72, 0x1e, 0xbf, 0x8d,
-            0x7f, 0xf1, 0xac, 0xff, 0x71, 0xb2, 0x40, 0x07, 0xc4, 0x73, 0x7f, 0x66, 0x9c, 0xc3, 0x06, 0xc2,
-            0x62, 0x7f, 0xcf, 0x10, 0xbd, 0xfe, 0x1c, 0x1b, 0xe1, 0xf3, 0x0b, 0x02, 0x6b, 0x0a, 0xd7, 0xb0,
-            0x30, 0x55, 0xde, 0x32, 0x9c, 0x03, 0x49, 0x9e, 0x4e, 0xdf, 0x89, 0xa4, 0x97, 0xb1, 0xd5, 0x2e,
-            0x70, 0x09, 0x94, 0x25, 0xf3, 0x43, 0x70, 0x7d, 0xd8, 0x15, 0x5c, 0xb9, 0x86, 0x3f, 0xa0, 0xd7,
-            0x7f, 0x40, 0x8c, 0x29, 0xbc, 0x14, 0x06, 0xc7, 0x3d, 0xdb, 0x5f, 0x4f, 0xb6, 0x96, 0x80, 0x06,
-            0x05, 0x9e, 0x18, 0x7e, 0x0d, 0x3b, 0x79, 0x4c, 0x3b, 0x7e, 0x0c, 0x00, 0xa4, 0x66, 0x07, 0xd6,
-            0xd3, 0xa9, 0xf2, 0x64, 0x28, 0x20, 0xe9, 0xf8, 0x0f, 0x7a, 0xc9, 0xae, 0x94, 0xc1, 0x5b, 0xdc,
-            0x71, 0x3b, 0x26, 0x8f, 0xad, 0x20, 0xef, 0x30, 0x67, 0xb7, 0x41, 0x6e, 0xda, 0x72, 0x77, 0x26,
-            0x76, 0x8f, 0x0f, 0xc6, 0xa6, 0xc5, 0x6b, 0x25, 0x2a, 0x7c, 0xe6, 0x35, 0x27, 0xf5, 0xb4, 0x7b,
-            0xdc, 0xa3, 0x52, 0xc6, 0xc3, 0x80, 0x43, 0xf9, 0x86, 0x2f, 0x7e, 0xb7, 0x0d, 0x47, 0xb5, 0x0f,
-            0x67, 0xc9, 0x04, 0x4c, 0xeb, 0xb3, 0x67, 0x45, 0x2e, 0x3c, 0x01, 0x7d, 0x3c, 0x12, 0x10, 0x17,
-            0x1c, 0x77, 0xfd, 0xb3, 0x67, 0xb4, 0x4b, 0xd3, 0x9b, 0x05, 0x11, 0xb8, 0xb4, 0x07, 0x54, 0x2c,
-            0x78, 0xcb, 0x95, 0x57, 0x6c, 0x30, 0xbe, 0x63, 0xc5, 0xe4, 0x73, 0x6b, 0x20, 0xf1, 0x30, 0xbd,
-            0x1e, 0x8b, 0x13, 0xc4, 0x8d, 0x13, 0x39, 0xf4, 0x5f, 0x36, 0xfe, 0x94, 0x28, 0xec, 0x96, 0xc6,
-            0xed, 0xa9, 0xf9, 0xcf, 0x9b, 0x37, 0x2d, 0xd4, 0x1b, 0xaf, 0xe1, 0x67, 0xf6, 0x00, 0x17, 0x4d,
-            0xb4, 0xe2, 0x67, 0x24, 0xb6, 0xde, 0x25, 0x9a, 0xa0, 0x16, 0x7f, 0xff, 0x91, 0xe4, 0xf4, 0x1b,
-            0xcc, 0x0c, 0x4f, 0x28, 0x38, 0xa4, 0xb1, 0x1a, 0xa0, 0xdf, 0xa4, 0xd9, 0x87, 0x77, 0x59, 0x8a,
-            0x73, 0x8c, 0x63, 0x08, 0x3f, 0x99, 0x8d, 0x38, 0x0d, 0x8c, 0x10, 0xb1, 0xe6, 0x39, 0xbc, 0x61,
-            0x37, 0x9f, 0x61, 0x95, 0xd3, 0x9a, 0x1b, 0x73, 0x23, 0xd4, 0x56, 0xe8, 0x93, 0x25, 0xc6, 0x8f,
-            0x27, 0x1d, 0x02, 0x07, 0xc4, 0x0b, 0x06, 0x57, 0xd4, 0x62, 0xce, 0x89, 0x46, 0xed, 0x5b, 0x83,
-            0x14, 0x9f, 0x14, 0x73, 0x9c, 0x56, 0xcc, 0xa1, 0x1f, 0xb1, 0x2e, 0x74, 0x3a, 0x85, 0x4f, 0xfa,
-            0xbb, 0xe4, 0x60, 0xa5, 0xc1, 0x89, 0x31, 0xaf, 0xfe, 0xd2, 0x8c, 0x8e, 0x2d, 0xfa, 0xff, 0x3e,
-            0xd9, 0x7f, 0x82, 0xe7, 0xa1, 0x7f, 0x85, 0xa8, 0xa7, 0x8c, 0xaf, 0x10, 0x13, 0x92, 0xaf, 0xe9,
-            0xf7, 0xdd, 0x16, 0x5b, 0xde, 0xd7, 0x75, 0xfb, 0x45, 0x24, 0xa9, 0x65, 0xf4, 0x43, 0x61, 0x27,
-            0x84, 0x87, 0x1d, 0x24, 0x6c, 0x3b, 0x68, 0xec, 0x8a, 0xda, 0xae, 0x1d, 0x0c, 0x0f, 0x8e, 0x71,
-            0x11, 0x9b, 0x6f, 0xf6, 0x45, 0xa6, 0x4c, 0x84, 0xc1, 0x60, 0x58, 0x06, 0xef, 0x58, 0x0b, 0xd9,
-            0xc6, 0x36, 0x5c, 0x8c, 0xf7, 0x69, 0x07, 0xcb, 0xdd, 0xd5, 0xd6, 0x3b, 0xe6, 0x4d, 0xef, 0xd3,
-            0x9c, 0x28, 0xca, 0x2d, 0x5a, 0xbe, 0x76, 0xe9, 0x95, 0xa4, 0x89, 0x7b, 0x4b, 0xcd, 0x19, 0x1f,
-            0x05, 0x52, 0xe5, 0x05, 0xca, 0xc1, 0x40, 0x3e, 0x41, 0x84, 0x46, 0xe9, 0x70, 0x3b, 0x04, 0xb1,
-            0xf5, 0x48, 0xb3, 0x8e, 0x95, 0x9d, 0x7f, 0x81, 0x6e, 0x47, 0xac, 0xee, 0x59, 0x2a, 0x08, 0x44,
-            0xa9, 0x87, 0xc4, 0x4f, 0x09, 0x5b, 0x52, 0xfc, 0x44, 0xe2, 0xdb, 0x5d, 0xf3, 0x43, 0x53, 0xce,
-            0x8c, 0x5e, 0x14, 0x35, 0x29, 0x41, 0xe9, 0x79, 0x12, 0x98, 0x73, 0xd2, 0xae, 0x8e, 0xfd, 0x06,
-            0xa7, 0x6e, 0x83, 0xf1, 0xc5, 0x1b, 0xb3, 0xc8, 0x83, 0xd4, 0xd8, 0xb9, 0xad, 0xf1, 0x9b, 0xc0,
-            0x63, 0xbf, 0x54, 0x90, 0x35, 0xf4, 0x51, 0xba, 0x83, 0x2a, 0x40, 0xc6, 0x65, 0xc4, 0xa3, 0xb0,
-            0x77, 0x4b, 0xeb, 0x4a, 0xba, 0xd7, 0x7d, 0x4c, 0x3c, 0x32, 0x57, 0x49, 0x2c, 0x0d, 0xdf, 0x57,
-            0xf0, 0x2a, 0x67, 0xfd, 0xa1, 0x63, 0x7c, 0xd5, 0x2f, 0x4d, 0xd2, 0x2d, 0xa4, 0x31, 0x1a, 0xe5,
-            0x97, 0x72, 0x7f, 0xc6, 0xbc, 0x3f, 0x69, 0xb8, 0x75, 0x52, 0xd7, 0xfe, 0xc2, 0x40, 0x3f, 0x62,
-            0x8d, 0x9c, 0x58, 0xd1, 0x77, 0xea, 0x1c, 0x42, 0x9c, 0x92, 0xa7, 0xe8, 0x48, 0x89, 0x68, 0x1c,
-            0xa4, 0x85, 0x47, 0x52, 0xc4, 0x98, 0xdf, 0x3f, 0xdc, 0x95, 0xda, 0xc1, 0x67, 0xec, 0x05, 0x00,
-            0x34, 0x02, 0x87, 0xb7, 0xc4, 0xe7, 0x9d, 0x85, 0xef, 0x8d, 0x81, 0x41, 0x94, 0x68, 0x42, 0xdd,
-            0xe0, 0xd9, 0x67, 0xee, 0x79, 0x65, 0x59, 0xd0, 0x23, 0xe0, 0xae, 0xbc, 0x20, 0xab, 0x70, 0xe3,
-            0x9a, 0x2f, 0x22, 0xae, 0x58, 0x5d, 0x1b, 0x99, 0x16, 0xf7, 0x8d, 0xb2, 0xd3, 0x07, 0xe3, 0x72,
-            0x3a, 0x4b, 0xaf, 0x24, 0x46, 0x1b, 0x57, 0xb4, 0x3f, 0x8d, 0x7c, 0x10, 0x49, 0xf9, 0x9e, 0xb6,
-            0x91, 0xff, 0x18, 0x2d, 0xac, 0x7b, 0x67, 0x94, 0x9f, 0xd4, 0x56, 0x72, 0xe9, 0xde, 0x0b, 0x11,
-            0xba, 0x10, 0x75, 0xd5, 0x28, 0xd4, 0xdc, 0x88, 0xb8, 0xc8, 0x50, 0x24, 0x08, 0x74, 0x25, 0x4c,
-            0x5e, 0x5a, 0x65, 0xad, 0xf8, 0x80, 0x1e, 0x5f, 0x9d, 0xb8, 0x2d, 0x94, 0xd9, 0xf9, 0xfd, 0x80,
-            0xa9, 0x46, 0x78, 0x6f, 0xd0, 0x88, 0x60, 0xd7, 0x1e, 0x2c, 0xf4, 0xf2, 0xf7, 0xb6, 0x37, 0xea,
-            0x3e, 0x18, 0x55, 0xa2, 0x0f, 0xed, 0xe2, 0x11, 0x5b, 0x2d, 0xf8, 0x3e, 0x99, 0x38, 0xea, 0xa1,
-            0x7f, 0x6d, 0xd5, 0x88, 0x99, 0xed, 0x6d, 0x14, 0x86, 0xe7, 0xb3, 0x34, 0x01, 0x08, 0xf3, 0xb9,
-            0x57, 0x89, 0x17, 0x8d, 0x23, 0x02, 0xe3, 0xa0, 0xef, 0xc9, 0xb5, 0x4b, 0xb8, 0x2d, 0xc4, 0x1c,
-            0xcc, 0xd9, 0x16, 0x7e, 0x65, 0xf8, 0x44, 0x2e, 0x6d, 0x03, 0x14, 0xb6, 0x63, 0x2d, 0x5b, 0x36,
-            0xe2, 0x2b, 0xae, 0x72, 0x61, 0xa3, 0x9b, 0xaf, 0xa2, 0x56, 0x64, 0xef, 0x04, 0x8a, 0xff, 0x8a,
-            0xb9, 0x16, 0x56, 0x65, 0xac, 0xf1, 0xd7, 0x92, 0x25, 0x35, 0x49, 0x65, 0x10, 0x8c, 0xf1, 0x26,
-            0x02, 0xdb, 0x11, 0x62, 0x82, 0xc1, 0x98, 0xa9, 0xaa, 0x05, 0xa6, 0x9b, 0x26, 0x1e, 0xc9, 0x92,
-            0x9b, 0x3c, 0x0e, 0x17, 0x1f, 0x52, 0x59, 0x85, 0x5e, 0xa9, 0x50, 0xcd, 0x55, 0xc9, 0x37, 0x31,
-            0xca, 0x4a, 0xa4, 0x66, 0x77, 0xf8, 0x69, 0x89, 0x90, 0x74, 0xe4, 0x60, 0x7f, 0xc2, 0xef, 0x1e,
-            0x19, 0xe8, 0x3b, 0x10, 0x39, 0xb7, 0x85, 0x52, 0x5b, 0x74, 0x75, 0xab, 0x7b, 0xeb, 0xcb, 0xb0,
-            0x78, 0xd3, 0x7b, 0x74, 0x56, 0xaf, 0x66, 0xf1, 0xec, 0x6b, 0x86, 0x24, 0x87, 0x49, 0x9f, 0xa1,
-            0x55, 0xab, 0x10, 0xee, 0xe3, 0xd9, 0x33, 0x58, 0x74, 0x7d, 0x7d, 0xce, 0x8c, 0xdf, 0x80, 0xa5,
-            0xcc, 0xee, 0x5c, 0x0b, 0xcb, 0xef, 0xdb, 0xdb, 0xb9, 0xfc, 0x34, 0x72, 0xe8, 0xb9, 0x80, 0x39,
-            0xf7, 0x0a, 0xc5, 0xc2, 0x02, 0x6a, 0xf2, 0x1e, 0xc7, 0xe0, 0xd2, 0x89, 0xe2, 0x21, 0xeb, 0x50,
-            0x61, 0xab, 0x32, 0xf0, 0x12, 0x4a, 0x94, 0x70, 0xc9, 0x2c, 0x94, 0x58, 0x86, 0x29, 0xcb, 0x60,
-            0x4f, 0xcc, 0x91, 0x33, 0x7b, 0x22, 0xbb, 0x5c, 0xbd, 0xf6, 0x56, 0x05, 0xd2, 0x0d, 0x9b, 0x22,
-            0x44, 0x44, 0x0d, 0xcd, 0xee, 0xd8, 0x38, 0xf6, 0x8c, 0xa0, 0x69, 0x80, 0x04, 0xd0, 0x87, 0x15,
-            0xc1, 0x84, 0x0b, 0x94, 0x23, 0x2d, 0xc0, 0x72, 0x73, 0x3e, 0x1d, 0x1d, 0x11, 0x5a, 0xab, 0x07,
-            0xeb, 0x38, 0x07, 0x8d, 0x00, 0x21, 0x84, 0x7e, 0x1a, 0x4b, 0x43, 0xfb, 0x89, 0x35, 0xb3, 0xb1,
-            0xd6, 0x3b, 0xa3, 0xd0, 0x98, 0x67, 0xb6, 0x34, 0x46, 0x96, 0xe6, 0x61, 0x45, 0x90, 0x7f, 0x11,
-            0x35, 0x65, 0x3e, 0xe3, 0x0b, 0x79, 0xa2, 0x9b, 0x64, 0x28, 0xbf, 0x31, 0xee, 0x0b, 0x95, 0xc9,
-            0x85, 0xc5, 0x23, 0xe7, 0xf0, 0x33, 0x1c, 0x24, 0xdc, 0x84, 0x17, 0x3d, 0x33, 0xcc, 0xc1, 0x04,
-            0x7f, 0x8b, 0x2d, 0x1f, 0x51, 0x71, 0x39, 0x54, 0x10, 0x85, 0x5f, 0x84, 0xbb, 0xe9, 0xf6, 0x81,
-            0x42, 0xe0, 0x93, 0x3b, 0x28, 0x58, 0xc2, 0xe3, 0x2b, 0xb3, 0x43, 0x8c, 0x5c, 0x38, 0x9e, 0x4f,
-            0x93, 0x75, 0x12, 0x98, 0x5d, 0xf4, 0xfc, 0x5a, 0x19, 0x9b, 0x46, 0xbe, 0x27, 0xe0, 0x00, 0x7e,
-            0xfb, 0xef, 0xff, 0x01, 0xc4, 0x42, 0xc1, 0x35, 0x3f, 0xe8, 0x1a, 0x99, 0x7a, 0x4e, 0x0e, 0x3c,
-            0xe0, 0xd9, 0x80, 0x82, 0x21, 0x3b, 0x6c, 0x20, 0x19, 0x73, 0x13, 0xd5, 0x0a, 0xee, 0x7c, 0x72,
-            0x46, 0xe7, 0x90, 0x24, 0x4b, 0x96, 0x68, 0x9e, 0x21, 0x50, 0xcc, 0x98, 0x39, 0xbb, 0x69, 0xbc,
-            0xc1, 0x2d, 0xe6, 0x88, 0xee, 0x73, 0x37, 0x81, 0xc3, 0xc3, 0x04, 0xdc, 0xb5, 0x57, 0x3d, 0xee,
-            0x5e, 0x7b, 0x2a, 0x9e, 0x9e, 0xab, 0x1c, 0x25, 0x59, 0x0d, 0xb4, 0x98, 0x0f, 0x26, 0xe0, 0x1a,
-            0xdd, 0x05, 0x5c, 0xfc, 0x38, 0xa8, 0x95, 0x16, 0x5e, 0xe3, 0x39, 0xb1, 0x26, 0x57, 0x44, 0x26,
-            0x71, 0xac, 0x53, 0x4e, 0xdb, 0x2e, 0x8a, 0x33, 0x47, 0x25, 0x9d, 0x25, 0xb5, 0xdc, 0x88, 0xa3,
-            0xd7, 0xc4, 0xe7, 0xf1, 0x4d, 0xbc, 0x30, 0xfd, 0x8f, 0xbc, 0x11, 0x2e, 0x13, 0xda, 0xe0, 0x9e,
-            0x78, 0x26, 0x0c, 0xbc, 0x40, 0x26, 0x66, 0x5f, 0xbe, 0x06, 0x6b, 0x32, 0xc3, 0x76, 0xab, 0x3a,
-            0xa1, 0x12, 0xd7, 0x42, 0x9c, 0x80, 0xe5, 0x48, 0xfd, 0xa1, 0xfa, 0x7e, 0x68, 0x37, 0x5b, 0xbb,
-            0x62, 0xb6, 0x9f, 0x62, 0xf9, 0xed, 0x23, 0x77, 0xde, 0x8c, 0x6d, 0xb6, 0xe5, 0x9b, 0x35, 0x71,
-            0xbd, 0x5e, 0xb3, 0x5a, 0xbf, 0x8c, 0x44, 0x7d, 0x8e, 0x75, 0x18, 0xb7, 0x3c, 0xeb, 0x7e, 0xbf,
-            0x21, 0xb0, 0xc7, 0xcd, 0x7f, 0x33, 0x08, 0xf3, 0xb6, 0x3d, 0x0d, 0xc3, 0x1f, 0xb6, 0x15, 0xa3,
-            0xb0, 0x60, 0xf9, 0xb5, 0x88, 0x61, 0xef, 0x67, 0xe4, 0x33, 0x4b, 0x1c, 0xb9, 0x09, 0x03, 0x03,
-            0x52, 0x75, 0xbc, 0xb7, 0x3d, 0x70, 0x0b, 0x0b, 0x21, 0x08, 0xee, 0x35, 0x5c, 0x1d, 0x47, 0x06,
-            0x0b, 0xa9, 0x11, 0xda, 0x89, 0xbf, 0xb4, 0x01, 0x22, 0x39, 0x2e, 0x0e, 0xd7, 0xb1, 0x86, 0x8e,
-            0xbf, 0xde, 0xd9, 0x88, 0x21, 0x9f, 0xa1, 0x99, 0x55, 0x8d, 0x2c, 0x97, 0xac, 0x1c, 0x4f, 0xd9,
-            0x94, 0xd4, 0xd5, 0x63, 0x30, 0x6f, 0x88, 0x18, 0x22, 0x7b, 0x00, 0xd6, 0x8e, 0xe8, 0xc8, 0x33,
-            0x9d, 0xb4, 0xb6, 0x07, 0xb4, 0x2b, 0x38, 0x9f, 0x58, 0x44, 0x00, 0x01, 0xd1, 0xd1, 0x3c, 0x00,
-            0x03, 0x99, 0x4b, 0xd6, 0xc3, 0x71, 0x26, 0x4b, 0x8e, 0x94, 0x60, 0x84, 0xeb, 0x18, 0x81, 0x54,
-            0xc4, 0xd3, 0xf4, 0x56, 0x2d, 0x0b, 0x0c, 0x7c, 0xdb, 0x66, 0xf9, 0xc0, 0x2f, 0xf8, 0xc8, 0x80,
-            0xee, 0xfd, 0xa6, 0x49, 0x0c, 0x17, 0x32, 0x41, 0x3e, 0xdb, 0x6d, 0x1d, 0x4c, 0x1c, 0xb6, 0x3a,
-            0x4e, 0x6a, 0x58, 0x35, 0x39, 0x1a, 0x33, 0xc6, 0xa7, 0x28, 0x80, 0x4c, 0x56, 0x7c, 0x4f, 0x34,
-            0x47, 0xc6, 0x14, 0x71, 0xcc, 0xb6, 0x04, 0xb5, 0x42, 0xf6, 0x05, 0x95, 0xb0, 0x68, 0xdd, 0xd5,
-            0x65, 0x55, 0xe7, 0xe6, 0x51, 0x67, 0x1f, 0xfa, 0x53, 0x90, 0xc3, 0x14, 0x21, 0x18, 0x29, 0x6b,
-            0xfc, 0x8b, 0xfe, 0xb7, 0x9f, 0x31, 0x3c, 0x21, 0x5e, 0x6b, 0xb8, 0x9a, 0x81, 0x75, 0xf5, 0x9f,
-            0x34, 0x5a, 0x43, 0xa1, 0x51, 0x31, 0x11, 0x65, 0x11, 0x9b, 0xb4, 0xd6, 0xd4, 0x79, 0xa0, 0x7d,
-            0xcf, 0x8d, 0x32, 0x51, 0x85, 0x7e, 0xa8, 0x96, 0x08, 0x66, 0x16, 0x56, 0xe6, 0x60, 0xf9, 0xfa,
-            0xa3, 0xa2, 0xf8, 0x4c, 0xad, 0x73, 0x27, 0x5d, 0xe5, 0x91, 0xa9, 0x6a, 0xe1, 0xec, 0xd6, 0x30,
-            0x08, 0x30, 0x57, 0xf3, 0xb1, 0xe9, 0xfe, 0xd5, 0xc5, 0x80, 0x28, 0x84, 0xeb, 0x31, 0xd4, 0x76,
-            0xe9, 0x5e, 0x44, 0xb7, 0xae, 0x76, 0x82, 0x12, 0x2b, 0xc3, 0xe8, 0x1e, 0x8e, 0x31, 0xa1, 0xc9,
-            0xd3, 0x68, 0x90, 0xb6, 0xf4, 0xca, 0x0d, 0x2c, 0x93, 0x8b, 0x67, 0x01, 0x1c, 0xad, 0xff, 0xbd,
-            0x31, 0xc1, 0x07, 0xd8, 0xa5, 0x55, 0xa2, 0x1b, 0xea, 0x87, 0xdc, 0x68, 0xff, 0xe8, 0xe8, 0x35,
-            0x43, 0xbe, 0x3f, 0x3f, 0x7c, 0x6d, 0x58, 0x9d, 0x57, 0x24, 0x64, 0x09, 0x5e, 0xe0, 0x81, 0xca,
-            0x26, 0xc4, 0x98, 0x8f, 0xb8, 0x68, 0x59, 0xa8, 0x1f, 0x72, 0x13, 0x8a, 0x15, 0xe2, 0x6a, 0x8e,
-            0x6e, 0x28, 0x10, 0x1e, 0x3f, 0x5f, 0xcc, 0x71, 0xaa, 0xd1, 0x66, 0xc8, 0xbd, 0x64, 0x7d, 0xdf,
-            0xae, 0x83, 0xa7, 0x44, 0x7e, 0x32, 0xd8, 0xcd, 0x93, 0x8c, 0x6c, 0xc3, 0xe1, 0x08, 0x56, 0xf2,
-            0x3c, 0xab, 0xd6, 0x9d, 0x5d, 0x83, 0xd5, 0x54, 0x8a, 0x0a, 0x74, 0x14, 0xb0, 0xd8, 0x1b, 0x7c,
-            0x39, 0xe8, 0xc9, 0xef, 0x6b, 0x39, 0xbd, 0xba, 0x1c, 0x3d, 0x58, 0xac, 0x2c, 0xb4, 0x8c, 0x7e,
-            0xef, 0x47, 0xd1, 0xa0, 0x11, 0x1e, 0xd3, 0x45, 0xae, 0x0a, 0x03, 0x64, 0xb6, 0x87, 0xcf, 0xa4,
-            0x19, 0xa3, 0x3e, 0x04, 0xaa, 0x01, 0x19, 0xa4, 0x9f, 0x8e, 0x3e, 0x03, 0xb0, 0xe4, 0x1a, 0x5d,
-            0x5a, 0x3b, 0x11, 0x23, 0x65, 0x92, 0x52, 0xfd, 0xfe, 0xa8, 0xc2, 0x9e, 0x1f, 0x2c, 0xd4, 0xf2,
-            0xf1, 0xef, 0x5b, 0xbf, 0xf7, 0x90, 0x7b, 0x5b, 0xc0, 0x53, 0x6d, 0x43, 0x0c, 0x23, 0xb1, 0x3b,
-            0xb8, 0xcc, 0xaa, 0xec, 0x2c, 0x9b, 0xe2, 0xc7, 0xda, 0x24, 0x1b, 0x81, 0xac, 0x6e, 0xb9, 0xc6,
-            0xc5, 0xe0, 0x07, 0x15, 0x8e, 0xd7, 0xe8, 0x23, 0xac, 0xf8, 0x30, 0xa8, 0x48, 0xbf, 0x81, 0xc8,
-            0x12, 0xae, 0x9c, 0x6b, 0xa6, 0xe4, 0x1a, 0x44, 0xb9, 0xbb, 0xa8, 0xd6, 0x14, 0x28, 0x12, 0x20,
-            0x32, 0xc0, 0xf2, 0xf7, 0xad, 0xe8, 0xd1, 0x0e, 0x0d, 0xe8, 0x71, 0x24, 0xb7, 0xe2, 0xd7, 0xfc,
-            0xee, 0x30, 0xbe, 0x9b, 0xf8, 0x9e, 0xe2, 0x09, 0x05, 0x10, 0x31, 0x51, 0x35, 0x69, 0x4d, 0x22,
-            0x13, 0xcd, 0xd2, 0xa3, 0x9f, 0x4b, 0x8e, 0x38, 0x85, 0x7b, 0x1e, 0x3a, 0xb0, 0xd4, 0x5e, 0x69,
-            0xf8, 0x45, 0x76, 0x88, 0xbd, 0x9b, 0x66, 0xec, 0x6a, 0x23, 0xea, 0xb0, 0xbf, 0x09, 0x6a, 0x00,
-            0x2c, 0x05, 0xdc, 0x62, 0xf5, 0x01, 0xc2, 0xcf, 0xc0, 0x5c, 0xbf, 0xf6, 0xda, 0x19, 0xbc, 0x10,
-            0x91, 0x80, 0x75, 0xf2, 0xf5, 0x27, 0xb9, 0xf0, 0xcd, 0x2d, 0x0a, 0x94, 0xd6, 0xf6, 0x22, 0x97,
-            0xcc, 0x8c, 0xda, 0x5f, 0x54, 0x10, 0x76, 0x19, 0xad, 0x61, 0xaa, 0x94, 0x09, 0x11, 0x8d, 0xf1,
-            0xad, 0x39, 0x3e, 0x84, 0x60, 0xc3, 0x73, 0xff, 0xce, 0x02, 0x3d, 0xd8, 0x49, 0xf6, 0x1f, 0xf4,
-            0x87, 0x75, 0xfb, 0x1d, 0x72, 0x38, 0xb4, 0x65, 0xad, 0xa1, 0x78, 0x0e, 0xde, 0xa4, 0x78, 0xcd,
-            0xa9, 0x27, 0x8d, 0x94, 0xde, 0x19, 0xa4, 0x74, 0x38, 0xd9, 0xb8, 0x94, 0x36, 0xca, 0xd4, 0x5f,
-            0x50, 0x64, 0x21, 0x0b, 0x45, 0x88, 0xe1, 0x36, 0x70, 0x4a, 0x70, 0xb8, 0x69, 0x53, 0x54, 0x53,
-            0xd2, 0xab, 0xfc, 0x15, 0x4d, 0x4b, 0x03, 0x37, 0xba, 0x95, 0x9a, 0xf4, 0x71, 0xbd, 0xad, 0x12,
-            0x92, 0xaf, 0xbd, 0x54, 0x2d, 0x5d, 0x4c, 0x25, 0xf3, 0xfa, 0x07, 0x87, 0x91, 0x1b, 0xdc, 0xf9,
-            0xaa, 0x9d, 0xed, 0xc4, 0x3c, 0x74, 0xb4, 0x44, 0xe6, 0x9e, 0xef, 0xd3, 0x5d, 0x61, 0xac, 0xfb,
-            0xe3, 0xb2, 0xd3, 0x1d, 0xfc, 0x7f, 0x11, 0x0e, 0x79, 0x78, 0x32, 0xc8, 0x00, 0x00
-        };
-
-        private const uint8[] ZSTD_DATA = {
-            0x28, 0xb5, 0x2f, 0xfd, 0x60, 0x32, 0xc7, 0x45, 0xf1, 0x01, 0x4a, 0x51, 0x39, 0x3d, 0x2d, 0xa0,
-            0xce, 0x15, 0x3d, 0x77, 0x00, 0xd0, 0x87, 0x7d, 0x5b, 0x74, 0x72, 0xbf, 0x35, 0x7f, 0x61, 0x8f,
-            0xa3, 0xdf, 0x48, 0xd8, 0x03, 0x2b, 0xaa, 0x2f, 0xfe, 0x32, 0xe9, 0xeb, 0xb3, 0x8a, 0x4a, 0xb3,
-            0x30, 0x6a, 0xab, 0x64, 0x18, 0x4f, 0xe1, 0x75, 0x78, 0x1d, 0x9e, 0x2a, 0xb7, 0x03, 0xd0, 0x03,
-            0xbe, 0x03, 0xd0, 0xa2, 0x9d, 0x49, 0x58, 0xa8, 0xb6, 0x61, 0xe4, 0xdc, 0x9d, 0x48, 0xa3, 0x2d,
-            0xfe, 0x36, 0xf6, 0x4e, 0x74, 0x7f, 0x62, 0x56, 0xf4, 0x92, 0xe2, 0x25, 0x89, 0xe8, 0xbd, 0x15,
-            0x1b, 0xad, 0x71, 0x96, 0xf5, 0xd0, 0x0f, 0x25, 0xf9, 0x86, 0x35, 0x4f, 0xa7, 0x66, 0xe5, 0x22,
-            0x4c, 0x7b, 0x4a, 0xdf, 0xb2, 0x3d, 0xd4, 0xa5, 0xc6, 0xd2, 0x4b, 0xf8, 0xc1, 0x7e, 0xda, 0xb7,
-            0x92, 0x6e, 0xe4, 0x40, 0x6c, 0x2c, 0x6f, 0x09, 0x62, 0x22, 0x7b, 0xcc, 0x5b, 0x93, 0xb0, 0x55,
-            0x49, 0xef, 0xf1, 0x34, 0xcf, 0x67, 0x96, 0x0f, 0xf5, 0x63, 0x5e, 0xef, 0x67, 0x3c, 0xf6, 0x66,
-            0xdc, 0x8f, 0x0e, 0x0c, 0xc6, 0x04, 0xd4, 0x2e, 0x61, 0x4c, 0xbc, 0xbe, 0xbe, 0x28, 0xf6, 0x90,
-            0xc7, 0xf1, 0x5e, 0x84, 0x8d, 0xe9, 0xc5, 0x6d, 0x90, 0xe5, 0xb0, 0x2f, 0x71, 0x22, 0x36, 0xee,
-            0x0d, 0xab, 0x0e, 0xb5, 0xf4, 0xd5, 0x12, 0x03, 0x70, 0x2e, 0x11, 0x17, 0xb9, 0x22, 0x2f, 0x02,
-            0x21, 0x20, 0x24, 0x32, 0x01, 0x21, 0x62, 0x11, 0xa1, 0xb0, 0xe1, 0x5c, 0xa8, 0xd0, 0x0d, 0x94,
-            0xb0, 0x54, 0xe0, 0xf6, 0x64, 0x37, 0xc7, 0xae, 0xec, 0xbc, 0xd0, 0x02, 0xd5, 0x1a, 0x6c, 0xcf,
-            0xf9, 0x7d, 0x63, 0xe7, 0x9e, 0xb5, 0x36, 0xdf, 0x08, 0x31, 0x27, 0xa2, 0xc3, 0x0b, 0x13, 0x6a,
-            0xcb, 0xab, 0x14, 0xdf, 0xe4, 0xc1, 0xaf, 0xda, 0x86, 0xa5, 0x3a, 0x1a, 0xbd, 0x00, 0x6f, 0xce,
-            0x59, 0xab, 0x24, 0x39, 0xf8, 0x39, 0x19, 0x6a, 0x7d, 0x96, 0x82, 0x2e, 0xed, 0x68, 0xd4, 0xdc,
-            0xec, 0x2e, 0x32, 0xc0, 0xd6, 0x6a, 0x06, 0xb2, 0x30, 0x45, 0x0f, 0xa4, 0x10, 0x59, 0xf1, 0xad,
-            0x05, 0x01, 0x59, 0x8b, 0x66, 0x19, 0xcb, 0x7a, 0x30, 0xf4, 0xfc, 0x86, 0x1c, 0x8d, 0x4f, 0x79,
-            0x6f, 0x34, 0x82, 0x0e, 0x0e, 0x52, 0x33, 0x30, 0x60, 0xa9, 0x1d, 0x1c, 0x26, 0x97, 0xed, 0x6a,
-            0xd2, 0xdd, 0xf9, 0x27, 0x8a, 0xf8, 0x10, 0xd7, 0x1c, 0x21, 0x0c, 0x04, 0xf0, 0x0c, 0xe8, 0x88,
-            0x00, 0x31, 0x62, 0xd2, 0x58, 0xeb, 0x1c, 0x25, 0xc4, 0x53, 0xab, 0x65, 0xcc, 0xef, 0xe2, 0xc3,
-            0x9e, 0x37, 0x67, 0x14, 0x50, 0x81, 0x5d, 0x55, 0x0d, 0x4b, 0x94, 0x07, 0xf5, 0x98, 0x3f, 0xc9,
-            0x13, 0xcb, 0xb9, 0x39, 0x1b, 0x5e, 0xd5, 0x9a, 0x50, 0xf1, 0x4d, 0xe4, 0x83, 0x5e, 0x2d, 0x89,
-            0x14, 0xf3, 0x7b, 0x94, 0xa6, 0xbc, 0x2e, 0xc2, 0x8d, 0x7a, 0xa4, 0xb6, 0x26, 0x08, 0xe7, 0x71,
-            0xb3, 0xad, 0xfc, 0x0f, 0x26, 0xdc, 0x57, 0xd3, 0xcf, 0xe5, 0xb3, 0x49, 0xbb, 0xb0, 0x34, 0xce,
-            0x66, 0x58, 0xbe, 0x84, 0x7e, 0x5a, 0xad, 0xf6, 0x78, 0xf0, 0x24, 0xba, 0xb2, 0x35, 0x93, 0x95,
-            0x9e, 0x99, 0xec, 0xe5, 0x1b, 0xda, 0x84, 0xbf, 0x6a, 0x92, 0x0e, 0x06, 0x23, 0xe3, 0x32, 0x5d,
-            0xfa, 0x78, 0xd2, 0x74, 0xea, 0x55, 0xed, 0x44, 0x9f, 0x62, 0x68, 0xd4, 0xad, 0xe7, 0x36, 0xdf,
-            0xf0, 0xb4, 0x45, 0x5b, 0xc3, 0x41, 0xa6, 0x07, 0xb8, 0xef, 0x16, 0xba, 0x58, 0x98, 0xb2, 0xea,
-            0x69, 0x47, 0x3b, 0x9d, 0xf0, 0x54, 0x81, 0xe9, 0x05, 0x17, 0x3d, 0xd0, 0x3a, 0x33, 0xbd, 0xb7,
-            0xa7, 0xb5, 0x8b, 0x26, 0xc2, 0xd4, 0x18, 0xbd, 0xf6, 0x33, 0x1a, 0x47, 0x55, 0xe1, 0xb4, 0x92,
-            0x8d, 0x27, 0xec, 0x95, 0xbe, 0xdb, 0x0b, 0x91, 0x65, 0x3b, 0xf2, 0x33, 0xd3, 0x6d, 0x4d, 0x47,
-            0xf5, 0x1c, 0xb1, 0x66, 0xc3, 0x24, 0x99, 0x17, 0xe6, 0xc8, 0xbc, 0x30, 0x27, 0x4c, 0x08, 0x73,
-            0x41, 0x83, 0x39, 0x32, 0xb1, 0x19, 0x9a, 0xd7, 0x74, 0x8e, 0x49, 0x67, 0x67, 0x76, 0x68, 0x7e,
-            0xc6, 0x7c, 0x30, 0x25, 0x07, 0x54, 0x7e, 0x08, 0x24, 0x08, 0xe9, 0xf6, 0x88, 0xa4, 0x9f, 0xdb,
-            0x8d, 0x2f, 0xdd, 0xb0, 0xe7, 0xda, 0x8c, 0x0b, 0x23, 0xfa, 0x6a, 0x55, 0x8d, 0x3e, 0xf8, 0x6b,
-            0xb7, 0xbe, 0x21, 0x0d, 0x5c, 0xd1, 0x0d, 0x82, 0x3b, 0x16, 0x63, 0xb5, 0x07, 0xe7, 0xda, 0x7b,
-            0xbb, 0x00, 0x01, 0x49, 0xe2, 0x0c, 0x10, 0xb0, 0x91, 0x99, 0x00, 0x84, 0x00, 0x6b, 0x33, 0x59,
-            0x4e, 0x35, 0x1a, 0xbb, 0xdd, 0x70, 0xdf, 0xca, 0xe9, 0xd7, 0xdb, 0x99, 0x6f, 0xe0, 0xaa, 0xb7,
-            0xcc, 0x63, 0x6b, 0x2d, 0x1c, 0x63, 0xdf, 0x37, 0x5a, 0xfb, 0xaa, 0xe9, 0x6b, 0x1d, 0x13, 0x69,
-            0x8e, 0xc1, 0x20, 0x97, 0xd6, 0xb8, 0xdf, 0xc2, 0xda, 0x0d, 0x69, 0x1c, 0xf2, 0x34, 0xd3, 0x60,
-            0xcb, 0x66, 0xdf, 0x9e, 0x8a, 0x9d, 0x5e, 0x0d, 0xa8, 0xeb, 0x03, 0x8d, 0x7a, 0xe8, 0xa5, 0x1f,
-            0xb7, 0x1f, 0x73, 0x16, 0xdf, 0x58, 0x06, 0x73, 0x95, 0xcd, 0x78, 0xa7, 0x8f, 0xbd, 0xd6, 0x0f,
-            0xcd, 0xda, 0x42, 0xd3, 0xec, 0xad, 0x2a, 0xf4, 0xa9, 0xb5, 0x99, 0x48, 0x4e, 0x25, 0x94, 0x6d,
-            0xde, 0x74, 0xad, 0xd6, 0x19, 0x5c, 0x2d, 0xf9, 0x3a, 0x56, 0xeb, 0xbc, 0xa9, 0x37, 0x91, 0x46,
-            0x74, 0xa9, 0x57, 0x8b, 0x77, 0xfb, 0xbf, 0x92, 0x54, 0xae, 0xf7, 0x55, 0xbb, 0xdb, 0xaa, 0x41,
-            0x30, 0xe8, 0x39, 0xdb, 0x9e, 0xfa, 0x1a, 0xad, 0xef, 0x6d, 0xf5, 0xbd, 0xc8, 0xbe, 0x82, 0x24,
-            0xe7, 0x7d, 0x86, 0xd5, 0xce, 0xb2, 0xb7, 0x2a, 0x08, 0x3f, 0xf9, 0xaa, 0xb7, 0x99, 0xac, 0x06,
-            0xf7, 0x73, 0x9d, 0x7a, 0xff, 0xe9, 0xab, 0x1a, 0xa3, 0x9a, 0xdf, 0xea, 0xad, 0x32, 0x17, 0x90,
-            0xd5, 0x34, 0xba, 0x3d, 0xcc, 0x2b, 0x96, 0xcf, 0xea, 0xf7, 0x16, 0x5e, 0xe5, 0x55, 0x7c, 0xed,
-            0xd3, 0xaa, 0x5a, 0xbe, 0xd1, 0x16, 0xa7, 0x55, 0x5e, 0x25, 0x84, 0x80, 0xd6, 0xfe, 0x1b, 0x62,
-            0x12, 0x51, 0xad, 0x31, 0x1e, 0x47, 0x87, 0x46, 0xe3, 0xb6, 0x7b, 0x7d, 0x53, 0x6b, 0xa2, 0xcf,
-            0x64, 0x5e, 0xe3, 0x68, 0x63, 0x8d, 0xe2, 0xda, 0xa1, 0xe1, 0x98, 0x0c, 0xf7, 0xbd, 0xfa, 0x4a,
-            0x88, 0x88, 0xa9, 0x2f, 0xd4, 0x4c, 0x67, 0x15, 0xbd, 0x90, 0xcd, 0xdd, 0x9f, 0xac, 0xd6, 0x3a,
-            0xd4, 0x2f, 0xa2, 0x6b, 0x1f, 0xd7, 0xac, 0x9b, 0xb0, 0x7a, 0xb5, 0x5b, 0x0f, 0xcc, 0x6a, 0x6e,
-            0x2b, 0xf6, 0xfe, 0xd0, 0xa5, 0xdb, 0xda, 0x28, 0x08, 0x97, 0x50, 0x0d, 0xc3, 0xec, 0x53, 0xed,
-            0xc2, 0xb2, 0xfa, 0x63, 0x3d, 0x7d, 0x65, 0x96, 0x7c, 0xe2, 0x97, 0xfb, 0xbe, 0x54, 0x7c, 0x8f,
-            0xed, 0xf6, 0x46, 0x23, 0x6b, 0x7a, 0x17, 0x5f, 0xf6, 0x84, 0x9b, 0xd3, 0xe8, 0xe7, 0x71, 0x63,
-            0xab, 0x55, 0x9a, 0x56, 0x61, 0x79, 0xbd, 0x42, 0x94, 0x84, 0xde, 0xc6, 0xb0, 0xeb, 0x72, 0x8b,
-            0x71, 0x57, 0xf6, 0x6e, 0x52, 0xd3, 0x38, 0x9f, 0x2c, 0x6a, 0x39, 0xdc, 0x76, 0xd3, 0xc1, 0xe4,
-            0xb1, 0xdb, 0x8a, 0x7a, 0x5f, 0xd5, 0xfb, 0x78, 0xd2, 0x98, 0x7b, 0x5d, 0x84, 0x6e, 0xeb, 0x57,
-            0xce, 0x5d, 0x33, 0xe4, 0xf9, 0x6c, 0x72, 0xe9, 0x27, 0xd5, 0x73, 0xb3, 0xf4, 0xfe, 0xb9, 0xf4,
-            0x1c, 0x3d, 0x9b, 0x5f, 0x5e, 0x47, 0xbe, 0x37, 0x95, 0x54, 0x56, 0xeb, 0x74, 0xf0, 0xda, 0xac,
-            0xf2, 0x6e, 0x87, 0x1e, 0xa1, 0x8b, 0x18, 0xcd, 0x36, 0xa3, 0x96, 0x4b, 0xcc, 0x29, 0x48, 0xe6,
-            0xba, 0x18, 0x26, 0x06, 0x0a, 0x86, 0xad, 0x9b, 0x94, 0xba, 0xba, 0xb1, 0xcc, 0x64, 0x37, 0x58,
-            0xc8, 0xdc, 0x74, 0x8e, 0x8b, 0x21, 0xcf, 0x56, 0x56, 0x52, 0xab, 0x46, 0xa3, 0x1c, 0x1b, 0x40,
-            0x14, 0xc0, 0xf9, 0xff, 0x7f, 0xd2, 0x02, 0x83, 0xc9, 0xf1, 0x49, 0x4e, 0xc5, 0x25, 0x0c, 0xb3,
-            0x20, 0x46, 0x86, 0xa5, 0x2d, 0x83, 0x9e, 0xc9, 0x97, 0xe9, 0x2f, 0x7d, 0xac, 0x35, 0xf5, 0xfd,
-            0xa1, 0x50, 0x44, 0x81, 0x65, 0x10, 0x34, 0x33, 0x2a, 0x96, 0x54, 0xb4, 0x73, 0xd1, 0x91, 0x30,
-            0x38, 0xdb, 0x83, 0x61, 0x72, 0x93, 0x96, 0xcc, 0x60, 0x7f, 0xee, 0xd6, 0xcc, 0xd1, 0xe8, 0xe7,
-            0x8f, 0x74, 0x03, 0x49, 0x17, 0x2b, 0x5b, 0x55, 0xda, 0xac, 0x34, 0x5c, 0x33, 0x09, 0xd7, 0x89,
-            0xeb, 0xe4, 0x53, 0x48, 0x84, 0xc9, 0x22, 0x63, 0x7a, 0x5e, 0xb1, 0xee, 0x50, 0xd3, 0xf4, 0xda,
-            0xad, 0xbf, 0xc6, 0xb4, 0x82, 0x70, 0x43, 0x6e, 0xea, 0x52, 0x4d, 0xf2, 0xdf, 0x0f, 0x42, 0x22,
-            0x70, 0x9d, 0x91, 0xb9, 0xf3, 0xde, 0x9b, 0xa1, 0x34, 0xdd, 0xce, 0x3a, 0xaf, 0xac, 0xb0, 0xaa,
-            0x0c, 0x5c, 0x26, 0x91, 0x80, 0x81, 0xb1, 0xe8, 0xe8, 0x92, 0x8d, 0xf3, 0x8b, 0x4e, 0x66, 0xf3,
-            0xd8, 0x8b, 0xaf, 0xbe, 0x21, 0xea, 0x92, 0xfe, 0x68, 0xd9, 0x56, 0x6a, 0x9c, 0x35, 0x97, 0xb6,
-            0x26, 0x7d, 0xc9, 0xe4, 0x5e, 0xec, 0xd6, 0xf6, 0xc7, 0xbd, 0x8d, 0x01, 0x31, 0x72, 0xf8, 0x15,
-            0x17, 0x97, 0x52, 0xbe, 0x12, 0x0b, 0x48, 0x48, 0x3c, 0x9c, 0xdf, 0x12, 0x1b, 0x1c, 0x1d, 0x98,
-            0x0b, 0x07, 0x87, 0x0b, 0x06, 0xc6, 0x63, 0x44, 0x13, 0xe1, 0xa2, 0x61, 0x70, 0xdb, 0xd1, 0x3e,
-            0xbe, 0xd5, 0xbb, 0x92, 0x1c, 0x5e, 0x78, 0x9c, 0xcb, 0x3e, 0x47, 0x37, 0x1e, 0x1b, 0xec, 0xcf,
-            0xa0, 0xa2, 0x6c, 0x8e, 0x12, 0x5c, 0xa9, 0xf8, 0x13, 0x57, 0xce, 0xc3, 0xa3, 0x5c, 0xca, 0xdb,
-            0x3c, 0x8a, 0x85, 0x0e, 0x0e, 0x3d, 0xab, 0xd6, 0xd3, 0xd4, 0x1e, 0xea, 0x81, 0x51, 0xfb, 0x20,
-            0x22, 0xf2, 0xf0, 0xdc, 0x1d, 0x1c, 0xda, 0xaa, 0x9b, 0x4a, 0xb6, 0xd4, 0x60, 0x57, 0xb4, 0x94,
-            0x9e, 0x1f, 0x1e, 0xa6, 0x55, 0x27, 0x9f, 0x6a, 0x3d, 0xfa, 0xe0, 0x7b, 0x57, 0x94, 0xc4, 0xaa,
-            0x98, 0x6e, 0x6d, 0x88, 0x2c, 0x1a, 0x6b, 0x48, 0x5f, 0xb6, 0x09, 0xc1, 0x6e, 0x77, 0x2a, 0x5a,
-            0x55, 0x7a, 0xca, 0xe3, 0xf4, 0xe6, 0xaa, 0x54, 0x44, 0xf7, 0x9d, 0x6e, 0x95, 0xfe, 0xdc, 0xae,
-            0x00, 0xc8, 0x76, 0xea, 0xa4, 0xc6, 0x7a, 0xf4, 0x45, 0xd9, 0x7c, 0xfb, 0xaf, 0x8a, 0x0a, 0x42,
-            0xc5, 0x2a, 0x1b, 0x2c, 0x74, 0x91, 0x7a, 0x34, 0xff, 0xd4, 0x65, 0xec, 0x90, 0x6a, 0xa7, 0x2e,
-            0x15, 0xa5, 0x77, 0xac, 0xad, 0x64, 0x36, 0x47, 0x50, 0x26, 0x8e, 0x6f, 0xa2, 0x70, 0x7c, 0x56,
-            0x7d, 0xd2, 0xc2, 0xa6, 0x15, 0x6e, 0x29, 0x93, 0xb9, 0xa0, 0x3c, 0x00, 0x6f, 0x7e, 0x95, 0x56,
-            0xb3, 0x81, 0x7d, 0x5e, 0x77, 0x06, 0x1a, 0x9e, 0x73, 0x17, 0x2f, 0xe2, 0xc3, 0xc6, 0x34, 0xc4,
-            0xd2, 0xc5, 0x63, 0xdb, 0x76, 0x7a, 0xee, 0x0b, 0x03, 0xed, 0xcc, 0xed, 0xcf, 0x86, 0x61, 0x62,
-            0x7d, 0x62, 0xf5, 0xe4, 0x51, 0x9c, 0xf2, 0x30, 0x79, 0x0f, 0x94, 0xa6, 0x3c, 0xbc, 0x09, 0x9e,
-            0x74, 0xa6, 0x79, 0x80, 0x1a, 0xb7, 0xd6, 0x0c, 0x71, 0xb5, 0x8f, 0xfb, 0x25, 0x4b, 0x03, 0x8c,
-            0x01, 0xb0, 0x08, 0x8c, 0x72, 0x44, 0x01, 0x5a, 0x3a, 0xb3, 0xc1, 0x35, 0x73, 0x6e, 0x7b, 0xce,
-            0xf6, 0xe7, 0x4e, 0x4e, 0xe1, 0xf0, 0x43, 0x6a, 0xc9, 0x21, 0x72, 0x2b, 0x61, 0xe7, 0xeb, 0x9f,
-            0x7d, 0xb3, 0xf2, 0xa7, 0xdb, 0xde, 0x8f, 0xab, 0x26, 0x3f, 0xdf, 0x7d, 0xc8, 0x16, 0xf5, 0x68,
-            0x34, 0x41, 0xed, 0xf1, 0x34, 0x04, 0x0c, 0x07, 0x07, 0x26, 0xa3, 0x52, 0x99, 0x68, 0xca, 0x63,
-            0x17, 0x78, 0x6c, 0x60, 0x5c, 0x2e, 0x2e, 0x20, 0x1f, 0x23, 0x1e, 0x98, 0x0d, 0xcd, 0x46, 0x06,
-            0xf3, 0x31, 0xa2, 0xf1, 0xb8, 0x74, 0x84, 0x5c, 0x60, 0x30, 0xa4, 0x8a, 0xed, 0x47, 0x5f, 0x2a,
-            0x59, 0xdb, 0x58, 0xae, 0x60, 0x87, 0x24, 0x49, 0x54, 0x84, 0xdb, 0xac, 0xf0, 0x6c, 0x5c, 0x73,
-            0xc4, 0x52, 0x7c, 0x6c, 0xb3, 0x87, 0x22, 0x6b, 0xaf, 0x94, 0xc0, 0x83, 0x39, 0x5b, 0x3f, 0x7d,
-            0x37, 0x67, 0x60, 0x90, 0x52, 0xa7, 0x66, 0x42, 0xed, 0x05, 0x36, 0x78, 0x45, 0x04, 0x32, 0x3e,
-            0x36, 0xbb, 0x23, 0xfc, 0xab, 0x66, 0x78, 0xb3, 0x38, 0x57, 0x2a, 0x13, 0x9c, 0x4d, 0x44, 0xc5,
-            0x42, 0xa1, 0x7c, 0x97, 0x9b, 0xf3, 0xfa, 0x11, 0x94, 0x9e, 0x2e, 0xfd, 0xda, 0x77, 0x70, 0x78,
-            0xf2, 0x4e, 0xed, 0x42, 0x74, 0xff, 0xf7, 0xc0, 0xbb, 0xd7, 0xf3, 0x02, 0x2a, 0x11, 0x16, 0x09,
-            0x12, 0xda, 0x56, 0x69, 0x09, 0x1d, 0x0e, 0x6b, 0x18, 0x6c, 0x00, 0x7b, 0x02, 0x84, 0x07, 0x71,
-            0x2f, 0x5c, 0x70, 0x17, 0x3c, 0xc4, 0x95, 0x43, 0x6a, 0xf7, 0x38, 0xbb, 0xc1, 0x68, 0xb4, 0x31,
-            0xb8, 0x30, 0x35, 0x05, 0x94, 0x3d, 0x02, 0x35, 0x0d, 0x41, 0xb3, 0x47, 0x3a, 0xa1, 0x50, 0xcb,
-            0x7f, 0x98, 0xe1, 0x6a, 0x70, 0xa9, 0x59, 0x92, 0xd7, 0x5a, 0xd2, 0x2a, 0xfd, 0xb6, 0x9e, 0x45,
-            0xad, 0xf6, 0x00, 0x42, 0xc7, 0x58, 0x1a, 0x28, 0x16, 0x91, 0x67, 0x79, 0x39, 0xab, 0x2e, 0xa5,
-            0x64, 0x3f, 0x3b, 0xbe, 0x90, 0xc5, 0x32, 0x6d, 0xff, 0x19, 0x07, 0x48, 0x48, 0x88, 0xa7, 0x7f,
-            0x43, 0x83, 0xa7, 0x86, 0x11, 0x28, 0xe8, 0x81, 0xc9, 0x30, 0xf8, 0xf4, 0x4f, 0x8e, 0x6f, 0x1c,
-            0x8a, 0xfe, 0xf6, 0x66, 0xef, 0x87, 0x83, 0x30, 0x75, 0x22, 0x35, 0x0b, 0x05, 0x8b, 0x58, 0x22,
-            0xf4, 0x58, 0xf4, 0xd5, 0xf0, 0x0a, 0x92, 0xf0, 0xd8, 0x7f, 0xdb, 0xb9, 0x9b, 0xfd, 0x08, 0xbf,
-            0x6a, 0x90, 0xf7, 0xae, 0x96, 0x73, 0xd6, 0x22, 0xa3, 0x46, 0x4e, 0x6f, 0x1e, 0x66, 0x98, 0xdb,
-            0x24, 0x0a, 0xa5, 0xa9, 0x97, 0x68, 0x0a, 0x62, 0x36, 0xdc, 0xc0, 0x0e, 0xef, 0x26, 0xe7, 0x37,
-            0xaf, 0x6d, 0x49, 0x7f, 0x3c, 0xce, 0x9b, 0xd8, 0x4d, 0x25, 0xd9, 0xff, 0xbe, 0xf1, 0xc2, 0x8d,
-            0x2e, 0x5e, 0x8d, 0x64, 0x6d, 0x17, 0xaf, 0xbd, 0xd3, 0xbe, 0x07, 0xeb, 0xb4, 0x48, 0x4c, 0x58,
-            0x24, 0x1e, 0xe5, 0x29, 0x0f, 0x13, 0xef, 0xf6, 0x05, 0x55, 0xea, 0x9b, 0x93, 0x7e, 0x4f, 0xbf,
-            0xc4, 0x84, 0xc4, 0x43, 0xf7, 0x75, 0xbe, 0x74, 0xa9, 0x28, 0x55, 0x79, 0xa1, 0x07, 0xc7, 0xac,
-            0xb7, 0xa3, 0x2a, 0xde, 0x93, 0xd5, 0x32, 0x61, 0x11, 0x91, 0xa0, 0x08, 0xc0, 0xc9, 0x88, 0x60,
-            0x91, 0xcd, 0x04, 0xc5, 0x04, 0x85, 0x0d, 0x16, 0x09, 0x1f, 0xd9, 0x21, 0x39, 0xc6, 0xed, 0xe9,
-            0x2a, 0xbd, 0x22, 0x7c, 0xfd, 0xe9, 0xa7, 0x9a, 0x56, 0x41, 0x4d, 0x33, 0x5e, 0x52, 0xd1, 0x27,
-            0xbe, 0xa9, 0xac, 0xd0, 0xdd, 0xda, 0x8c, 0x27, 0x53, 0x47, 0x6b, 0x5b, 0x7d, 0x8d, 0xe3, 0xe2,
-            0x7d, 0xd8, 0x4e, 0xb9, 0x7b, 0x67, 0xab, 0xa5, 0xb7, 0xd5, 0xa2, 0x37, 0x64, 0x3b, 0x25, 0xd5,
-            0x6b, 0xad, 0x6f, 0x63, 0xd4, 0x53, 0x1f, 0x67, 0xf3, 0x8d, 0x2d, 0xad, 0xeb, 0x37, 0x76, 0x0f,
-            0xcd, 0xdc, 0xeb, 0xd4, 0x5f, 0xb5, 0x23, 0x2a, 0x31, 0x82, 0x56, 0x7e, 0xbf, 0xf1, 0x6b, 0xed,
-            0x92, 0x8a, 0xa0, 0x44, 0x88, 0xd1, 0x08, 0xce, 0x77, 0xce, 0x82, 0xe6, 0xf7, 0xfd, 0xff, 0xaa,
-            0xf1, 0x0c, 0xe6, 0xf7, 0xec, 0xb6, 0xfc, 0xe6, 0x29, 0xde, 0xa9, 0x93, 0x97, 0x83, 0x52, 0x13,
-            0x82, 0x80, 0x84, 0x83, 0xc3, 0x9c, 0xc0, 0xdc, 0xfb, 0xbb, 0xa0, 0x2a, 0xb9, 0x12, 0x41, 0xe3,
-            0x3d, 0xcd, 0x65, 0xc1, 0x83, 0xde, 0x9b, 0xbd, 0x59, 0x48, 0x76, 0xc6, 0x78, 0xfb, 0xd7, 0xe0,
-            0xe8, 0x70, 0xd0, 0xb0, 0x25, 0x50, 0xfd, 0xba, 0x4c, 0xe1, 0x40, 0xe1, 0x10, 0x80, 0xe3, 0x40,
-            0x61, 0x33, 0x3b, 0x15, 0x49, 0x44, 0x12, 0xc1, 0xae, 0x7d, 0x08, 0xb2, 0xfb, 0x4c, 0xcc, 0x94,
-            0x76, 0xe9, 0x0f, 0xcd, 0x68, 0x3c, 0xd4, 0xc9, 0x43, 0x8e, 0xf3, 0x9f, 0x44, 0xf2, 0x57, 0x11,
-            0x75, 0x2a, 0x96, 0xd4, 0x0d, 0xb2, 0xbb, 0x33, 0xe8, 0xa9, 0x31, 0x47, 0xab, 0xcb, 0x55, 0x65,
-            0xc5, 0x12, 0x4f, 0xf5, 0x82, 0x52, 0xd9, 0x4e, 0xf2, 0x4e, 0xd2, 0xe5, 0x4f, 0x5d, 0x84, 0x9c,
-            0xda, 0xe5, 0x38, 0x9b, 0x6f, 0x0c, 0x7e, 0x1e, 0x86, 0xcc, 0xcf, 0x95, 0x84, 0x84, 0xfb, 0x0d,
-            0xa8, 0x1f, 0x79, 0x95, 0xca, 0xbd, 0x5c, 0x15, 0x61, 0x3e, 0x09, 0xf5, 0x24, 0x1f, 0xf7, 0x41,
-            0x8e, 0x78, 0x5a, 0x2a, 0x4a, 0x57, 0xd6, 0xb7, 0x16, 0x77, 0xeb, 0x69, 0x3d, 0x64, 0xba, 0xbb,
-            0xcb, 0xfc, 0xb0, 0x35, 0x7a, 0xfd, 0x24, 0x69, 0xa7, 0xc3, 0x75, 0x3a, 0x8f, 0x7d, 0xcc, 0x5d,
-            0x3c, 0x01, 0x0d, 0x95, 0x88, 0x86, 0x27, 0x31, 0x4b, 0xdc, 0xc0, 0xf8, 0x25, 0xff, 0xa1, 0xd1,
-            0x1d, 0xdd, 0xa0, 0x99, 0xe1, 0xb3, 0x8b, 0x18, 0x0d, 0x3d, 0x6f, 0xc4, 0x37, 0x1a, 0x75, 0x31,
-            0x3e, 0x5a, 0x72, 0x73, 0x2c, 0x10, 0x23, 0xa6, 0x0a, 0xe5, 0x4d, 0x5a, 0x25, 0x82, 0x62, 0xa5,
-            0xf5, 0x01, 0x14, 0x7f, 0xee, 0xfe, 0x1f, 0xb5, 0x27, 0xca, 0x76, 0xd1, 0x3a, 0xc6, 0x76, 0xf1,
-            0x62, 0xbc, 0x05, 0xeb, 0x15, 0x44, 0x6e, 0xb8, 0x7b, 0x60, 0xa3, 0x51, 0xff, 0xab, 0xf8, 0x0b,
-            0x0b, 0x8f, 0xaf, 0x00, 0x89, 0xaf, 0x29, 0x6f, 0x62, 0x36, 0xd5, 0x2e, 0xe9, 0x51, 0xde, 0xc3,
-            0x44, 0x4e, 0x24, 0xc8, 0xb4, 0x8f, 0xb1, 0x93, 0x38, 0x09, 0xf5, 0x28, 0x9d, 0x70, 0x26, 0xf2,
-            0x69, 0xbc, 0x8b, 0x1d, 0x6f, 0x6c, 0x8f, 0xdb, 0x5f, 0x5b, 0xfa, 0x0b, 0xcc, 0x03, 0x87, 0x53,
-            0x79, 0xa0, 0x3c, 0x5c, 0x3b, 0x99, 0xc8, 0x08, 0x61, 0x05, 0x4f, 0x36, 0x01, 0x14, 0x6c, 0x02,
-            0x58, 0x2c, 0xd2, 0x03, 0xbc, 0x7c, 0x44, 0x80, 0xf3, 0x2b, 0xf7, 0x19, 0x2e, 0xd5, 0xe7, 0x2b,
-            0xaf, 0x6c, 0x2b, 0xdd, 0x0e, 0x85, 0xab, 0xe4, 0x1d, 0xcc, 0x46, 0xe6, 0x66, 0x87, 0xeb, 0xed,
-            0x38, 0x46, 0x75, 0x5f, 0x73, 0x74, 0xd9, 0x19, 0xea, 0xce, 0xce, 0xed, 0x8f, 0x9d, 0x5e, 0x29,
-            0x1a, 0x2f, 0xe5, 0xdd, 0xb6, 0x2a, 0xc8, 0x5e, 0x69, 0xef, 0x7f, 0x3a, 0xf9, 0x3e, 0x32, 0x4c,
-            0x35, 0xbe, 0x7a, 0xa5, 0x64, 0xc6, 0x43, 0x40, 0x08, 0x90, 0xf0, 0x3b, 0x0f, 0xf4, 0x61, 0x06,
-            0xa8, 0x9e, 0x6f, 0xdc, 0x17, 0x2a, 0xee, 0x2b, 0xdf, 0xa3, 0xde, 0x23, 0x82, 0xff, 0xa2, 0x8f,
-            0xb9, 0xe2, 0xa9, 0xb3, 0xc5, 0x45, 0xaa, 0xa2, 0x9c, 0xd5, 0xd4, 0xed, 0xb5, 0x0e, 0x29, 0xa7,
-            0x56, 0x66, 0x14, 0xa3, 0x9b, 0x7d, 0x08, 0x89, 0xa8, 0x65, 0xce, 0xe6, 0xda, 0x0c, 0x8b, 0x9b,
-            0xbf, 0x61, 0xd4, 0xd1, 0xe8, 0x6a, 0x0b, 0x73, 0xb8, 0xe6, 0x88, 0xe5, 0x28, 0x39, 0xc8, 0xc1,
-            0xcf, 0x1b, 0xed, 0x28, 0xa1, 0x0d, 0x41, 0xa2, 0x14, 0x53, 0xed, 0xc1, 0xcc, 0xd1, 0x36, 0x1e,
-            0xae, 0x2f, 0xc9, 0xc9, 0x7e, 0xcc, 0xde, 0xde, 0xa8, 0xa8, 0x1b, 0x68, 0xf7, 0xab, 0xb7, 0xae,
-            0xb5, 0x50, 0x24, 0x00, 0x14, 0x1e, 0x7d, 0x0f, 0x13, 0xf9, 0xf0, 0x9f, 0x65, 0xef, 0x2c, 0x67,
-            0xba, 0xab, 0xc2, 0x3a, 0x53, 0x38, 0x00, 0x28, 0x6c, 0x28, 0x6c, 0x7c, 0x14, 0x2f, 0x4f, 0x3b,
-            0xed, 0x68, 0x44, 0xa7, 0x4a, 0x31, 0x2d, 0xf5, 0x2a, 0x28, 0x2b, 0xad, 0x46, 0xab, 0xf5, 0x3a,
-            0x40, 0x30, 0x19, 0x23, 0xa3, 0xd1, 0xc3, 0x8a, 0x7f, 0x8a, 0x31, 0xc4, 0x77, 0xf5, 0x6d, 0x7f,
-            0x97, 0x39, 0xe7, 0xec, 0x53, 0x27, 0xa7, 0xe9, 0x23, 0xc8, 0xde, 0x26, 0xc3, 0xbc, 0x95, 0x56,
-            0x49, 0x6f, 0x4b, 0xaa, 0xaa, 0x55, 0x0f, 0x1c, 0xb7, 0xff, 0x36, 0x0f, 0x9c, 0xfc, 0xbe, 0x7a,
-            0x36, 0x9e, 0x6c, 0x34, 0x7a, 0xd7, 0xa3, 0x66, 0xaf, 0x38, 0x79, 0x97, 0xd8, 0x6f, 0x4b, 0xb3,
-            0x19, 0x6e, 0x0e, 0xdd, 0x58, 0x7b, 0x39, 0x3c, 0xa5, 0x0c, 0x67, 0x19, 0xfe, 0x18, 0x2f, 0xd2,
-            0x35, 0x3d, 0xcb, 0xc3, 0xcd, 0x67, 0x65, 0x15, 0xa5, 0xf2, 0xca, 0xd5, 0xc5, 0xe5, 0x3a, 0x33,
-            0x9e, 0xb4, 0x1e, 0xe1, 0x26, 0x71, 0x54, 0xee, 0x9e, 0xe8, 0xf6, 0xa7, 0xdf, 0x46, 0x44, 0x6e,
-            0x2c, 0x54, 0xbc, 0x90, 0x16, 0x62, 0x3a, 0x6b, 0xfd, 0xd7, 0x27, 0x69, 0x5f, 0x3a, 0x91, 0xcf,
-            0x6d, 0x1f, 0x2f, 0xb1, 0x1d, 0xcc, 0x6e, 0x09, 0x57, 0xfd, 0xdb, 0xb3, 0xdf, 0xc3, 0x4c, 0xcf,
-            0xf8, 0x45, 0x38, 0x99, 0x26, 0x14, 0x13, 0x4c, 0x79, 0x12, 0x94, 0x2e, 0x31, 0x7c, 0x9c, 0x7f,
-            0x92, 0x3d, 0x75, 0x3d, 0x85, 0xe8, 0xbb, 0x08, 0x6b, 0x3f, 0xbb, 0xba, 0x9c, 0xc5, 0x52, 0xc6,
-            0x85, 0x8e, 0x79, 0x6f, 0x52, 0x3e, 0x53, 0x7e, 0xbe, 0x43, 0x54, 0x2a, 0xcd, 0xc1, 0x13, 0x3f,
-            0x4a, 0xa5, 0xbc, 0xc9, 0x8b, 0x98, 0x17, 0xbe, 0x4b, 0xce, 0x10, 0x21, 0x3e, 0xd6, 0x27, 0x22,
-            0x42, 0x45, 0x54, 0x26, 0xc8, 0xfb, 0x39, 0x82, 0x02, 0xc1, 0xe7, 0x8d, 0xb1, 0x17, 0x7c, 0xc7,
-            0xec, 0x00, 0x76, 0x12, 0xb0, 0x08, 0x85, 0x0b, 0x8b, 0x7c, 0x78, 0x0f, 0x9b, 0xd9, 0x13, 0x12,
-            0x54, 0x20, 0x20, 0x4c, 0xa8, 0x54, 0x34, 0x8c, 0xf4, 0x02, 0x8e, 0xb4, 0xcc, 0x8b, 0x65, 0x76,
-            0x03, 0xce, 0x46, 0xf6, 0x06, 0xe3, 0x5b, 0xe9, 0xd4, 0x4d, 0x9f, 0xea, 0xc6, 0x56, 0x6b, 0xeb,
-            0xa7, 0x63, 0x00, 0xb2, 0x37, 0xfb, 0xab, 0x65, 0x3b, 0x38, 0x50, 0x6c, 0x16, 0x42, 0x2a, 0xff,
-            0x74, 0xaa, 0xa7, 0x07, 0x82, 0x1a, 0x07, 0x54, 0x84, 0xd9, 0x01, 0x44, 0x86, 0x79, 0x92, 0x0f,
-            0x3a, 0xec, 0x48, 0x14, 0x78, 0xb3, 0x9b, 0xc7, 0xd1, 0xe8, 0x51, 0x94, 0x84, 0xcf, 0xdb, 0x3c,
-            0xf8, 0x84, 0x37, 0x51, 0x21, 0x7b, 0xad, 0x34, 0xa6, 0x3d, 0xc1, 0x9e, 0xc9, 0x24, 0x62, 0x22,
-            0x27, 0xd9, 0xdb, 0xb2, 0x6a, 0x36, 0xd1, 0x6a, 0xa7, 0xe2, 0xfa, 0xa1, 0x20, 0x2a, 0xba, 0xd9,
-            0x4e, 0xaa, 0x40, 0xa9, 0x30, 0x91, 0xbb, 0x6b, 0xc0, 0x12, 0x15, 0xe4, 0x7b, 0x53, 0x85, 0x97,
-            0xbb, 0x86, 0x37, 0x7d, 0x52, 0x81, 0x02, 0x3a, 0x04, 0xd1, 0xf5, 0x06, 0x1c, 0xde, 0xa0, 0x19,
-            0xf8, 0xfb, 0xed, 0x37, 0xcd, 0x19, 0x0f, 0x4c, 0xfa, 0xb6, 0xfb, 0x05, 0x92, 0x2b, 0xa5, 0xec,
-            0xf2, 0xe4, 0x51, 0x26, 0x99, 0xc9, 0x9b, 0x60, 0xf5, 0x43, 0xa8, 0xa6, 0x6c, 0x0b, 0x91, 0xfd,
-            0x5f, 0xa9, 0xa8, 0x4c, 0xf2, 0x65, 0xf7, 0x24, 0x43, 0x1d, 0xab, 0x93, 0x22, 0x89, 0xc9, 0x37,
-            0x3b, 0x6f, 0x67, 0xe8, 0x59, 0x5a, 0xd7, 0x69, 0xdd, 0x9c, 0x89, 0x44, 0x5b, 0x27, 0x63, 0xb0,
-            0x27, 0xf6, 0x0f, 0x0c, 0x20, 0x10, 0xc0, 0x30, 0x35, 0xee, 0xe2, 0x30, 0x9d, 0x77, 0xa3, 0xac,
-            0x8c, 0xa2, 0x14, 0xe6, 0x99, 0xf7, 0x79, 0xa4, 0x83, 0x43, 0xde, 0xac, 0x8c, 0x4e, 0xb8, 0x4a,
-            0xec, 0xf2, 0xf8, 0xc4, 0xde, 0x16, 0xf3, 0xdc, 0x42, 0x26, 0xc7, 0x8d, 0x46, 0x19, 0xc7, 0xc0,
-            0xe0, 0x1d, 0x9a, 0xe4, 0xa0, 0xbf, 0xea, 0x5b, 0x2d, 0x07, 0x87, 0x96, 0x33, 0xe3, 0xcf, 0xc4,
-            0xf8, 0x71, 0x38, 0x6c, 0x06, 0xfd, 0x3d, 0x6d, 0xfb, 0x83, 0x0a, 0xf9, 0xbb, 0xbe, 0x93, 0x8d,
-            0x0a, 0x30, 0xbf, 0x87, 0x5c, 0x31, 0xc3, 0x23, 0x44, 0x04, 0xfc, 0xb6, 0xb0, 0x06, 0x71, 0x7a,
-            0x65, 0x0a, 0x8d, 0xa8, 0x54, 0xae, 0xaa, 0xb4, 0x49, 0x29, 0x7a, 0x75, 0x55, 0x7d, 0x6b, 0xff,
-            0xb3, 0x5e, 0x3b, 0xcd, 0x0c, 0x52, 0xb1, 0xcf, 0x67, 0xb5, 0x58, 0xa4, 0xc3, 0x0e, 0x06, 0x98,
-            0xbc, 0xa0, 0x89, 0xe2, 0x32, 0x19, 0x68, 0x32, 0x54, 0xcc, 0x1a, 0x7d, 0xfb, 0x52, 0x4a, 0x3d,
-            0x71, 0x9d, 0x7c, 0xca, 0xfb, 0x8d, 0x93, 0x30, 0x89, 0x71, 0xfa, 0x62, 0x6f, 0x03, 0xbb, 0xfa,
-            0xb4, 0xf0, 0x13, 0xa4, 0x42, 0xe3, 0x8d, 0x2f, 0x2a, 0xb7, 0xdb, 0xdc, 0xde, 0xf8, 0x1d, 0x73,
-            0x2d, 0x48, 0xbc, 0xb5, 0x46, 0xd3, 0x41, 0xc5, 0x8a, 0x29, 0x49, 0x1a, 0xf7, 0x98, 0x3f, 0x69,
-            0x80, 0x7c, 0x74, 0x19, 0x17, 0x13, 0xd6, 0x4d, 0x8d, 0x04, 0xf9, 0x21, 0x31, 0xe8, 0x16, 0x28,
-            0xce, 0xc7, 0x26, 0x34, 0x25, 0x7c, 0x84, 0x42, 0x1f, 0x1a, 0xd6, 0xa5, 0x0c, 0x45, 0xc1, 0x8e,
-            0x6d, 0x0b, 0xc1, 0x34, 0xaf, 0x1a, 0xbe, 0x81, 0xc1, 0x60, 0x93, 0xa2, 0xf1, 0x28, 0x34, 0x26,
-            0xb4, 0x5b, 0x0b, 0xc4, 0x30, 0x2f, 0xcc, 0x8b, 0x4f, 0x8d, 0x08, 0xcc, 0xc8, 0xbc, 0x00, 0xc0,
-            0xe7, 0xc8, 0x6b, 0x34, 0xeb, 0x38, 0x38, 0x74, 0x2e, 0x20, 0x2a, 0x44, 0x3d, 0x75, 0x31, 0xfd,
-            0x42, 0xaa, 0x99, 0xd1, 0xa8, 0x92, 0x6a, 0x27, 0x14, 0x3f, 0x1f, 0x9f, 0x0c, 0xab, 0x9d, 0x93,
-            0x11, 0xb4, 0x49, 0xd0, 0x65, 0xe2, 0x64, 0xc3, 0xd4, 0xfd, 0xbc, 0x34, 0xf8, 0xc5, 0xcc, 0xb8,
-            0x57, 0xb0, 0x5b, 0x3e, 0xec, 0xda, 0x07, 0x9a, 0x1f, 0xe8, 0xa2, 0x09, 0x22, 0x99, 0x1f, 0x90,
-            0x49, 0xf2, 0x00, 0xfa, 0x83, 0x90, 0xd9, 0x79, 0x6b, 0x86, 0xc8, 0x10, 0x6c, 0x6d, 0xd6, 0xae,
-            0x80, 0x40, 0xa0, 0x4a, 0xc8, 0x52, 0x2b, 0x6f, 0x13, 0xf2, 0x0f, 0x15, 0x45, 0xb2, 0xf2, 0xcc,
-            0x10, 0x85, 0x25, 0xd0, 0x93, 0xa5, 0x68, 0xea, 0x24, 0xc3, 0x14, 0x4d, 0x51, 0x84, 0x2d, 0x42,
-            0x4f, 0x8f, 0xc5, 0xa4, 0xb0, 0x89, 0x51, 0x8f, 0xb3, 0xb1, 0x72, 0x9e, 0x1b, 0x86, 0x83, 0x03,
-            0x86, 0xc5, 0xd8, 0x72, 0x86, 0x00, 0xe7, 0x36, 0x81, 0x90, 0x3d, 0x8b, 0xee, 0xaf, 0x64, 0xc5,
-            0x67, 0x79, 0xc0, 0x69, 0x6d, 0x64, 0x99, 0x99, 0x6d, 0x78, 0xcc, 0x0d, 0x6b, 0x7a, 0x58, 0x6c,
-            0xd6, 0x9d, 0xd9, 0x8c, 0x0b, 0x24, 0x95, 0x0d, 0x9a, 0xc3, 0xb8, 0xca, 0x3a, 0x55, 0xdf, 0xd2,
-            0x4a, 0x97, 0xb2, 0x9a, 0x39, 0xce, 0x59, 0xe2, 0xb9, 0x93, 0x72, 0x70, 0x58, 0x1c, 0x1c, 0x15,
-            0xb3, 0xe2, 0xaa, 0xe0, 0x5a, 0xd3, 0xe0, 0xa7, 0xba, 0xc0, 0xae, 0x46, 0x23, 0xa9, 0x62, 0xd8,
-            0xf7, 0x8e, 0x46, 0x19, 0x0f, 0x46, 0xa3, 0x3a, 0x3b, 0xa6, 0x86, 0x5b, 0xaa, 0x53, 0xa5, 0xa8,
-            0xb3, 0x6a, 0xb8, 0xe4, 0x5e, 0xdb, 0x18, 0x12, 0x4e, 0xb8, 0x65, 0x9c, 0xbc, 0x7f, 0xb8, 0xbb,
-            0xb5, 0x8f, 0xbb, 0xde, 0xf7, 0xcb, 0xc4, 0x8c, 0xf0, 0xda, 0x7b, 0xa9, 0xab, 0x41, 0x9e, 0x66,
-            0x3b, 0x1e, 0x11, 0x7e, 0x6b, 0xdb, 0x71, 0x44, 0x6f, 0x2c, 0xd6, 0xec, 0xeb, 0x64, 0xa8, 0xe5,
-            0x47, 0xce, 0xb1, 0x63, 0x35, 0x8b, 0xe7, 0xdf, 0x45, 0x8e, 0x6f, 0x22, 0x46, 0x9d, 0x1e, 0x5b,
-            0x8d, 0x6a, 0x2b, 0x56, 0xaf, 0x9d, 0x28, 0xde, 0xf4, 0x9c, 0xed, 0x50, 0xcd, 0x56, 0x1b, 0xb3,
-            0xa9, 0xf6, 0x2c, 0xa5, 0x94, 0x52, 0x66, 0x5d, 0xee, 0xcf, 0x6c, 0xd9, 0x9f, 0xd1, 0x08, 0x34,
-            0xb5, 0x55, 0xef, 0xed, 0x0f, 0xa6, 0xb3, 0xfb, 0xf3, 0x39, 0x20, 0xd6, 0xc8, 0xa7, 0x5d, 0x10,
-            0x8b, 0x76, 0xda, 0x2b, 0x2e, 0xf6, 0xb9, 0x8a, 0x4a, 0xe5, 0x51, 0x44, 0x97, 0xe1, 0x5a, 0x88,
-            0x32, 0xc2, 0xd6, 0x40, 0x34, 0x4d, 0xe3, 0x8a, 0xd1, 0xce, 0xa9, 0x62, 0xe5, 0xd5, 0x67, 0x76,
-            0x58, 0xde, 0xf8, 0x22, 0x7c, 0xee, 0x2f, 0x77, 0x03, 0xf0, 0x53, 0x93, 0xd5, 0x68, 0xad, 0xd8,
-            0xf2, 0xce, 0x16, 0x19, 0x42, 0xe6, 0x77, 0xbb, 0xe3, 0xe1, 0x3c, 0xdf, 0x0b, 0x31, 0x37, 0x6b,
-            0x29, 0x9f, 0x33, 0x47, 0xae, 0x21, 0x36, 0x9c, 0x7e, 0xad, 0xa7, 0xce, 0x31, 0xa4, 0x7f, 0x6c,
-            0x3b, 0x65, 0x47, 0x23, 0xcb, 0x5f, 0xfa, 0xd1, 0xa6, 0xdb, 0xf5, 0xaa, 0x96, 0x05, 0x59, 0x2f,
-            0xf1, 0x90, 0x07, 0x35, 0xb4, 0xce, 0x66, 0x56, 0xa1, 0xf4, 0x2a, 0x70, 0xd5, 0xc9, 0xcd, 0x3b,
-            0x59, 0x0a, 0x0b, 0x37, 0xbb, 0x49, 0x76, 0x72, 0x95, 0x80, 0x88, 0x88, 0x79, 0xc0, 0x9a, 0x93,
-            0xc5, 0x66, 0x41, 0x21, 0x86, 0x3c, 0x51, 0xb4, 0x77, 0xf2, 0xbd, 0x1f, 0x09, 0xd8, 0x00, 0x78,
-            0x13, 0x59, 0x4c, 0xce, 0xfb, 0x6d, 0x23, 0x5f, 0xe6, 0x17, 0x54, 0x9e, 0x1e, 0xd2, 0xa9, 0xd2,
-            0x3d, 0x69, 0xe4, 0xe4, 0xd9, 0x26, 0x85, 0xe1, 0xd8, 0xa5, 0xbc, 0xf9, 0x28, 0xf1, 0x29, 0xed,
-            0xed, 0x76, 0x03, 0x24, 0xa4, 0x2d, 0x5b, 0x79, 0x4f, 0xc7, 0xf8, 0x73, 0x78, 0x93, 0xd2, 0xbd,
-            0x79, 0xc9, 0x9d, 0x2e, 0x59, 0x27, 0x6c, 0xab, 0x56, 0x55, 0x96, 0x93, 0x17, 0x77, 0x3d, 0x4d,
-            0xc8, 0x87, 0xc7, 0xc6, 0xf3, 0xc0, 0x68, 0x34, 0x21, 0x7d, 0x65, 0xf6, 0x98, 0xa3, 0x91, 0x9d,
-            0x1a, 0xb6, 0xf3, 0x5a, 0x54, 0xe7, 0xd8, 0x13, 0xcf, 0xa4, 0xc7, 0x1c, 0x94, 0x2d, 0xa8, 0x94,
-            0xf1, 0x2e, 0x96, 0x2d, 0x54, 0x66, 0x66, 0x04, 0x00, 0x00, 0x00, 0x04, 0xb3, 0x40, 0x00, 0x18,
-            0x1e, 0x15, 0xca, 0x84, 0x72, 0xc1, 0x84, 0xb4, 0x8c, 0x1f, 0x44, 0x83, 0x0a, 0x89, 0x10, 0x09,
-            0x47, 0x8c, 0xa5, 0x53, 0x99, 0x14, 0xc9, 0x14, 0x63, 0xd2, 0x20, 0x32, 0x00, 0x23, 0x00, 0x00,
-            0x04, 0x00, 0x00, 0x00, 0xb0, 0x8b, 0x92, 0xc0, 0x5a, 0x5d, 0xec, 0x28, 0xa1, 0xa8, 0x15, 0xff,
-            0xde, 0xf5, 0x75, 0x2e, 0xa1, 0x00, 0xd2, 0xc7, 0x55, 0x62, 0x75, 0x3b, 0xfd, 0xda, 0xe6, 0x42,
-            0x90, 0xd0, 0x42, 0x1b, 0x8f, 0x10, 0x27, 0x04, 0x32, 0x81, 0x0b, 0x1b, 0x3c, 0xb9, 0x35, 0x7a,
-            0xe8, 0x94, 0x18, 0x4c, 0xb4, 0x58, 0x91, 0xa2, 0x38, 0x96, 0x8f, 0xa6, 0x95, 0x46, 0xa1, 0xcb,
-            0xe7, 0xda, 0xc5, 0x6a, 0x25, 0x6b, 0xb0, 0x38, 0xdb, 0x0f, 0xb1, 0x73, 0xbc, 0xdf, 0x9f, 0xac,
-            0xb4, 0x06, 0x44, 0x22, 0xed, 0x4c, 0x72, 0xee, 0x99, 0x53, 0xf1, 0xa8, 0x3a, 0xf1, 0x6a, 0xad,
-            0xaa, 0x0a, 0xdf, 0x66, 0xb8, 0x30, 0x55, 0xe1, 0x8a, 0xc0, 0xa8, 0x4c, 0x4e, 0xa7, 0xa5, 0xab,
-            0x2c, 0x57, 0x6d, 0x70, 0x57, 0x03, 0x39, 0xcb, 0xb9, 0xbf, 0x9e, 0x18, 0x6a, 0x88, 0x5e, 0x28,
-            0xd6, 0x4e, 0xa1, 0x5e, 0x0e, 0x5a, 0xbf, 0xdf, 0x87, 0x46, 0xee, 0xa4, 0xa2, 0x13, 0xb0, 0x31,
-            0xdd, 0x3d, 0x35, 0x8c, 0x9a, 0x58, 0x0e, 0xcf, 0x81, 0x84, 0x7e, 0x41, 0xd6, 0x44, 0x4b, 0xc5,
-            0x85, 0x7c, 0xd6, 0x04, 0x17, 0x11, 0x21, 0x61, 0x2a, 0x56, 0xda, 0x51, 0xbe, 0x86, 0xc3, 0x11,
-            0x1f, 0x05, 0x21, 0xd5, 0x93, 0x59, 0xf7, 0xe9, 0x0e, 0x9d, 0x6d, 0xd2, 0x39, 0xcf, 0x68, 0xb1,
-            0xd8, 0x41, 0x94, 0x19, 0x9e, 0x5a, 0x50, 0x1e, 0x2a, 0x27, 0xdc, 0xaa, 0x18, 0x62, 0x21, 0xc7,
-            0x94, 0x04, 0xe7, 0x20, 0xb8, 0x09, 0xdd, 0xa3, 0xbc, 0xdf, 0xc6, 0xa5, 0xe6, 0x5c, 0xba, 0x89,
-            0x5c, 0x81, 0x73, 0x7b, 0xa1, 0x89, 0x51, 0x92, 0x89, 0x9e, 0x6e, 0xb4, 0x80, 0x2e, 0xba, 0xaa,
-            0x46, 0x3e, 0x3a, 0x9f, 0xee, 0x40, 0x92, 0x82, 0xaa, 0x50, 0xa0, 0x56, 0x66, 0xea, 0xb8, 0x42,
-            0xce, 0xfb, 0x83, 0x2f, 0xa7, 0x0c, 0x94, 0xd1, 0x89, 0x64, 0x1a, 0x7c, 0xae, 0x56, 0xd6, 0x9a,
-            0xf3, 0xe7, 0xab, 0x9a, 0xa7, 0x6f, 0x01, 0x36, 0x6e, 0xb6, 0x9b, 0x6e, 0x76, 0xac, 0xa4, 0x8c,
-            0xca, 0x5a, 0x5d, 0x44, 0x69, 0xc6, 0x70, 0x01, 0x08, 0x14, 0x9e, 0xce, 0xd1, 0x22, 0xd8, 0x9d,
-            0xbf, 0x4b, 0xa6, 0x35, 0x66, 0xdf, 0x31, 0xfc, 0xb2, 0x7c, 0x00, 0x4b, 0x4b, 0xfd, 0xa4, 0x98,
-            0x86, 0x9d, 0xe1, 0xc3, 0xbd, 0xaf, 0x7e, 0x1a, 0xe0, 0x84, 0xe0, 0x8e, 0x6f, 0x36, 0x06, 0x9e,
-            0x01, 0x54, 0x4e, 0x86, 0xe4, 0xf0, 0x21, 0xa9, 0x31, 0xa3, 0x4d, 0x2d, 0xab, 0x24, 0x7f, 0x46,
-            0x04, 0xa0, 0xf0, 0x4f, 0x67, 0x5c, 0xcb, 0x47, 0xc0, 0x7a, 0x27, 0xed, 0xd8, 0x7b, 0x65, 0xd6,
-            0x4b, 0x60, 0x29, 0x10, 0xe3, 0xc1, 0xa2, 0x81, 0x13, 0xbb, 0xe2, 0x77, 0x80, 0x07, 0x45, 0x29,
-            0x18, 0x8a, 0xaf, 0x0e, 0xfc, 0xde, 0xa8, 0x26, 0x44, 0x68, 0x39, 0x7f, 0x5c, 0x35, 0x5d, 0x1a,
-            0x23, 0x31, 0x24, 0xc2, 0xda, 0x3c, 0x0a, 0xa7, 0x6d, 0x4a, 0x51, 0x88, 0x1c, 0xdc, 0xbc, 0xad,
-            0x31, 0x9f, 0xb8, 0x83, 0x79, 0x3b, 0x0f, 0xaa, 0x8e, 0xe8, 0x56, 0xfa, 0x83, 0x7a, 0x88, 0xbb,
-            0x24, 0x25, 0xce, 0xdc, 0x13, 0xf9, 0x80, 0x26, 0x6e, 0x15, 0xc3, 0xb9, 0x93, 0x6d, 0xed, 0x60,
-            0xbe, 0xcf, 0x84, 0x34, 0x9b, 0x48, 0xeb, 0x25, 0xec, 0xcc, 0x42, 0xe8, 0x1d, 0xf0, 0x43, 0x9f,
-            0xa0, 0xe7, 0x64, 0x09, 0x30, 0x75, 0x47, 0x5c, 0x7c, 0x72, 0xd6, 0x0f, 0x3e, 0xf1, 0x5b, 0x31,
-            0x64, 0x8b, 0xcd, 0xa9, 0xc9, 0x2d, 0xa4, 0xf0, 0x0f, 0x76, 0x50, 0x17, 0x40, 0x8d, 0x04, 0xa2,
-            0xa2, 0x85, 0x52, 0x4f, 0x04, 0xe0, 0x64, 0xa0, 0x0b, 0x28, 0x63, 0x1e, 0xf1, 0x90, 0xae, 0x64,
-            0xa0, 0xf6, 0xd5, 0x12, 0xac, 0x29, 0x33, 0xc8, 0xaa, 0xf3, 0xde, 0x02, 0x27, 0x85, 0x8d, 0x79,
-            0x2e, 0x2e, 0xfe, 0x18, 0x22, 0x25, 0x24, 0xb4, 0xa0, 0x1c, 0xb2, 0x8e, 0x1d, 0x15, 0xdf, 0x04,
-            0x5d, 0x08, 0xef, 0x90, 0x62, 0xc5, 0x61, 0xa1, 0xf9, 0x76, 0xc9, 0xe8, 0xc7, 0x01, 0x95, 0x10,
-            0x7c, 0xe0, 0x64, 0x19, 0x60, 0xa6, 0x29, 0x2a, 0x6f, 0x9e, 0xbc, 0xc4, 0xdb, 0x1a, 0x86, 0xa5,
-            0x89, 0xb4, 0x89, 0xc8, 0xe0, 0xc2, 0x57, 0x5c, 0x8a, 0x8b, 0x32, 0x88, 0x89, 0x4d, 0xe9, 0x19,
-            0x5c, 0xd7, 0xee, 0xfd, 0xdf, 0x21, 0x18, 0x87, 0xc0, 0x20, 0x65, 0xd2, 0xd5, 0xf0, 0x42, 0xb1,
-            0x73, 0xd7, 0x21, 0xb3, 0xd0, 0x44, 0x81, 0x28, 0x66, 0x36, 0x09, 0xeb, 0x0d, 0xcd, 0xea, 0x1b,
-            0x60, 0x4e, 0x00, 0x2e, 0x2b, 0x4e, 0xa4, 0x77, 0x54, 0xf6, 0xeb, 0x80, 0x91, 0x97, 0x85, 0x28,
-            0x7e, 0xb3, 0x4d, 0x7e, 0x88, 0x8b, 0xb3, 0x1e, 0xbc, 0x04, 0x1b, 0x31, 0x36, 0xe0, 0x98, 0x66,
-            0xa2, 0x79, 0xcb, 0x66, 0x55, 0x49, 0x39, 0xb7, 0x2b, 0xe4, 0x62, 0xc8, 0x6d, 0x8d, 0x38, 0x30,
-            0xc7, 0xf7, 0xc0, 0x0f, 0xbd, 0x34, 0x64, 0x65, 0x5d, 0xeb, 0xe2, 0x4f, 0xdc, 0xe0, 0x3d, 0x61,
-            0xf4, 0xf0, 0x43, 0xe8, 0x0a, 0x39, 0x1b, 0xd3, 0xe1, 0xee, 0x01, 0xda, 0x2c, 0x18, 0x50, 0xaa,
-            0xa9, 0xd7, 0x92, 0x88, 0x82, 0xf4, 0x5b, 0x91, 0x35, 0x47, 0x00, 0xd1, 0xe9, 0x32, 0x38, 0x44,
-            0xac, 0x6e, 0x78, 0xa5, 0xaa, 0xda, 0x82, 0x4d, 0x74, 0x93, 0x0b, 0x1e, 0x61, 0x70, 0x2b, 0x36,
-            0xd7, 0x28, 0xf0, 0x05, 0x71, 0x77, 0x1e, 0x9a, 0x01, 0x4e, 0x4b, 0x6a, 0x3a, 0x9d, 0x80, 0x84,
-            0xde, 0x82, 0xc1, 0x17, 0xa3, 0x46, 0x0f, 0xcc, 0x54, 0x5d, 0x52, 0x65, 0x08, 0xfb, 0x5b, 0x5f,
-            0xb7, 0x4a, 0x87, 0x46, 0x0e, 0x6a, 0xd2, 0xfd, 0x95, 0x25, 0xce, 0x8c, 0xc2, 0x90, 0xbe, 0x14,
-            0x55, 0xe5, 0xea, 0xe5, 0x8b, 0x98, 0x37, 0x19, 0xb8, 0xe2, 0xeb, 0x46, 0x4b, 0x31, 0x86, 0x1e,
-            0x0f, 0x82, 0x87, 0x8e, 0x4b, 0x7f, 0x1e, 0x64, 0x5b, 0xef, 0xa0, 0xe0, 0x09, 0xc0, 0x0e, 0x22,
-            0x9a, 0x04, 0xf2, 0x5b, 0x12, 0x4f, 0xde, 0xc4, 0xc9, 0x27, 0x82, 0xb2, 0x27, 0x6d, 0x78, 0x5e,
-            0x7e, 0x46, 0x82, 0xf6, 0xdf, 0x39, 0x69, 0x90, 0x42, 0xea, 0x4f, 0x3c, 0x1b, 0x7d, 0x83, 0xe6,
-            0xfe, 0x4b, 0x56, 0x8a, 0x56, 0x4b, 0xfa, 0x3a, 0x0e, 0xca, 0x85, 0xee, 0x00, 0x5e, 0x45, 0x25,
-            0x44, 0x65, 0xd5, 0xc3, 0xd4, 0xde, 0x3c, 0x98, 0xe5, 0xdc, 0x34, 0x80, 0x15, 0x35, 0xde, 0x91,
-            0x59, 0x34, 0x98, 0x93, 0x62, 0xfb, 0xdb, 0x9e, 0xed, 0xee, 0xc3, 0x38, 0x7f, 0x41, 0x26, 0x35,
-            0xfb, 0x3b, 0x4c, 0xf0, 0xcb, 0xc0, 0x67, 0x6b, 0x4a, 0xba, 0xc9, 0xd0, 0xb5, 0xf2, 0xa8, 0x07,
-            0x3d, 0xf8, 0x76, 0x8d, 0x47, 0x5e, 0x62, 0xff, 0xe8, 0x3a, 0x4c, 0x5f, 0x9e, 0x6f, 0x65, 0x51,
-            0x17, 0xa2, 0x2b, 0xc1, 0x3f, 0x84, 0x7c, 0xd4, 0x8e, 0xda, 0x4b, 0x37, 0xea, 0xb9, 0xd2, 0x25,
-            0xc4, 0xa5, 0xb0, 0xa4, 0x65, 0x94, 0xca, 0x6f, 0x85, 0x56, 0x0a, 0x25, 0xa6, 0xfa, 0x10, 0xd1,
-            0x11, 0x0e, 0xf3, 0x23, 0x52, 0x61, 0xf0, 0x84, 0x15, 0x5e, 0x6b, 0xdc, 0x05, 0x4f, 0x0b, 0x14,
-            0xce, 0x72, 0x89, 0x01, 0xff, 0x7b, 0x32, 0xa3, 0xae, 0x4c, 0x47, 0xf3, 0x33, 0xf7, 0xf1, 0x53,
-            0x2e, 0x17, 0x38, 0x3a, 0x94, 0x63, 0xf8, 0x15, 0xef, 0x86, 0x8b, 0xe6, 0xbd, 0x68, 0x5d, 0x68,
-            0x7f, 0xc8, 0x0c, 0x23, 0x74, 0x5b, 0x84, 0x27, 0x83, 0x8c, 0x26, 0x17, 0xb0, 0x3d, 0x9c, 0x48,
-            0xb5, 0xa6, 0xf2, 0x9d, 0x38, 0xf7, 0xa8, 0xd3, 0x41, 0x01, 0x3f, 0x33, 0xdc, 0x08, 0x1e, 0x7b,
-            0x3a, 0xae, 0xdf, 0xa7, 0x2e, 0x0a, 0xa8, 0x47, 0x30, 0xac, 0x3c, 0xe7, 0xe8, 0x05, 0x9a, 0x34,
-            0xcb, 0xdc, 0x67, 0xb2, 0x7d, 0x2b, 0xdc, 0x5e, 0x70, 0x64, 0x57, 0xa0, 0x1d, 0x04, 0x73, 0xa1,
-            0x52, 0x2a, 0xe1, 0xee, 0x82, 0xdf, 0xe8, 0xdc, 0x83, 0x4c, 0xc0, 0xc2, 0xc2, 0x5d, 0xa3, 0x59,
-            0x89, 0x3d, 0xea, 0x52, 0x89, 0xe2, 0x4d, 0x2f, 0x7f, 0xf6, 0x9d, 0x3b, 0xfa, 0x44, 0x71, 0xaf,
-            0x5b, 0x6e, 0x03, 0xb9, 0x84, 0x30, 0x55, 0xec, 0x3e, 0x4f, 0x58, 0x73, 0xdb, 0x78, 0xfe, 0x73,
-            0x32, 0x1c, 0x3b, 0xa7, 0x43, 0x8d, 0xce, 0xe3, 0xf5, 0x99, 0xeb, 0xe7, 0x8a, 0x23, 0x87, 0xd8,
-            0x39, 0x53, 0x18, 0xf1, 0x1c, 0xdb, 0x48, 0x27, 0xd0, 0xef, 0x05, 0x63, 0xb4, 0x58, 0x1a, 0x41,
-            0xd4, 0x49, 0xfc, 0xed, 0xd9, 0x0b, 0x42, 0x2d, 0xfa, 0x6e, 0xcd, 0xa9, 0x41, 0x8e, 0x2e, 0xe5,
-            0x50, 0x13, 0x10, 0x60, 0xf9, 0x40, 0xcf, 0xe2, 0xab, 0x55, 0x1d, 0x47, 0x31, 0x32, 0x1b, 0xce,
-            0x70, 0x40, 0xfd, 0x21, 0x76, 0x7c, 0x3c, 0x73, 0xa6, 0xcf, 0xfa, 0xd0, 0x83, 0x0e, 0x27, 0x3a,
-            0xc9, 0x18, 0x09, 0xab, 0x9b, 0xa8, 0xc2, 0x65, 0xcf, 0x53, 0xe2, 0x95, 0x03, 0x87, 0x3d, 0xcb,
-            0xc6, 0x8d, 0x7a, 0x34, 0xef, 0x3b, 0x60, 0x4b, 0x41, 0x0b, 0xd5, 0x9b, 0x70, 0xad, 0x82, 0x1c,
-            0x22, 0x67, 0xf2, 0x5b, 0x4a, 0x4f, 0x31, 0x73, 0xd9, 0x38, 0xf9, 0x41, 0x08, 0xcb, 0x44, 0xfd,
-            0x2a, 0xe0, 0x4e, 0x82, 0xe6, 0x49, 0x41, 0x39, 0xd5, 0x79, 0xd9, 0x8d, 0x89, 0x73, 0xa5, 0x31,
-            0x06, 0xed, 0x91, 0xd9, 0xa2, 0xe2, 0xe4, 0xff, 0x77, 0x1a, 0xd8, 0xd0, 0x92, 0xd3, 0x9b, 0x6e,
-            0x3e, 0x8e, 0x01, 0x89, 0x9c, 0xa7, 0x96, 0x74, 0x94, 0x1e, 0x6c, 0x5b, 0x49, 0xa5, 0x77, 0xd2,
-            0x8a, 0xd4, 0xf6, 0x69, 0x9f, 0xf2, 0xbc, 0x2e, 0xe8, 0x7a, 0x69, 0xe1, 0x18, 0xf7, 0x83, 0xe9,
-            0x45, 0x1e, 0x87, 0x57, 0xb1, 0xd8, 0x86, 0xd3, 0x30, 0xde, 0xbe, 0x99, 0x4f, 0xd6, 0xf1, 0x4a,
-            0xe3, 0xe0, 0x55, 0x06, 0x9f, 0xce, 0x0a, 0x51, 0x3e, 0x20, 0x22, 0x5a, 0xed, 0x0b, 0xc3, 0xc8,
-            0x76, 0x39, 0xa8, 0x39, 0x7c, 0xd3, 0x32, 0xd6, 0x8c, 0x9b, 0x1f, 0x01, 0x3d, 0x51, 0x02, 0x01,
-            0x33, 0xa9, 0x12, 0xbb, 0x90, 0x9b, 0xb5, 0xbf, 0xad, 0xeb, 0x15, 0xbe, 0xf1, 0xb8, 0x8d, 0xac,
-            0x56, 0xac, 0xb9, 0x3d, 0x3a, 0x55, 0x27, 0x99, 0xbb, 0xbb, 0x2c, 0xa0, 0xfd, 0xfc, 0x61, 0x0c,
-            0x49, 0x1c, 0x69, 0x64, 0xaa, 0xbc, 0xbd, 0x6d, 0x75, 0xe7, 0x5e, 0x44, 0x94, 0xa8, 0xa8, 0x53,
-            0x20, 0xb3, 0x29, 0x2e, 0x4a, 0x14, 0x1e, 0x5c, 0xc1, 0x3e, 0x07, 0x3c, 0x3f, 0x3b, 0x68, 0x10,
-            0xd0, 0x47, 0x32, 0x57, 0x06, 0x97, 0x0a, 0x2a, 0x2a, 0x0d, 0x85, 0x02, 0x5f, 0x3e, 0xda, 0xac,
-            0x20, 0xa1, 0xb8, 0xa9, 0x23, 0x46, 0xbe, 0x1c, 0xa9, 0xe0, 0x23, 0xa6, 0xcb, 0x07, 0x89, 0x20,
-            0xe0, 0x17, 0x8b, 0xde, 0x96, 0xbc, 0xfb, 0x07, 0x66, 0xf2, 0x6a, 0x8a, 0x40, 0x7c, 0xa4, 0x76,
-            0x87, 0xdc, 0xce, 0xe5, 0x57, 0xf7, 0xf4, 0xd0, 0x67, 0x09, 0xbc, 0x67, 0x27, 0x89, 0x38, 0x69,
-            0xc0, 0x83, 0x43, 0x9f, 0xf5, 0x27, 0x06, 0x42, 0x12, 0xb1, 0x64, 0xd4, 0xfa, 0x9d, 0x72, 0xa4,
-            0x69, 0xcb, 0x60, 0x70, 0xf0, 0x91, 0x85, 0x61, 0x79, 0x85, 0x77, 0xd2, 0x8d, 0x25, 0x5d, 0x43,
-            0x36, 0x36, 0x21, 0x74, 0x0f, 0x2f, 0xd3, 0x7d, 0x86, 0x75, 0x69, 0xf6, 0x11, 0x43, 0x59, 0xee,
-            0x97, 0x80, 0xa6, 0xd9, 0xf5, 0x47, 0x2d, 0x4f, 0x45, 0xb1, 0x21, 0x29, 0x4b, 0x2d, 0x11, 0x1d,
-            0xea, 0x43, 0xd8, 0x3c, 0x3b, 0x2b, 0xbf, 0x11, 0x75, 0x9c, 0xdb, 0x0a, 0xa6, 0xf1, 0x81, 0x44,
-            0x34, 0x81, 0x1f, 0x3d, 0x6e, 0x64, 0x22, 0x32, 0xb8, 0xcd, 0x93, 0x59, 0x95, 0xb9, 0x16, 0x4c,
-            0xf5, 0x69, 0x77, 0x22, 0xea, 0xe8, 0x5f, 0x27, 0xc1, 0x36, 0xcb, 0x06, 0x09, 0x6b, 0x53, 0x08,
-            0x68, 0xdd, 0xcb, 0x67, 0xc4, 0xd7, 0xff, 0xa8, 0x0f, 0x6d, 0x9c, 0x71, 0xd3, 0xe5, 0x84, 0x78,
-            0x18, 0xb4, 0xff, 0x11, 0x3a, 0xb5, 0x5f, 0xf4, 0xbd, 0x04, 0xc5, 0x8d, 0x67, 0xc2, 0xad, 0x10,
-            0x6c, 0x53, 0x44, 0x1e, 0xd3, 0xf9, 0xaf, 0xcc, 0xc6, 0xf7, 0xaa, 0x6d, 0x34, 0x1e, 0x49, 0x14,
-            0xbd, 0xa0, 0xa7, 0xd2, 0xe5, 0x2f, 0x7d, 0xbe, 0xec, 0x29, 0x89, 0xf8, 0xe4, 0x45, 0x74, 0x06,
-            0x1d, 0xce, 0xd9, 0x9e, 0x12, 0xaf, 0xf9, 0x30, 0x3f, 0xb7, 0x9c, 0x31, 0x3e, 0x7a, 0xff, 0x8c,
-            0xcd, 0xee, 0x6b, 0x28, 0x8a, 0xe4, 0xb0, 0xac, 0xe4, 0xf6, 0xc7, 0x36, 0x14, 0x63, 0x8d, 0x49,
-            0xc9, 0x62, 0xcd, 0x63, 0x9a, 0xd9, 0xc0, 0x7b, 0x4a, 0x3e, 0xe7, 0x61, 0xe5, 0xba, 0xf4, 0x9f,
-            0xc6, 0x68, 0x8e, 0x55, 0x85, 0x9a, 0xa0, 0xd8, 0xdb, 0x88, 0x4c, 0x9c, 0xa8, 0x81, 0x02, 0x9e,
-            0x01, 0x48, 0x00, 0xa8, 0x74, 0x7a, 0x56, 0x01, 0x07, 0xfc, 0xcf, 0x53, 0xa4, 0xfc, 0xb3, 0xd4,
-            0xd5, 0xf2, 0x9b, 0xb7, 0x54, 0x94, 0x86, 0x45, 0x38, 0x68, 0x81, 0xda, 0x9c, 0x1c, 0x0c, 0x76,
-            0x60, 0x0b, 0x74, 0x33, 0xde, 0x6c, 0x6d, 0xe8, 0x0e, 0xc5, 0x16, 0xe0, 0xc6, 0x3f, 0xf1, 0x21,
-            0x3b, 0x23, 0x7d, 0x1c, 0xe0, 0x61, 0x2e, 0xe5, 0x9f, 0x70, 0x08, 0xde, 0x97, 0x76, 0x44, 0xea,
-            0x75, 0x56, 0x97, 0x6d, 0x73, 0xe0, 0xe4, 0x19, 0xb4, 0x35, 0x85, 0x7e, 0x2d, 0x94, 0xa9, 0xbb,
-            0x5a, 0xc2, 0xca, 0x3e, 0xaf, 0x17, 0x66, 0xc4, 0xa7, 0x76, 0x9a, 0x7c, 0x17, 0x62, 0x12, 0x91,
-            0x15, 0x5a, 0xc6, 0xc9, 0x53, 0x7b, 0x3c, 0xf9, 0xdd, 0x3c, 0xe7, 0x56, 0xa5, 0xe5, 0xe9, 0xd7,
-            0x9a, 0x06, 0x67, 0x36, 0xd0, 0x02, 0x26, 0x6d, 0xfb, 0x5a, 0x30, 0x40, 0x32, 0xaa, 0xe6, 0xb5,
-            0x0a, 0x3e, 0x42, 0x41, 0xe3, 0x49, 0x89, 0xf0, 0x74, 0x59, 0x4e, 0x09, 0xae, 0xd6, 0xda, 0x99,
-            0x4d, 0x2f, 0xf5, 0x42, 0xee, 0x26, 0x42, 0xe8, 0xf6, 0x29, 0x32, 0x78, 0xf8, 0x68, 0x9b, 0xb4,
-            0x49, 0x53, 0x17, 0x3c, 0xa3, 0xf9, 0xdc, 0x5e, 0x2c, 0x51, 0x88, 0x9b, 0xec, 0xa5, 0xb7, 0xbe,
-            0xe0, 0xd4, 0x7a, 0xa2, 0x20, 0x21, 0x9f, 0x69, 0x04, 0xda, 0xba, 0x27, 0x28, 0xf2, 0x1d, 0x50,
-            0x54, 0xd5, 0x68, 0x4d, 0xb0, 0xd5, 0x66, 0x89, 0x0d, 0x09, 0x52, 0xfe, 0x4a, 0xa7, 0xc1, 0x96,
-            0x8d, 0x0d, 0x73, 0x72, 0xc7, 0x4a, 0xaa, 0x9a, 0x83, 0xa2, 0x93, 0x22, 0xf6, 0x9c, 0x11, 0xb7,
-            0x03, 0xcc, 0xc5, 0x10, 0x49, 0x25, 0xf0, 0xee, 0x1a, 0x2b, 0xf9, 0xe7, 0xaf, 0x88, 0x0f, 0x3c,
-            0x9b, 0x33, 0x68, 0x16, 0xc1, 0x11, 0xd6, 0x56, 0x04, 0x1a, 0xa9, 0x88, 0x8d, 0x54, 0xe5, 0xf0,
-            0xf9, 0x29, 0x75, 0xfb, 0x3c, 0x31, 0x58, 0x64, 0x52, 0x40, 0xe1, 0x04, 0x23, 0x7b, 0x55, 0x9b,
-            0x0b, 0xa1, 0xf7, 0x24, 0xbd, 0x61, 0x7e, 0x8c, 0x36, 0x58, 0x27, 0xf1, 0xf8, 0x4c, 0xc4, 0x17,
-            0xa9, 0xbb, 0xa9, 0x5c, 0xb2, 0xb7, 0x87, 0xc0, 0x3c, 0x81, 0x6a, 0x9b, 0xd8, 0x26, 0xd9, 0x1d,
-            0x3b, 0xed, 0x31, 0xb6, 0x40, 0x4e, 0x9c, 0x3b, 0xf9, 0x9b, 0x3b, 0x60, 0xa5, 0x86, 0x0b, 0xd9,
-            0xf4, 0x0b, 0x00, 0x93, 0x85, 0x78, 0x02, 0x29, 0x38, 0x4a, 0x32, 0xa7, 0x1d, 0x85, 0xc9, 0xa9,
-            0x46, 0x06, 0x6d, 0xbb, 0x74, 0x14, 0xe5, 0x34, 0xea, 0x6e, 0xfb, 0xda, 0x97, 0x93, 0xc3, 0xb3,
-            0x22, 0x9c, 0x31, 0x58, 0x3b, 0x6f, 0xfc, 0x31, 0xfc, 0x57, 0xce, 0x3d, 0x4e, 0x45, 0xa5, 0x45,
-            0x31, 0x52, 0x52, 0xae, 0xb3, 0x26, 0x20, 0x73, 0x67, 0xa7, 0x87, 0x82, 0x48, 0x18, 0x4c, 0x4d,
-            0x5f, 0xf3, 0x62, 0x0b, 0x63, 0x6e, 0x7b, 0x12, 0xa0, 0x2c, 0x01, 0x0d, 0xa7, 0x07, 0xb9, 0x66,
-            0xaa, 0x4c, 0x64, 0x84, 0xb0, 0xfb, 0x1d, 0x51, 0x56, 0xa4, 0xb3, 0x98, 0xb1, 0xea, 0x69, 0x2d,
-            0xc3, 0x5a, 0x52, 0x88, 0xaf, 0x5d, 0x50, 0x2d, 0xfd, 0xc9, 0x26, 0xd9, 0x56, 0xa6, 0xe3, 0x17,
-            0xc3, 0x20, 0xc7, 0xb7, 0x7e, 0x6f, 0x54, 0xfc, 0x2e, 0x35, 0xc0, 0xf7, 0x67, 0x16, 0xda, 0xa6,
-            0x09, 0x35, 0x06, 0x93, 0x7c, 0x6c, 0xbb, 0x51, 0x09, 0xfb, 0x54, 0xf3, 0x78, 0x91, 0x2e, 0x18,
-            0xae, 0x88, 0x80, 0xde, 0x86, 0xa6, 0xc4, 0x9a, 0xc8, 0x8b, 0xc3, 0x67, 0xca, 0xc9, 0x23, 0x95,
-            0x0f, 0xe6, 0x3b, 0xf9, 0x22, 0xc1, 0xa8, 0x50, 0x1e, 0x47, 0x83, 0x82, 0x5d, 0xda, 0x5f, 0xaf,
-            0x59, 0xff, 0x4d, 0x6f, 0xc3, 0x6f, 0x1a, 0x14, 0x0d, 0x5e, 0x76, 0x33, 0x58, 0x26, 0xe3, 0x60,
-            0x76, 0x05, 0xe6, 0x48, 0x29, 0xa3, 0x6c, 0xf3, 0xfc, 0x4e, 0xaf, 0x6b, 0x57, 0xcf, 0xd6, 0xe1,
-            0xec, 0x7f, 0x19, 0x33, 0x54, 0x58, 0xe7, 0xa8, 0x3c, 0xb0, 0xf2, 0x7e, 0x4a, 0xd2, 0xd3, 0x3a,
-            0xde, 0x36, 0x77, 0x7c, 0xd1, 0xda, 0x92, 0xe4, 0xd0, 0x31, 0xcb, 0x58, 0xd5, 0x82, 0xf6, 0xa4,
-            0x5b, 0xf8, 0x89, 0xf9, 0x1d, 0x2d, 0x3d, 0xaf, 0x87, 0x1e, 0xbf, 0xc8, 0x8e, 0xa2, 0x39, 0x70,
-            0xf7, 0xa4, 0x53, 0xb3, 0xd2, 0xf3, 0xf2, 0xbb, 0x6a, 0x41, 0x60, 0x37, 0x39, 0xd3, 0xfc, 0x0c,
-            0x5b, 0x07, 0xea, 0xc2, 0x7d, 0xdc, 0x8b, 0xed, 0x5d, 0x8a, 0x10, 0xb0, 0x03, 0x06, 0x99, 0xaa,
-            0x76, 0xeb, 0x91, 0xb2, 0x72, 0x4a, 0x38, 0x27, 0x82, 0xa1, 0xdc, 0xa9, 0x77, 0x9c, 0x7b, 0x05,
-            0x77, 0xe9, 0x7a, 0x16, 0xab, 0xd2, 0xe8, 0x9e, 0x08, 0xcd, 0x26, 0xf3, 0x66, 0x03, 0x12, 0xb8,
-            0xe3, 0x05, 0x22, 0xbb, 0xa7, 0x1b, 0x6b, 0x1f, 0xd2, 0x81, 0x68, 0x90, 0xff, 0xee, 0xcd, 0xd6,
-            0x8e, 0xff, 0xb1, 0xa3, 0x12, 0x90, 0x51, 0xf6, 0xd8, 0xc0, 0xe6, 0x5e, 0x89, 0x10, 0x1d, 0xcb,
-            0xb5, 0x9a, 0x5d, 0xda, 0x72, 0x60, 0xc2, 0x6b, 0xaf, 0x32, 0xdc, 0x7f, 0xdf, 0xc2, 0xdb, 0x74,
-            0xfa, 0x90, 0x8e, 0xe0, 0x35, 0x6c, 0xc4, 0xf7, 0x9d, 0xec, 0xce, 0x9e, 0x03, 0x54, 0x6d, 0x25,
-            0x24, 0x02, 0x12, 0xd0, 0x3a, 0xa4, 0x78, 0x26, 0x2d, 0xf0, 0x70, 0x2d, 0x1d, 0x94, 0x55, 0x7a,
-            0x65, 0x95, 0x59, 0xf7, 0x27, 0x44, 0xe7, 0x11, 0x28, 0xa0, 0xd4, 0xc5, 0x61, 0x21, 0x52, 0xc9,
-            0x66, 0x4f, 0x44, 0xfc, 0xf1, 0x10, 0xd6, 0x21, 0xb7, 0x67, 0xf2, 0x01, 0xbb, 0x86, 0xdf, 0x1b,
-            0x57, 0x21, 0xfa, 0x26, 0x53, 0xa8, 0xc9, 0x39, 0x3c, 0xe2, 0xeb, 0xa2, 0x32, 0x8d, 0xcc, 0x0c,
-            0xd8, 0x4a, 0x9c, 0x2e, 0xa0, 0x74, 0xbb, 0x13, 0xc2, 0x59, 0x6d, 0xe9, 0xec, 0x6e, 0x36, 0x05,
-            0x9e, 0xf6, 0x5a, 0x5b, 0x95, 0x9f, 0x85, 0x7d, 0xb7, 0x99, 0x97, 0xbd, 0x10, 0x36, 0x71, 0xa4,
-            0xa9, 0x20, 0xf4, 0xc7, 0xc0, 0xb4, 0x10, 0xdc, 0xc3, 0x6d, 0x44, 0x82, 0x93, 0x69, 0x35, 0x74,
-            0x6a, 0x53, 0x3b, 0x68, 0xc5, 0x4a, 0xf6, 0x59, 0x12, 0x90, 0x86, 0xc8, 0x0e, 0xe0, 0x22, 0x46,
-            0xd7, 0x08, 0x97, 0x15, 0x24, 0x26, 0x7f, 0x12, 0x46, 0x96, 0x98, 0x9b, 0xc8, 0x43, 0xbd, 0x11,
-            0xb9, 0xc9, 0x8c, 0xab, 0xf6, 0x20, 0x86, 0x4d, 0xdd, 0xb7, 0x32, 0x10, 0x39, 0x00, 0x15, 0x52,
-            0x10, 0xf5, 0x0b, 0x50, 0xe3, 0x62, 0x36, 0x2c, 0xa5, 0x59, 0xda, 0x9b, 0xff, 0x17, 0xef, 0x7a,
-            0xfa, 0xaa, 0xa9, 0x93, 0xe4, 0xe1, 0xe2, 0x34, 0x76, 0x33, 0xdc, 0x79, 0xc8, 0x5a, 0x94, 0x1a,
-            0x11, 0xc7, 0x45, 0x45, 0x90, 0xee, 0xec, 0x9c, 0x73, 0x89, 0x5b, 0x56, 0x70, 0x63, 0x9c, 0xac,
-            0x2a, 0xb1, 0xa2, 0xa9, 0x64, 0x3e, 0xaa, 0xd5, 0x65, 0xc0, 0xeb, 0x1b, 0x54, 0xea, 0xd5, 0xed,
-            0x28, 0x86, 0xcc, 0x5d, 0x9f, 0xc1, 0x20, 0x35, 0x06, 0x41, 0xcb, 0x50, 0x21, 0x32, 0xfb, 0xd5,
-            0x74, 0x14, 0x9a, 0xbf, 0x78, 0x50, 0x75, 0x00, 0xae, 0x01, 0xa7, 0xe6, 0xc0, 0x90, 0xc1, 0x19,
-            0x93, 0x30, 0xe6, 0x71, 0xf9, 0x10, 0xde, 0x71, 0x8f, 0xc5, 0xa0, 0x5b, 0x29, 0x3a, 0xe1, 0x15,
-            0x70, 0x01, 0x9b, 0xbd, 0x4b, 0x76, 0x19, 0x5a, 0x1f, 0x6a, 0x45, 0xd2, 0x98, 0xd8, 0xd9, 0x0b,
-            0x78, 0x8e, 0x45, 0xf1, 0xde, 0x2a, 0x17, 0x10, 0x82, 0x68, 0x43, 0x1a, 0xd6, 0x09, 0xbd, 0x5d,
-            0xab, 0x56, 0x6d, 0x4b, 0x91, 0x3f, 0xf2, 0xf7, 0xa4, 0x9a, 0xad, 0xaf, 0x27, 0x0b, 0x8f, 0xc6,
-            0x34, 0xfb, 0x2c, 0x17, 0x6e, 0x0f, 0xe0, 0xe7, 0x48, 0xf9, 0x13, 0xa0, 0xbb, 0x5c, 0xe6, 0x7d,
-            0xde, 0x8e, 0x58, 0x71, 0xd4, 0xee, 0x4a, 0x96, 0xcf, 0x04, 0xbf, 0xee, 0x59, 0xe5, 0x3b, 0x44,
-            0xa9, 0x5d, 0x32, 0x18, 0xd5, 0xb7, 0xb4, 0xd0, 0xbb, 0x6a, 0xf6, 0xb7, 0x22, 0xc0, 0xc8, 0xc5,
-            0x99, 0x15, 0x63, 0xeb, 0x78, 0xbb, 0xe9, 0x21, 0x5c, 0x87, 0xd2, 0x3a, 0xa3, 0xbe, 0x84, 0x50,
-            0x99, 0xda, 0x10, 0x62, 0xe1, 0x31, 0x38, 0x64, 0xa8, 0x92, 0x87, 0xa5, 0x20, 0x5a, 0x19, 0x16,
-            0x79, 0x65, 0x39, 0x96, 0x11, 0x97, 0xff, 0x81, 0xd6, 0x79, 0x98, 0x5b, 0x06, 0xa9, 0x7d, 0xc0,
-            0x3d, 0xeb, 0x39, 0x41, 0x8a, 0x3c, 0x87, 0x72, 0x8f, 0xb5, 0x23, 0xd8, 0x74, 0x90, 0x39, 0xfc,
-            0x26, 0x6e, 0xb9, 0xed, 0xed, 0x04, 0x07, 0x4d, 0x9a, 0xdd, 0xda, 0xb8, 0xbd, 0xcd, 0x44, 0x14,
-            0xd2, 0x4d, 0x29, 0xf9, 0x6b, 0x63, 0x78, 0x94, 0x0e, 0xd0, 0x86, 0xd6, 0x3a, 0x0e, 0x5d, 0x16,
-            0x38, 0x17, 0xc5, 0x6d, 0x48, 0x32, 0x2a, 0xa7, 0xc1, 0x14, 0x93, 0x13, 0x55, 0xa7, 0x94, 0x49,
-            0x1b, 0x0a, 0xed, 0x27, 0xf1, 0xd8, 0x20, 0xca, 0x14, 0x46, 0x75, 0x7d, 0x2c, 0x63, 0xd7, 0xf8,
-            0x0c, 0x0e, 0x38, 0xd9, 0x9a, 0x39, 0x77, 0x63, 0xe7, 0xcd, 0x4d, 0x52, 0x95, 0x0f, 0xda, 0xc2,
-            0x7f, 0xf4, 0xc0, 0x1d, 0xec, 0xbe, 0x49, 0x70, 0x04, 0x2e, 0x3c, 0xe8, 0x22, 0x33, 0x36, 0x05,
-            0x47, 0x78, 0x72, 0x0a, 0x4c, 0xda, 0x7e, 0x73, 0x56, 0x88, 0xcd, 0x39, 0x09, 0xfc, 0x00, 0x91,
-            0xf8, 0x5a, 0xed, 0x09, 0x3d, 0xc4, 0x19, 0xd2, 0xf1, 0xe2, 0x22, 0xd4, 0x45, 0x51, 0xf8, 0xe0,
-            0xb4, 0x9e, 0xf1, 0x2d, 0xdb, 0xa1, 0x76, 0x76, 0x92, 0xfc, 0x58, 0x8e, 0x12, 0xe1, 0x23, 0x98,
-            0x46, 0x88, 0x37, 0x70, 0x7f, 0x8d, 0x54, 0x20, 0xc1, 0xe1, 0x5d, 0x12, 0x5f, 0x7c, 0x87, 0x23,
-            0x19, 0xf2, 0x45, 0x16, 0x3f, 0xba, 0x55, 0xec, 0xea, 0xfb, 0x6b, 0x6a, 0x31, 0xd0, 0xd1, 0x84,
-            0x57, 0x83, 0x29, 0x47, 0x82, 0xae, 0xb3, 0xf7, 0x35, 0x6b, 0x33, 0xcc, 0xa1, 0xb3, 0x14, 0x00,
-            0x3d, 0x3c, 0xb1, 0x4c, 0xe4, 0xe4, 0x1e, 0x47, 0xba, 0xf6, 0x93, 0xc3, 0x40, 0xaa, 0x79, 0x4c,
-            0x84, 0x80, 0x36, 0xdc, 0x6c, 0x0a, 0x32, 0x07, 0xe8, 0x12, 0x29, 0x79, 0x5c, 0xc1, 0x68, 0x10,
-            0xab, 0xb2, 0x45, 0xd7, 0x4a, 0xd1, 0x32, 0xaa, 0x74, 0x86, 0x1b, 0x1b, 0xfb, 0x13, 0x7d, 0x2d,
-            0x5d, 0x83, 0x74, 0x8a, 0x06, 0x1c, 0x5f, 0xdf, 0xd8, 0x0f, 0xea, 0x9d, 0xd4, 0x75, 0xc7, 0x59,
-            0x98, 0xcc, 0x43, 0x5e, 0xd0, 0x78, 0x91, 0x91, 0x45, 0xc2, 0xa6, 0xc7, 0x87, 0x40, 0x94, 0x92,
-            0x3a, 0x0b, 0x2a, 0x8d, 0x27, 0xf5, 0x15, 0xc5, 0x11, 0x61, 0xee, 0xbd, 0x1c, 0x22, 0xeb, 0xf1,
-            0xb9, 0xaa, 0xf2, 0xf1, 0x5c, 0x54, 0xe7, 0xd4, 0x84, 0xff, 0xac, 0x71, 0xba, 0x9d, 0xd2, 0x22,
-            0xb4, 0xbc, 0x91, 0x01, 0xf8, 0x8b, 0x11, 0x5a, 0x34, 0x0d, 0x4d, 0x61, 0xcd, 0x99, 0x18, 0xd7,
-            0x34, 0x04, 0x4b, 0x76, 0x79, 0x6b, 0xb8, 0x95, 0xff, 0x21, 0x54, 0x73, 0xca, 0x5b, 0xcd, 0x48,
-            0x71, 0x51, 0xe6, 0x16, 0xc7, 0xbd, 0x2a, 0x31, 0x52, 0xb5, 0x29, 0xf8, 0x8d, 0x9c, 0x2b, 0x19,
-            0xea, 0xdf, 0x1e, 0x61, 0x57, 0xb8, 0x08, 0x8a, 0x1d, 0x81, 0x76, 0xb1, 0xd6, 0x84, 0x5a, 0x71,
-            0x22, 0xa0, 0xea, 0x94, 0x63, 0x60, 0x2a, 0x78, 0x60, 0xfe, 0xa4, 0x16, 0x71, 0xc4, 0x56, 0x81,
-            0x9d, 0x8f, 0x43, 0x02, 0xe2, 0x31, 0x27, 0xb6, 0xcd, 0xc0, 0xbc, 0x45, 0x78, 0x63, 0xce, 0xe5,
-            0x52, 0x05, 0x55, 0x08, 0x82, 0x37, 0xca, 0x98, 0x89, 0xce, 0x8f, 0x3b, 0xce, 0x10, 0x21, 0x5b,
-            0x10, 0xe0, 0xba, 0xf3, 0xd6, 0x83, 0x07, 0x54, 0xb3, 0xa3, 0xac, 0xd7, 0x33, 0x3c, 0xac, 0x10,
-            0x53, 0x21, 0x78, 0x8d, 0xc2, 0x82, 0x96, 0xf9, 0xee, 0xb9, 0x12, 0xde, 0x22, 0x51, 0x64, 0xe6,
-            0x0f, 0x9c, 0x90, 0x37, 0x9c, 0x69, 0x83, 0xba, 0xef, 0xeb, 0x91, 0x56, 0xf2, 0xb3, 0xcc, 0xfb,
-            0x7e, 0xb3, 0xd7, 0x85, 0xca, 0xa8, 0x4f, 0x50, 0xb1, 0xc7, 0x87, 0xfa, 0xe8, 0x07, 0x8b, 0xa1,
-            0xa2, 0x65, 0x9e, 0x0a, 0x7e, 0x65, 0xe8, 0xde, 0xa0, 0x45, 0xdd, 0xb7, 0x41, 0x90, 0xc5, 0x59,
-            0x55, 0x21, 0xea, 0x95, 0x07, 0x6a, 0x9b, 0x2e, 0x03, 0xc6, 0x25, 0x28, 0x13, 0xd8, 0x6f, 0x0e,
-            0x8c, 0xb3, 0x27, 0xdd, 0x95, 0x9f, 0x0e, 0x39, 0xbf, 0xd6, 0x57, 0x1c, 0xd0, 0xf6, 0x9e, 0xe0,
-            0x33, 0xb8, 0x00, 0x97, 0x62, 0x30, 0x8e, 0x42, 0x1f, 0x80, 0x69, 0xcc, 0x43, 0xad, 0x1a, 0xb3,
-            0x48, 0x5b, 0xd6, 0x23, 0x59, 0xb7, 0xe0, 0x93, 0x50, 0x09, 0x8c, 0xfc, 0x72, 0x75, 0x62, 0xe9,
-            0x75, 0x6b, 0x0c, 0x71, 0x41, 0x2a, 0x63, 0x8f, 0xba, 0x7b, 0x5d, 0x6f, 0x93, 0x25, 0x91, 0x08,
-            0xc6, 0xd9, 0x7d, 0xb0, 0xb4, 0x8e, 0x8e, 0x19, 0x80, 0x1d, 0x7f, 0x39, 0xf6, 0x5f, 0x21, 0x20,
-            0xc9, 0xa2, 0xd0, 0x6d, 0xa9, 0x8d, 0x34, 0x97, 0xd9, 0x1a, 0x78, 0x5d, 0x81, 0xb5, 0xa9, 0x96,
-            0x97, 0x8d, 0xcf, 0x7c, 0xac, 0xd3, 0x96, 0x83, 0x19, 0xe1, 0x83, 0x6f, 0xa5, 0x72, 0x18, 0x4a,
-            0xb4, 0xc2, 0xa5, 0x6a, 0x90, 0x2c, 0xf1, 0x59, 0x82, 0xbc, 0x04, 0x5f, 0x9b, 0x1e, 0x30, 0x08,
-            0x7f, 0xc7, 0xc2, 0x1e, 0x7f, 0x1e, 0xc6, 0x11, 0x21, 0x52, 0xcc, 0x96, 0xfe, 0x3e, 0x86, 0x6b,
-            0x5e, 0x04, 0x90, 0x85, 0xf8, 0xcb, 0x49, 0xa3, 0xc4, 0x77, 0xdc, 0x9a, 0x21, 0xb6, 0x11, 0xb2,
-            0xcd, 0xfe, 0x16, 0x37, 0xda, 0x2f, 0x83, 0x4c, 0x65, 0x43, 0xef, 0x9e, 0x02, 0x31, 0x29, 0xb6,
-            0xd6, 0x73, 0xd6, 0xdc, 0xa0, 0x9f, 0x68, 0x72, 0x47, 0xd8, 0x75, 0x37, 0xa0, 0x78, 0x4e, 0x83,
-            0xa9, 0x45, 0x8c, 0xa3, 0x7a, 0xc9, 0x14, 0xa3, 0xd4, 0xa3, 0x8c, 0xfc, 0x1f, 0xd2, 0x0b, 0xab,
-            0x86, 0x8e, 0xec, 0x9c, 0x2a, 0xdc, 0x33, 0x25, 0xf1, 0xc2, 0x56, 0x91, 0xc8, 0xd3, 0xb5, 0x9e,
-            0xea, 0x0a, 0xcf, 0xbd, 0xa4, 0x69, 0xc7, 0xaa, 0xe1, 0xa5, 0x74, 0x3e, 0x6d, 0x6c, 0x12, 0x9c,
-            0x6c, 0xba, 0x11, 0x90, 0x2c, 0xe9, 0x55, 0x11, 0x9e, 0xdb, 0x5f, 0xb6, 0x03, 0xb3, 0x29, 0x83,
-            0x92, 0x93, 0xd4, 0x34, 0x9c, 0x02, 0x6a, 0xd0, 0x95, 0x24, 0x9c, 0x92, 0x1a, 0x2d, 0xde, 0x8c,
-            0xac, 0x49, 0x13, 0x6c, 0xec, 0x58, 0xc3, 0x81, 0x68, 0x80, 0xe6, 0xfc, 0x2d, 0x0f, 0xe5, 0xa2,
-            0x20, 0x9c, 0xa1, 0x30, 0x58, 0xe1, 0x9a, 0xa8, 0xd9, 0x85, 0x19, 0x1e, 0x8c, 0x29, 0xd5, 0xe2,
-            0x83, 0xe3, 0xda, 0x09, 0x0d, 0x61, 0xbc, 0xa2, 0x6e, 0x92, 0x12, 0x35, 0xca, 0x12, 0xd0, 0xe9,
-            0xe7, 0x4f, 0x35, 0x60, 0xdd, 0x95, 0xcc, 0x5a, 0xb0, 0xad, 0xe2, 0x25, 0x85, 0xbf, 0xc7, 0x3e,
-            0x39, 0x29, 0x08, 0x7f, 0xa7, 0xb6, 0xe6, 0xa1, 0x15, 0x14, 0x75, 0xf4, 0x44, 0x81, 0x63, 0x74,
-            0xcb, 0x94, 0x21, 0x8a, 0x5f, 0xf7, 0x67, 0xff, 0x92, 0x5c, 0x21, 0x06, 0x5d, 0xec, 0x23, 0xd1,
-            0xa2, 0xff, 0x87, 0xd6, 0xa8, 0xd2, 0xdd, 0x9a, 0x5f, 0xe8, 0x14, 0x9a, 0x96, 0x78, 0x05, 0x13,
-            0xdc, 0xea, 0x88, 0xee, 0xbc, 0x0f, 0x53, 0x6f, 0x40, 0x68, 0xc1, 0x22, 0x7b, 0x46, 0xc3, 0xc4,
-            0x10, 0x22, 0x95, 0x01, 0x19, 0xf2, 0x63, 0xcc, 0x1a, 0x44, 0x1b, 0xf1, 0x39, 0x80, 0x1a, 0xde,
-            0x44, 0x47, 0xb6, 0x2a, 0xf2, 0xda, 0x23, 0xbc, 0xff, 0x4a, 0x89, 0x29, 0x22, 0xf2, 0x39, 0x1b,
-            0x5b, 0x09, 0xc4, 0xbb, 0x32, 0x8f, 0xa4, 0xd7, 0x8b, 0x19, 0xe6, 0x61, 0xd7, 0xa6, 0xbf, 0xbe,
-            0xf6, 0xe3, 0x93, 0x8d, 0x4e, 0x1e, 0x8a, 0xc6, 0xf4, 0xc3, 0x3b, 0x90, 0x93, 0x57, 0x8e, 0x4a,
-            0xea, 0xea, 0x69, 0xd9, 0x1c, 0xff, 0x99, 0xe8, 0xdf, 0x23, 0x33, 0x8d, 0x8b, 0xc6, 0x46, 0xe9,
-            0x66, 0xa3, 0x7c, 0xf4, 0x61, 0x48, 0x60, 0xb1, 0x82, 0x3f, 0x2e, 0x6f, 0xce, 0x6a, 0x29, 0x23,
-            0x0e, 0x3a, 0x12, 0x5f, 0x24, 0xd0, 0x21, 0xc4, 0xc9, 0xa5, 0xb8, 0x01, 0x5d, 0xb8, 0xe6, 0x3e,
-            0x18, 0xa4, 0xd4, 0x88, 0x2c, 0x9e, 0xa8, 0xee, 0x62, 0x6f, 0xcf, 0x05, 0x22, 0x49, 0xd8, 0x2f,
-            0x9f, 0x08, 0xe6, 0xc5, 0x4d, 0xb4, 0x05, 0x3a, 0xd4, 0xff, 0x7d, 0x9b, 0x88, 0x6c, 0xd2, 0xd8,
-            0x84, 0x2e, 0x61, 0x63, 0x9b, 0x3d, 0x43, 0xcc, 0x4c, 0x3c, 0x01, 0x09, 0x38, 0x44, 0x59, 0x2d,
-            0x8c, 0x68, 0x31, 0x8c, 0xba, 0xae, 0x43, 0x17, 0x74, 0x4d, 0x1c, 0x75, 0xae, 0xe0, 0xfc, 0x8e,
-            0x86, 0xdf, 0x5f, 0xe4, 0x08, 0x15, 0xef, 0x2f, 0xcb, 0x0f, 0x64, 0x18, 0xd7, 0x7c, 0x63, 0xa7,
-            0x5b, 0x77, 0xf6, 0xe5, 0xa2, 0x0a, 0x09, 0xa8, 0x34, 0xb1, 0x5e, 0x5b, 0x6f, 0x83, 0x68, 0x11,
-            0xa6, 0x38, 0xfd, 0xcf, 0xd7, 0x31, 0x09, 0x65, 0xab, 0x72, 0xfa, 0xa7, 0x64, 0x5f, 0x13, 0x72,
-            0x7c, 0x0d, 0xb8, 0x9b, 0x86, 0xf0, 0x99, 0xe7, 0xa4, 0x0a, 0x2a, 0x63, 0x1f, 0xc5, 0x5b, 0x36,
-            0x20, 0x3a, 0x74, 0x00, 0xa7, 0x57, 0x28, 0xda, 0x14, 0xc0, 0x89, 0x64, 0x35, 0xff, 0xcc, 0xad,
-            0x57, 0x31, 0xf8, 0xed, 0x0c, 0x6a, 0x2f, 0x4b, 0xd4, 0xea, 0xe6, 0xa7, 0x5a, 0x8a, 0x21, 0x91,
-            0xcc, 0x0b, 0x09, 0xa7, 0x0a, 0xf4, 0x90, 0x65, 0xb9, 0xc9, 0x17, 0xa9, 0x4a, 0x11, 0x0c, 0x4d,
-            0x26, 0xe9, 0x88, 0xd5, 0x8e, 0x90, 0x82, 0xf7, 0x32, 0x36, 0x2a, 0x8b, 0x9b, 0x86, 0xa8, 0x43,
-            0xc4, 0xf4, 0xdd, 0xe4, 0x70, 0x1d, 0x51, 0x62, 0x5b, 0xd9, 0x7f, 0x51, 0xd6, 0xfd, 0x1f, 0xf5,
-            0xd9, 0xec, 0x5a, 0x89, 0xd6, 0xe5, 0x2a, 0x39, 0xae, 0xdb, 0x77, 0x39, 0x45, 0x83, 0x9f, 0x99,
-            0x5a, 0x18, 0x61, 0x3a, 0xbb, 0xac, 0x9a, 0x51, 0x2c, 0xc9, 0x1b, 0x64, 0xe2, 0x53, 0x01, 0xbb,
-            0x43, 0xf6, 0xde, 0x31, 0x65, 0x4d, 0xa9, 0x53, 0x37, 0x66, 0x24, 0x21, 0x5b, 0x25, 0xf9, 0xf1,
-            0x9a, 0x19, 0x0d, 0xf3, 0x16, 0x18, 0xf3, 0x32, 0xf6, 0xeb, 0x4f, 0x27, 0x13, 0x27, 0xcb, 0x4a,
-            0x30, 0xd4, 0xbe, 0x89, 0x73, 0xfd, 0xb9, 0xa6, 0x52, 0x6d, 0x89, 0xd4, 0x4b, 0x26, 0xb9, 0x9c,
-            0x18, 0xf6, 0x3d, 0x7c, 0x2a, 0x40, 0x93, 0xf8, 0x11, 0x87, 0x42, 0x4b, 0xd5, 0xde, 0xce, 0x20,
-            0xe0, 0x45, 0x2b, 0xe0, 0x88, 0x1a, 0x1d, 0x49, 0x73, 0xed, 0xe5, 0x31, 0x27, 0xf0, 0x69, 0xfd,
-            0xce, 0x07, 0xd4, 0x64, 0xed, 0x99, 0x67, 0xf4, 0x9c, 0xe9, 0xf6, 0x04, 0xc0, 0xbd, 0xa1, 0x76,
-            0x3f, 0x24, 0xf0, 0x11, 0xc2, 0x1e, 0xa3, 0x81, 0x25, 0xb5, 0x67, 0x35, 0x48, 0x9a, 0x8e, 0x8f,
-            0x31, 0x9e, 0x7f, 0x74, 0x7b, 0x65, 0x95, 0xcf, 0x09, 0xf6, 0x74, 0xe0, 0x7a, 0xe6, 0xde, 0xe5,
-            0x3e, 0x3c, 0xea, 0x08, 0x23, 0x06, 0x2f, 0xf2, 0x22, 0xb3, 0x93, 0x8e, 0x72, 0x04, 0x21, 0x33,
-            0x82, 0x9c, 0x16, 0xe3, 0x69, 0xab, 0x4a, 0x6f, 0x66, 0x34, 0x45, 0x62, 0x28, 0xcb, 0xf5, 0xea,
-            0x01, 0x14, 0x12, 0x31, 0xf8, 0x37, 0x0c, 0x88, 0x46, 0x99, 0x0d, 0xd3, 0xc3, 0xb9, 0x73, 0x3c,
-            0xd7, 0xaa, 0x8c, 0x40, 0x74, 0x50, 0x9f, 0x4b, 0x90, 0xf9, 0x2a, 0xda, 0x7d, 0xd2, 0x8c, 0x8e,
-            0x34, 0x3b, 0xf9, 0x0a, 0x49, 0x80, 0xf4, 0x97, 0xea, 0x7c, 0xdf, 0x24, 0x88, 0xe2, 0x0a, 0x70,
-            0x27, 0x5e, 0x82, 0x2f, 0x96, 0xcd, 0xc1, 0x7e, 0x18, 0x99, 0xaa, 0x28, 0x35, 0x85, 0xbc, 0xc4,
-            0xb6, 0x99, 0x09, 0x30, 0x41, 0xa4, 0xfb, 0xa2, 0x82, 0x88, 0x40, 0x95, 0x64, 0x3f, 0x7b, 0x46,
-            0xde, 0x01, 0xf8, 0x07, 0xbf, 0x8a, 0x40, 0x35, 0xb3, 0x34, 0xa7, 0x25, 0x31, 0xd9, 0xe6, 0x6c,
-            0xe1, 0x88, 0x93, 0x9c, 0x61, 0x23, 0xb2, 0xa7, 0x22, 0x26, 0x4b, 0x60, 0x00, 0xd0, 0xb1, 0x8f,
-            0x98, 0xb0, 0x8f, 0x5a, 0x1a, 0x78, 0x6a, 0x40, 0x3c, 0x76, 0xf5, 0xb9, 0x25, 0x4b, 0x9e, 0xb5,
-            0x8f, 0xa3, 0xdd, 0x98, 0x7c, 0x8d, 0xdf, 0x61, 0x82, 0x0b, 0xcd, 0xfc, 0x03, 0x25, 0xfb, 0x69,
-            0x76, 0xeb, 0x86, 0x50, 0xe9, 0x5d, 0xd7, 0x77, 0x6b, 0x40, 0xf9, 0xcb, 0xeb, 0x1c, 0x2b, 0xe5,
-            0x40, 0xc1, 0x1c, 0xf7, 0x95, 0x83, 0x33, 0x1f, 0x85, 0x8e, 0x31, 0x98, 0x8b, 0x07, 0x4b, 0x23,
-            0x11, 0x8c, 0xef, 0x12, 0x5b, 0x5e, 0xfb, 0x3f, 0x34, 0x20, 0x60, 0x87, 0xff, 0x65, 0xab, 0x26,
-            0x90, 0xca, 0xb7, 0x3c, 0xe1, 0x8e, 0xf9, 0x6e, 0xe4, 0x9b, 0xbe, 0x2e, 0x3d, 0x4a, 0xc9, 0x7b,
-            0x34, 0x52, 0x05, 0xf3, 0xae, 0x36, 0xc0, 0xc4, 0x25, 0x77, 0x21, 0x11, 0xda, 0xcd, 0x31, 0xfe,
-            0x59, 0x94, 0xc2, 0x8d, 0xf2, 0xc8, 0x3b, 0xa2, 0x64, 0xa8, 0x24, 0x93, 0x0a, 0x14, 0xb4, 0xb0,
-            0x21, 0x53, 0x59, 0x11, 0x9e, 0xce, 0x11, 0x49, 0x4b, 0xe4, 0x20, 0xdf, 0xc1, 0xe6, 0x88, 0xde,
-            0x9c, 0x67, 0xb7, 0x26, 0xc4, 0x77, 0xa4, 0x3e, 0x8f, 0x4d, 0x48, 0x0c, 0x5e, 0xa4, 0x7f, 0xdc,
-            0xf0, 0x95, 0xb6, 0x28, 0x3a, 0x0c, 0x50, 0x65, 0xa5, 0x84, 0x70, 0xb6, 0x13, 0xbd, 0x61, 0xa0,
-            0x77, 0x4a, 0x67, 0xeb, 0x7a, 0x01, 0x2f, 0xf8, 0xa6, 0x99, 0x92, 0x73, 0xf6, 0x24, 0xaf, 0xfa,
-            0x89, 0x10, 0x61, 0x5b, 0x3a, 0x58, 0x13, 0x91, 0x9e, 0x49, 0x04, 0xea, 0x92, 0xd9, 0x82, 0xa3,
-            0xae, 0x96, 0x23, 0x0a, 0x2f, 0x90, 0x6b, 0x64, 0x8a, 0x3c, 0x4a, 0xab, 0xc3, 0x6f, 0xf2, 0x62,
-            0x1a, 0x06, 0x62, 0xfc, 0x29, 0xc2, 0x1b, 0x36, 0xd4, 0x2b, 0x7a, 0xd4, 0xc3, 0x8b, 0x59, 0x8c,
-            0xa9, 0x34, 0x3b, 0x1a, 0x7a, 0x6a, 0x4f, 0xc1, 0x9d, 0xd1, 0x68, 0x51, 0x39, 0x80, 0xce, 0xe2,
-            0x70, 0x6c, 0xa9, 0x27, 0x1a, 0x08, 0xf2, 0xf6, 0xe0, 0xad, 0x10, 0x93, 0x1e, 0xb4, 0x17, 0x39,
-            0x99, 0x25, 0x25, 0x54, 0x16, 0xf0, 0x7c, 0x68, 0xcb, 0x9c, 0xc3, 0xd5, 0x4d, 0x25, 0xdf, 0x25,
-            0xa5, 0xf3, 0x7c, 0xff, 0xad, 0xa3, 0x04, 0x9e, 0xae, 0x49, 0x77, 0xd3, 0xd9, 0x30, 0xcc, 0xd6,
-            0xc2, 0xc5, 0x91, 0x81, 0xbc, 0x04, 0x2b, 0x40, 0x81, 0xf5, 0xc2, 0x53, 0xa3, 0x8f, 0x23, 0xee,
-            0x04, 0xaf, 0x21, 0xce, 0x85, 0x90, 0xb6, 0xae, 0x94, 0xa4, 0x18, 0x04, 0x42, 0xf8, 0x63, 0x6c,
-            0xed, 0x22, 0x68, 0xd9, 0x92, 0x54, 0x0b, 0xa9, 0xa0, 0xc1, 0xf7, 0xcd, 0x86, 0x51, 0xa2, 0x25,
-            0xdf, 0xf3, 0x3e, 0xad, 0x8c, 0x5b, 0x49, 0x05, 0x77, 0xb1, 0xd8, 0x46, 0x81, 0x12, 0x52, 0xb0,
-            0x8f, 0xe0, 0x4d, 0x6e, 0xad, 0x6e, 0x0d, 0xee, 0x43, 0x94, 0xb0, 0x82, 0xc7, 0x28, 0xf5, 0x71,
-            0x30, 0xed, 0x48, 0x14, 0xbb, 0x03, 0xd8, 0x94, 0x4d, 0x59, 0x21, 0x4b, 0xe6, 0x85, 0x71, 0x29,
-            0x07, 0xa1, 0x05, 0x1c, 0x82, 0x36, 0x9c, 0x79, 0x09, 0x85, 0x1a, 0xa3, 0x61, 0xca, 0xe1, 0x71,
-            0xec, 0x6b, 0x1f, 0xe7, 0x16, 0xbe, 0x6b, 0x36, 0x5a, 0x51, 0xc6, 0xb4, 0xc7, 0x22, 0xca, 0x19,
-            0x81, 0xd2, 0x51, 0x74, 0xf6, 0xc9, 0x01, 0xa5, 0x76, 0x0c, 0x3b, 0x09, 0xfa, 0x68, 0xe1, 0xbe,
-            0x67, 0x9f, 0xd5, 0xad, 0xaa, 0xe7, 0x18, 0xef, 0x55, 0xb5, 0xb4, 0xb7, 0xf4, 0xec, 0x8a, 0x1b,
-            0xb1, 0xe4, 0x1b, 0xf8, 0x82, 0x1a, 0x0f, 0x75, 0xc1, 0x26, 0x4a, 0x59, 0xcc, 0x29, 0x5c, 0xf0,
-            0x51, 0x47, 0x03, 0x8b, 0x28, 0x82, 0xd9, 0x94, 0x34, 0xbf, 0x08, 0xf6, 0xc7, 0x40, 0x86, 0x53,
-            0xc3, 0x07, 0x8c, 0x72, 0x6d, 0x9a, 0x71, 0x15, 0xaa, 0x39, 0xf9, 0x26, 0x77, 0x73, 0x72, 0xcd,
-            0x2c, 0x83, 0xe4, 0xb9, 0xd4, 0x8a, 0x6f, 0x72, 0x85, 0xb9, 0xde, 0x2e, 0x31, 0x35, 0x4b, 0x68,
-            0x8d, 0x68, 0x52, 0xee, 0x71, 0x4e, 0xa6, 0x90, 0xe9, 0x61, 0xe7, 0x1f, 0xa6, 0x56, 0x31, 0xc3,
-            0x95, 0x8e, 0xc0, 0x30, 0x1b, 0xcb, 0xb1, 0x6a, 0x0c, 0xaa, 0xf2, 0x13, 0x8b, 0xd3, 0xf7, 0x83,
-            0xfe, 0xa2, 0xdb, 0x25, 0x22, 0x1d, 0x46, 0x34, 0x5c, 0xdb, 0xc1, 0x3f, 0x9d, 0x52, 0xa9, 0xff,
-            0x31, 0x72, 0xbb, 0xe1, 0x7d, 0xe7, 0xeb, 0xa2, 0xe6, 0xd0, 0x7b, 0x78, 0x78, 0xc1, 0x90, 0x95,
-            0x06, 0xc5, 0xb9, 0x04, 0xab, 0x21, 0xf6, 0x78, 0x10, 0x47, 0x85, 0x72, 0xd1, 0x38, 0x66, 0xbf,
-            0x99, 0x97, 0x2a, 0x52, 0x2e, 0xca, 0xf0, 0x6a, 0x74, 0x95, 0xaf, 0x37, 0xd8, 0xa3, 0x54, 0x3c,
-            0x4c, 0x47, 0x62, 0x9e, 0x80, 0x51, 0x1e, 0x98, 0xec, 0xcf, 0x1e, 0x3a, 0xa3, 0x8f, 0xcc, 0x5e,
-            0x2d, 0x11, 0xe7, 0xa2, 0x8b, 0x5f, 0x19, 0x0f, 0x73, 0x2e, 0xc9, 0x45, 0x26, 0xcf, 0xf4, 0xa0,
-            0x4b, 0x11, 0x9e, 0x4c, 0x9d, 0xab, 0x80, 0x43, 0xe6, 0x18, 0xa5, 0x39, 0xae, 0x8b, 0x10, 0x73,
-            0x88, 0xdd, 0x7c, 0x5b, 0x1c, 0xae, 0x70, 0xc3, 0xbf, 0x16, 0x20, 0xcf, 0x4e, 0x0b, 0x01, 0xf5,
-            0xb9, 0x92, 0xa9, 0x49, 0x60, 0x25, 0xa9, 0xd1, 0xd4, 0x91, 0x9e, 0x32, 0xd3, 0x37, 0xd0, 0xc9,
-            0xd4, 0x01, 0x79, 0x75, 0x95, 0x6e, 0x7a, 0x92, 0xa6, 0x5e, 0xa6, 0x48, 0x68, 0xf2, 0x93, 0x96,
-            0x86, 0x61, 0xcb, 0x80, 0xc3, 0xf7, 0xf2, 0xeb, 0x48, 0x5e, 0x10, 0xb5, 0x06, 0x22, 0x9e, 0x42,
-            0x46, 0x68, 0xbc, 0xba, 0xa8, 0xa0, 0xd8, 0x72, 0xa7, 0x86, 0xd1, 0xea, 0x01, 0x89, 0xce, 0x59,
-            0xea, 0x4f, 0xd1, 0x88, 0xa0, 0x61, 0xed, 0x4b, 0xdd, 0x00, 0x33, 0xba, 0x39, 0x7c, 0xb7, 0x7b,
-            0x47, 0x24, 0x01, 0x67, 0x89, 0x56, 0x74, 0x79, 0x84, 0x2a, 0x84, 0xb8, 0x54, 0xcb, 0xa5, 0xde,
-            0xac, 0xc0, 0x43, 0xcb, 0x06, 0x9f, 0x07, 0x5e, 0x56, 0xdd, 0x62, 0xc0, 0xca, 0xe9, 0x6a, 0xb0,
-            0x13, 0x60, 0x61, 0x11, 0x46, 0x61, 0x03, 0x4c, 0x85, 0xa4, 0xa9, 0x55, 0x88, 0x80, 0x2a, 0x43,
-            0x4a, 0x29, 0xc2, 0xb0, 0x48, 0x49, 0x27, 0xf4, 0xd5, 0xf7, 0x19, 0x8a, 0xbc, 0x6b, 0x10, 0x78,
-            0x3c, 0x8b, 0xd4, 0xe7, 0x92, 0x87, 0x33, 0x24, 0x1d, 0x84, 0x9a, 0x6d, 0xc0, 0x8a, 0x48, 0x57,
-            0x06, 0x7f, 0x55, 0x52, 0x9e, 0xd7, 0x44, 0x67, 0xc9, 0x53, 0xf6, 0xe8, 0x01, 0xb4, 0xd5, 0x7d,
-            0x02, 0x9c, 0xfe, 0x37, 0x98, 0x2b, 0x17, 0x1f, 0x98, 0x46, 0xff, 0x57, 0x98, 0x94, 0x6b, 0xd8,
-            0x01, 0xa0, 0x14, 0x6a, 0x68, 0x73, 0xa6, 0x8c, 0xcb, 0x3f, 0xf4, 0xde, 0xfd, 0x92, 0xaf, 0x04,
-            0x93, 0x78, 0xd0, 0x00, 0xfd, 0xc6, 0x5b, 0x43, 0x0b, 0xca, 0x52, 0xff, 0x59, 0x21, 0x08, 0x57,
-            0x1e, 0x1d, 0x60, 0xef, 0x59, 0xf4, 0xa8, 0x25, 0xc9, 0x73, 0x3d, 0x90, 0xbe, 0xec, 0x69, 0xdb,
-            0xd0, 0x54, 0xb6, 0x18, 0xab, 0xee, 0x3f, 0xc0, 0x34, 0xc3, 0x37, 0xca, 0x60, 0xdb, 0x96, 0x0b,
-            0x47, 0x4c, 0x36, 0x97, 0x52, 0x12, 0xcd, 0x04, 0xe1, 0x8e, 0x9d, 0x4e, 0xb3, 0x34, 0x3c, 0xa4,
-            0x47, 0xfd, 0x69, 0x4d, 0x17, 0x68, 0x74, 0x38, 0xd4, 0x19, 0x51, 0xd8, 0x6a, 0xee, 0x1a, 0x65,
-            0x68, 0xa4, 0x32, 0x6d, 0x9a, 0x84, 0x59, 0x07, 0x65, 0xe7, 0xde, 0xf6, 0xe0, 0x11, 0x95, 0x5d,
-            0x6d, 0xb1, 0x97, 0x67, 0xe6, 0x65, 0xb4, 0x9b, 0x64, 0xea, 0x90, 0x36, 0x07, 0xcf, 0xac, 0xff,
-            0xac, 0x31, 0x9c, 0x07, 0x97, 0xbf, 0x79, 0xf7, 0x8c, 0x81, 0x58, 0xd2, 0x35, 0xea, 0xf4, 0xb0,
-            0x49, 0xf4, 0x29, 0xda, 0x81, 0x1d, 0x65, 0x49, 0x0f, 0xa8, 0xa0, 0xe7, 0x35, 0x9e, 0xb0, 0x78,
-            0x63, 0x82, 0xb0, 0x06, 0x4e, 0xbc, 0x99, 0x06, 0x08, 0xa2, 0x8f, 0xe1, 0xd9, 0xa9, 0x23, 0x64,
-            0x4e, 0xbe, 0x7f, 0x26, 0x92, 0xd7, 0xc5, 0x19, 0xba, 0xcf, 0x8e, 0xf2, 0x60, 0x25, 0x28, 0x73,
-            0x8a, 0x68, 0xc6, 0xa5, 0x47, 0xd7, 0xfb, 0x13, 0x11, 0x00, 0x2a, 0x6d, 0x4b, 0x75, 0xba, 0xf6,
-            0x55, 0x63, 0x95, 0xc9, 0xde, 0x51, 0x08, 0x1b, 0x04, 0x63, 0xa3, 0x94, 0xf8, 0x33, 0xf9, 0xff,
-            0x55, 0x68, 0x0e, 0x85, 0xf4, 0x2c, 0xfb, 0x81, 0x8a, 0xd1, 0xa2, 0x37, 0xe6, 0x9f, 0x10, 0x82,
-            0xc9, 0x70, 0xd9, 0x54, 0xbf, 0x55, 0x19, 0x44, 0x54, 0xb9, 0x6a, 0x34, 0xa3, 0x20, 0x99, 0x43,
-            0xb3, 0xdc, 0x06, 0x11, 0xae, 0x9d, 0x5e, 0xde, 0x97, 0xaa, 0x01, 0x68, 0xc5, 0xd4, 0x0b, 0xf6,
-            0xa7, 0x42, 0x4c, 0x58, 0xeb, 0xc6, 0xa2, 0x82, 0x3b, 0xbd, 0x4f, 0xf1, 0x3f, 0x7a, 0x51, 0x91,
-            0x86, 0x0b, 0xf2, 0xcd, 0xec, 0x7b, 0x50, 0x12, 0x25, 0x98, 0xd7, 0xc1, 0x29, 0x94, 0xa5, 0x1b,
-            0xf9, 0x89, 0xc1, 0x72, 0x17, 0x0d, 0x4d, 0x60, 0xaf, 0x19, 0x5b, 0x18, 0xef, 0x7e, 0xc9, 0xcc,
-            0x8b, 0x7b, 0xd2, 0xb8, 0x80, 0x8b, 0xf2, 0xab, 0x94, 0x3f, 0x2a, 0x24, 0x5e, 0x74, 0x49, 0xb5,
-            0x08, 0xb4, 0x44, 0xca, 0x2e, 0x53, 0x2e, 0x5b, 0x6d, 0x03, 0x23, 0x37, 0x63, 0x08, 0xba, 0x95,
-            0x4b, 0x76, 0xcd, 0x13, 0xf8, 0x92, 0x16, 0x44, 0xf7, 0xa6, 0xbe, 0xe4, 0xb0, 0x10, 0x91, 0x74,
-            0x6f, 0x23, 0x1a, 0xe5, 0x69, 0xc0, 0xec, 0x7f, 0xee, 0x46, 0xd3, 0x9c, 0xba, 0x98, 0x30, 0x69,
-            0x98, 0x8e, 0x7b, 0x0b, 0x96, 0x7a, 0x73, 0xe5, 0x86, 0xd6, 0x43, 0x52, 0x1b, 0x22, 0x90, 0x70,
-            0xa3, 0x9e, 0x29, 0x76, 0xad, 0xb7, 0xf6, 0x35, 0x61, 0xc8, 0x66, 0x85, 0x48, 0x74, 0x3f, 0x62,
-            0x31, 0x14, 0x33, 0x42, 0x68, 0x48, 0x2e, 0x1c, 0x00, 0x20, 0x90, 0x92, 0x20, 0x22, 0xfc, 0xaa,
-            0x48, 0x68, 0x9b, 0x55, 0xd5, 0xb0, 0x99, 0x8e, 0x35, 0x7a, 0x0a, 0x55, 0x9b, 0x63, 0xd0, 0x77,
-            0xf2, 0xdc, 0xec, 0xba, 0x11, 0x49, 0x2f, 0x8b, 0xed, 0xac, 0xa6, 0xed, 0x92, 0x51, 0x3e, 0x31,
-            0x74, 0x28, 0xc3, 0xd8, 0x76, 0xe0, 0xfd, 0x04, 0x8e, 0x6a, 0xae, 0xae, 0x6d, 0x8e, 0x6b, 0xab,
-            0xd4, 0x91, 0x53, 0xfa, 0x81, 0x2e, 0x03, 0x04, 0xcb, 0x6c, 0x24, 0x59, 0xf4, 0x18, 0xe1, 0x24,
-            0x41, 0x96, 0xeb, 0xe2, 0xe2, 0xf9, 0x6f, 0xb0, 0xc1, 0xb0, 0x12, 0x93, 0xd1, 0x98, 0x60, 0x49,
-            0xea, 0xf5, 0x14, 0xbb, 0x4e, 0xa7, 0x10, 0xed, 0x97, 0xab, 0x67, 0x63, 0x2b, 0x8e, 0x6d, 0x73,
-            0x7f, 0x49, 0x61, 0x00, 0x3a, 0x1e, 0xc9, 0x23, 0x1e, 0x1c, 0x0c, 0x5d, 0x92, 0xc2, 0xed, 0x44,
-            0x70, 0x73, 0xa3, 0xc2, 0x32, 0x49, 0x30, 0xe5, 0x2f, 0xc0, 0x91, 0xfe, 0xef, 0xc9, 0xe5, 0x12,
-            0x12, 0x2c, 0x55, 0x53, 0x51, 0x91, 0x59, 0x86, 0x01, 0x1e, 0x4e, 0xba, 0x0a, 0xb9, 0x57, 0x6a,
-            0x0a, 0x20, 0xd6, 0x2d, 0xf9, 0x85, 0x9e, 0x0c, 0xb9, 0x72, 0x27, 0x0a, 0x32, 0xee, 0xed, 0xda,
-            0xbe, 0x1e, 0xf6, 0xb4, 0x28, 0xea, 0x66, 0xb2, 0x49, 0x3d, 0x34, 0xd4, 0xea, 0x59, 0xc4, 0x41,
-            0x0b, 0xb7, 0xb0, 0xdf, 0x77, 0x76, 0x26, 0xc2, 0x37, 0x88, 0xc7, 0x8f, 0x99, 0xb4, 0x57, 0x2a,
-            0xc5, 0x9f, 0xba, 0xcd, 0xd7, 0xd5, 0xc2, 0x27, 0x20, 0x0b, 0xe2, 0xec, 0x4b, 0x76, 0xb0, 0x88,
-            0xd1, 0xe9, 0xd9, 0x92, 0x79, 0x8c, 0x69, 0x10, 0x80, 0xdb, 0x46, 0x8d, 0xfd, 0x28, 0xea, 0x54,
-            0xe1, 0x41, 0xdb, 0x34, 0x8a, 0x56, 0x29, 0x28, 0xb5, 0xea, 0x1d, 0x2e, 0xe8, 0x68, 0x5a, 0x73,
-            0x0b, 0x86, 0x04, 0xd1, 0x91, 0x0f, 0x2f, 0xf5, 0x88, 0xea, 0xb6, 0xce, 0x36, 0x13, 0xba, 0xcf,
-            0xd3, 0xff, 0x3f, 0xd5, 0x47, 0xcd, 0xe5, 0x92, 0x40, 0x33, 0xfd, 0x3a, 0xe1, 0x23, 0xa4, 0xf9,
-            0x5b, 0xc3, 0x50, 0x83, 0x0c, 0x97, 0xa0, 0x60, 0x3d, 0x1a, 0x57, 0xb5, 0x88, 0xd8, 0x77, 0xc0,
-            0x49, 0xe5, 0xed, 0x3e, 0xf1, 0x64, 0x69, 0x2c, 0x19, 0x84, 0x8f, 0x0a, 0x95, 0xa6, 0x48, 0xbf,
-            0x84, 0xd1, 0xe5, 0xda, 0x17, 0x5e, 0x9d, 0x1c, 0x26, 0xfc, 0x27, 0xd7, 0x7f, 0x15, 0x7b, 0xc3,
-            0xea, 0xa5, 0xc1, 0x10, 0x6b, 0x29, 0x88, 0x16, 0xfc, 0x46, 0x0c, 0x32, 0xd6, 0x07, 0xd3, 0x7c,
-            0x1a, 0x1e, 0xd6, 0x5e, 0x5d, 0x49, 0x5a, 0xbc, 0x8b, 0xfc, 0xac, 0x85, 0xe5, 0xfe, 0x26, 0x3b,
-            0x60, 0xa5, 0x59, 0x59, 0x56, 0xf5, 0x05, 0x88, 0x5e, 0x1b, 0x83, 0x3b, 0xc6, 0x07, 0x90, 0x16,
-            0x2d, 0x5d, 0x27, 0xfc, 0x45, 0x6c, 0xc2, 0x8c, 0xbe, 0xdd, 0xf9, 0x8e, 0x06, 0x41, 0xb4, 0xfa,
-            0xaa, 0x19, 0xa6, 0x51, 0x1f, 0x74, 0x6e, 0xf2, 0x2d, 0xac, 0x0e, 0x60, 0x06, 0x28, 0x30, 0xaf,
-            0x2e, 0x45, 0x0f, 0xf8, 0x90, 0xd9, 0xa2, 0xf6, 0x6b, 0x94, 0xc7, 0xc7, 0x44, 0xd7, 0x1b, 0xab,
-            0xc8, 0x81, 0x72, 0xc1, 0x7a, 0x2a, 0x92, 0xf9, 0x96, 0x9c, 0x81, 0x20, 0xb1, 0x9f, 0x84, 0x17,
-            0x2c, 0xa9, 0x02, 0x9f, 0x1a, 0xe4, 0x30, 0xcd, 0x02, 0x87, 0x21, 0x38, 0x98, 0x9b, 0x56, 0x54,
-            0xee, 0x57, 0x4d, 0xae, 0x8a, 0xa4, 0xfc, 0xf2, 0x88, 0x6c, 0x9e, 0x24, 0x63, 0xa3, 0xc1, 0xc1,
-            0x11, 0xf4, 0x58, 0xf9, 0x5b, 0xdd, 0xc0, 0x4c, 0x74, 0x3e, 0x4a, 0xb0, 0x3c, 0xed, 0x29, 0x0e,
-            0xfd, 0xcb, 0x32, 0x00, 0x7f, 0x29, 0x9b, 0x55, 0x8d, 0xe9, 0x7d, 0x45, 0x62, 0x3c, 0x93, 0xb9,
-            0x1b, 0xf5, 0x39, 0xda, 0x63, 0x33, 0x24, 0x9a, 0x3d, 0xa7, 0xc0, 0xcb, 0xd8, 0xd0, 0xa0, 0xb1,
-            0xe0, 0x6d, 0x62, 0xb6, 0x55, 0xc6, 0x97, 0x03, 0x3e, 0xdb, 0x1d, 0xe1, 0xa4, 0x6b, 0xb1, 0x12,
-            0x1c, 0xb8, 0x7b, 0x43, 0x3b, 0x1d, 0x09, 0xa2, 0x8f, 0x06, 0x45, 0x1c, 0x69, 0xc0, 0x74, 0x9b,
-            0x75, 0x65, 0x93, 0xd5, 0xda, 0x13, 0x6d, 0x20, 0x94, 0xeb, 0x5a, 0x9c, 0xf7, 0x6e, 0xf0, 0xd1,
-            0xfd, 0xb1, 0x85, 0x18, 0x82, 0xd2, 0x04, 0xd6, 0x03, 0x69, 0x08, 0x9e, 0x45, 0xcc, 0xf3, 0x1c,
-            0xd5, 0x60, 0x30, 0x6e, 0x78, 0x47, 0x42, 0x4f, 0x39, 0xf2, 0x54, 0xf8, 0xf8, 0xd2, 0xd9, 0x9f,
-            0x4a, 0x7d, 0xed, 0x9c, 0x50, 0x7e, 0xe2, 0x7e, 0xd9, 0x0c, 0x60, 0x7a, 0xc0, 0x01, 0x4f, 0x9a,
-            0x46, 0xc7, 0x15, 0xf4, 0x54, 0x66, 0x26, 0x16, 0x19, 0x11, 0xde, 0x0f, 0x55, 0x8f, 0x42, 0x47,
-            0x76, 0x30, 0x81, 0x65, 0x23, 0x02, 0x7a, 0x78, 0xe5, 0x8a, 0x9c, 0xc9, 0xbc, 0x10, 0x76, 0x54,
-            0x55, 0x7a, 0x17, 0x6d, 0x8d, 0xf2, 0x20, 0x53, 0x8e, 0x22, 0x8a, 0xf6, 0xac, 0x7e, 0xc6, 0xa6,
-            0x34, 0xda, 0x73, 0x19, 0x90, 0x19, 0x79, 0xbb, 0x6a, 0x05, 0x4a, 0x83, 0xef, 0x1c, 0xe7, 0xf3,
-            0x3e, 0x2a, 0x54, 0x49, 0x5c, 0x03, 0x7b, 0xf4, 0xe7, 0x9e, 0x64, 0x83, 0x19, 0x7a, 0x8e, 0xd9,
-            0xfd, 0x5d, 0x89, 0xfd, 0xa5, 0x5a, 0x7a, 0x96, 0x14, 0x8d, 0x88, 0x7a, 0xf4, 0xe7, 0xf1, 0x22,
-            0xab, 0xf2, 0x3a, 0x16, 0x4f, 0x58, 0xb6, 0xcc, 0xeb, 0x1e, 0x48, 0xe7, 0x23, 0x79, 0x11, 0xef,
-            0x59, 0x82, 0x10, 0xb0, 0x46, 0xa4, 0xe1, 0xf9, 0xf1, 0xcf, 0x5b, 0x58, 0xe7, 0x12, 0x57, 0xd9,
-            0x33, 0xb0, 0xab, 0x6e, 0x66, 0xcb, 0xf2, 0x48, 0xcb, 0x86, 0xa1, 0x30, 0xaf, 0x8e, 0xb0, 0xad,
-            0x1c, 0x0a, 0xa8, 0x79, 0xb7, 0x42, 0xae, 0xb4, 0xe7, 0x34, 0x1d, 0x7d, 0x5c, 0x98, 0x45, 0x33,
-            0x58, 0x87, 0x2c, 0x8b, 0xc0, 0xf7, 0xd6, 0x3c, 0x02, 0x02, 0x00, 0x5b, 0xd9, 0x9e, 0xd8, 0x66,
-            0x38, 0x05, 0xb9, 0xe7, 0x03, 0x42, 0x28, 0xa7, 0x60, 0xfd, 0x1a, 0xa1, 0xb1, 0xa1, 0x63, 0x27,
-            0xae, 0xc0, 0x9f, 0xb5, 0xab, 0x47, 0xdf, 0xba, 0x57, 0x40, 0xc0, 0x46, 0x00, 0x51, 0xc8, 0x29,
-            0x7d, 0x23, 0x80, 0x6f, 0x79, 0x7a, 0x7e, 0xae, 0x80, 0xc0, 0x39, 0x09, 0x66, 0x96, 0x4e, 0x82,
-            0x86, 0x57, 0xf5, 0xa8, 0x1b, 0x27, 0x48, 0xc6, 0x7f, 0x4b, 0x37, 0xfd, 0xa6, 0x45, 0x0a, 0xbe,
-            0x46, 0x52, 0x32, 0x6e, 0xa7, 0x2e, 0x8a, 0xb1, 0xf1, 0x92, 0x0a, 0x2f, 0x63, 0x37, 0xb0, 0xfe,
-            0x26, 0x54, 0x60, 0xc9, 0x32, 0xe6, 0x12, 0xc7, 0xce, 0x43, 0xd1, 0x8e, 0x08, 0x01, 0x56, 0x4c,
-            0xf6, 0x5e, 0x23, 0x95, 0x9c, 0xf4, 0x94, 0x42, 0xee, 0x5b, 0x6a, 0xfa, 0x5d, 0x3a, 0x17, 0xdc,
-            0x88, 0x6e, 0x24, 0x56, 0x81, 0xe6, 0xfd, 0x42, 0x53, 0xd2, 0xad, 0xdf, 0xdd, 0xb2, 0x72, 0xa3,
-            0x88, 0xe5, 0x81, 0xe9, 0xc3, 0x63, 0x45, 0x7f, 0x52, 0x18, 0xa6, 0xb2, 0x25, 0x4b, 0x9f, 0xa6,
-            0x66, 0x6b, 0xc0, 0x73, 0xc3, 0x6b, 0x3c, 0xc5, 0x68, 0x47, 0xde, 0x60, 0x0c, 0x43, 0xba, 0x4d,
-            0x55, 0x4a, 0x50, 0x40, 0xeb, 0xf2, 0x4a, 0xc9, 0xdf, 0x65, 0xcf, 0x97, 0xd1, 0xf2, 0x91, 0x60,
-            0xe1, 0x06, 0x98, 0xb3, 0x40, 0xa8, 0x77, 0xc6, 0xe1, 0x6f, 0x48, 0x33, 0x32, 0x6f, 0xdb, 0x53,
-            0xc5, 0x90, 0x19, 0xef, 0x37, 0x7b, 0x8e, 0x73, 0xf9, 0xc9, 0x93, 0x9b, 0xcf, 0x87, 0xf4, 0xf1,
-            0xfe, 0xf5, 0xd8, 0xa6, 0x8d, 0x15, 0x17, 0x8d, 0x62, 0x00, 0x95, 0xf0, 0x19, 0x6c, 0xf8, 0x0b,
-            0x28, 0xdf, 0xe5, 0x54, 0x5c, 0x36, 0xc2, 0x08, 0x1d, 0x62, 0x9a, 0x86, 0x5b, 0xf6, 0x27, 0xf2,
-            0x34, 0x0d, 0xb5, 0x8c, 0x62, 0x00, 0xe3, 0x9e, 0x9d, 0x78, 0xf1, 0x26, 0x29, 0xc3, 0x51, 0x3d,
-            0xc4, 0x83, 0xce, 0xcf, 0xc9, 0x46, 0x47, 0x3b, 0x8a, 0x1a, 0x19, 0xa6, 0x42, 0x72, 0x06, 0xf0,
-            0x9a, 0x1e, 0x4d, 0x0f, 0x0d, 0x92, 0xa5, 0xe1, 0x25, 0xd9, 0x2b, 0xa7, 0x42, 0x42, 0x9f, 0xda,
-            0x8f, 0xda, 0x93, 0xd4, 0xfb, 0xe4, 0x5f, 0x9d, 0x23, 0x57, 0x19, 0x86, 0x9a, 0x22, 0x3b, 0xf5,
-            0xdb, 0x52, 0xde, 0x12, 0x96, 0x83, 0x52, 0x1e, 0x37, 0x3c, 0xd1, 0x7e, 0x75, 0x15, 0xf9, 0x4e,
-            0x98, 0x8d, 0xb3, 0xc1, 0x35, 0x42, 0x83, 0xbc, 0xd8, 0x27, 0xac, 0x25, 0xa9, 0x78, 0x19, 0xc7,
-            0x39, 0x2a, 0x79, 0x7b, 0x22, 0xd4, 0xe2, 0x02, 0x4d, 0x1b, 0x6d, 0x0a, 0x0e, 0x94, 0x1b, 0x3b,
-            0x6a, 0x2f, 0x2a, 0x76, 0x42, 0x6a, 0x83, 0xb4, 0x16, 0x1b, 0x83, 0xbd, 0x75, 0xa7, 0x35, 0xd7,
-            0xbc, 0x86, 0xf2, 0x8b, 0x21, 0xf2, 0x82, 0x76, 0xb2, 0x5f, 0x1e, 0xd8, 0x4a, 0x25, 0x5d, 0x99,
-            0x2a, 0x75, 0x87, 0x02, 0x5b, 0xc5, 0xb3, 0xe0, 0xec, 0x05, 0x3a, 0xc8, 0x69, 0x46, 0x95, 0x94,
-            0x02, 0x02, 0x85, 0x4d, 0xbd, 0x42, 0x1f, 0x07, 0x5a, 0x7d, 0x10, 0x31, 0xd8, 0x43, 0x89, 0xc9,
-            0xfd, 0xcf, 0x66, 0x5f, 0xf6, 0x5e, 0xc5, 0x74, 0xeb, 0x9d, 0x6d, 0x37, 0x0a, 0xf1, 0xe3, 0xfe,
-            0xe3, 0xf9, 0x16, 0x08, 0xec, 0x6b, 0x46, 0xd3, 0xcf, 0x34, 0x89, 0x03, 0x21, 0x44, 0x26, 0x23,
-            0xca, 0xb0, 0x65, 0x26, 0xca, 0xab, 0x1e, 0xd8, 0xb3, 0x02, 0x80, 0x85, 0x05, 0xba, 0x7a, 0xdd,
-            0x3d, 0x9b, 0x00, 0x68, 0x08, 0x05, 0x5a, 0x69, 0x8f, 0xe9, 0x24, 0xce, 0x7a, 0xd4, 0xa3, 0xdd,
-            0x8d, 0xa7, 0xa6, 0xf8, 0xb0, 0xba, 0x3b, 0xdb, 0x4f, 0xaa, 0x6b, 0x04, 0x80, 0x8e, 0x4a, 0x47,
-            0x88, 0x3c, 0x4b, 0x1f, 0x95, 0x68, 0x26, 0x5f, 0x2b, 0x23, 0x6c, 0xee, 0x0a, 0xb6, 0xf6, 0x93,
-            0x64, 0x63, 0x6a, 0x8a, 0xc0, 0x77, 0xe5, 0xc4, 0x09, 0x6c, 0x59, 0x32, 0xff, 0xe9, 0x21, 0xc4,
-            0x70, 0xcf, 0x4c, 0x78, 0x69, 0x47, 0x48, 0x72, 0x00, 0x2a, 0xf7, 0xe3, 0xf0, 0xfc, 0xd3, 0xd7,
-            0x1b, 0x13, 0x88, 0xf8, 0xd7, 0xd7, 0x88, 0xeb, 0x6f, 0x0a, 0xfc, 0xdb, 0x1b, 0x12, 0x00, 0x71,
-            0x6b, 0x99, 0x40, 0x75, 0x5d, 0xf9, 0x26, 0x7d, 0xcb, 0x0e, 0xcf, 0x70, 0xc7, 0xd8, 0x25, 0x92,
-            0xa6, 0x30, 0x8a, 0x8e, 0x82, 0x9e, 0xda, 0x56, 0x19, 0xac, 0xc1, 0xc1, 0x1a, 0x2d, 0xcd, 0x24,
-            0x8f, 0x6c, 0x0f, 0x3e, 0x94, 0x32, 0x8e, 0x5f, 0xa3, 0x61, 0x3c, 0x69, 0x1a, 0xc2, 0x92, 0x82,
-            0x82, 0x89, 0xdc, 0xdf, 0x84, 0x23, 0x2c, 0x92, 0x5c, 0x66, 0x5f, 0x95, 0x86, 0xdb, 0x96, 0xf0,
-            0xbb, 0x94, 0x87, 0xc2, 0x7d, 0x27, 0xea, 0x45, 0x9b, 0x64, 0x91, 0xe7, 0xf6, 0xb5, 0x21, 0x85,
-            0xd0, 0xcd, 0x90, 0xe7, 0x9b, 0x9e, 0xf4, 0x54, 0x85, 0xd3, 0xee, 0xae, 0x35, 0x52, 0x44, 0x34,
-            0x5f, 0x16, 0xf3, 0x9c, 0x79, 0x92, 0x85, 0x65, 0x81, 0x44, 0x91, 0xd7, 0x2e, 0xe0, 0xed, 0x50,
-            0x22, 0x86, 0x29, 0xc9, 0xea, 0xfd, 0xad, 0xc0, 0x5d, 0xb1, 0x94, 0x6f, 0x46, 0x19, 0x6f, 0x5f,
-            0xb8, 0xe3, 0x40, 0xa1, 0x94, 0xa3, 0xe6, 0x61, 0x67, 0xd0, 0x41, 0x3b, 0x90, 0x24, 0x59, 0xa7,
-            0x56, 0x5a, 0xe4, 0xcc, 0x6e, 0x50, 0x5c, 0xb3, 0x13, 0xae, 0x73, 0x69, 0x89, 0x06, 0x9c, 0x21,
-            0x6f, 0x38, 0x07, 0x76, 0x75, 0xa9, 0x94, 0x30, 0x53, 0x93, 0x65, 0x73, 0x95, 0x69, 0xbd, 0xba,
-            0x05, 0x19, 0x44, 0x2d, 0x19, 0xe7, 0xc5, 0xaa, 0x76, 0xa4, 0x3b, 0x33, 0xed, 0x98, 0xe9, 0x1d,
-            0xc3, 0xe3, 0xa2, 0x88, 0xaf, 0x4c, 0x78, 0x26, 0xc0, 0x7d, 0xe6, 0x89, 0x95, 0x7f, 0x71, 0x53,
-            0xe3, 0x34, 0xa5, 0x3f, 0xb3, 0x78, 0x9b, 0xcc, 0x26, 0x2a, 0xbd, 0x9a, 0xe4, 0xd6, 0x94, 0x2d,
-            0x1e, 0x66, 0xb6, 0x39, 0xb3, 0xe5, 0xed, 0xf2, 0xb0, 0xa9, 0x25, 0x15, 0x9f, 0x42, 0x2f, 0xaa,
-            0x0d, 0x7b, 0xe6, 0x6c, 0xec, 0xff, 0x50, 0x0f, 0xfe, 0x78, 0x65, 0x91, 0x55, 0x41, 0xc0, 0x45,
-            0xa2, 0x04, 0xe8, 0xa0, 0x19, 0xd4, 0x5e, 0xae, 0x88, 0x19, 0x14, 0x78, 0x97, 0x14, 0xd0, 0x4d,
-            0xab, 0xba, 0x16, 0x7a, 0x5e, 0x16, 0x08, 0x53, 0xff, 0x5c, 0xab, 0x15, 0xca, 0x95, 0xee, 0xbc,
-            0x30, 0x05, 0x47, 0xb6, 0x61, 0xb0, 0xf6, 0xbb, 0x53, 0x40, 0x8d, 0x9b, 0x98, 0x06, 0xf4, 0x7b,
-            0xb3, 0x2b, 0xcc, 0x83, 0x2f, 0x0b, 0x43, 0x48, 0x6e, 0x42, 0x80, 0x29, 0x71, 0xd7, 0x4b, 0x2f,
-            0x7c, 0x72, 0xc3, 0x11, 0xa6, 0xb0, 0xe3, 0x03, 0xf8, 0x9f, 0x64, 0x57, 0x69, 0x3f, 0x69, 0xaf,
-            0x92, 0xef, 0xb7, 0xaf, 0x2f, 0xe2, 0x1c, 0xfb, 0xf2, 0x1f, 0x4d, 0x76, 0x21, 0xab, 0x5b, 0x2c,
-            0x47, 0x66, 0x3f, 0x73, 0xe1, 0xf2, 0x2a, 0x48, 0xd8, 0xfa, 0x2f, 0xc7, 0xdb, 0x40, 0xcd, 0x92,
-            0x35, 0xb6, 0xae, 0x44, 0xa9, 0xfc, 0x3b, 0xb1, 0x81, 0x8a, 0x03, 0xab, 0xd0, 0xa0, 0x1c, 0x75,
-            0x54, 0x45, 0x38, 0xa7, 0x3a, 0x36, 0x02, 0x51, 0x22, 0xb5, 0xf6, 0x86, 0x9b, 0xd1, 0xd8, 0xeb,
-            0x80, 0xca, 0xf3, 0x66, 0x91, 0xae, 0x57, 0x27, 0x2a, 0xbb, 0x3f, 0x4e, 0x57, 0xff, 0x10, 0x2e,
-            0x08, 0x0b, 0xd5, 0x3a, 0x7c, 0x21, 0x47, 0x6d, 0xf9, 0xc8, 0xb6, 0xda, 0x43, 0xd1, 0xf0, 0xc7,
-            0xde, 0x54, 0x77, 0x15, 0xa6, 0xfc, 0x15, 0x2e, 0x7d, 0xe7, 0x41, 0x2b, 0x5c, 0x54, 0x1b, 0x7e,
-            0x64, 0xf5, 0xac, 0xfd, 0x93, 0x1f, 0xa6, 0x4f, 0xbe, 0x42, 0xf4, 0xcd, 0x34, 0x21, 0x92, 0x9f,
-            0x88, 0xbd, 0xac, 0xfe, 0x85, 0x9d, 0x18, 0x18, 0x55, 0x4b, 0x73, 0xcf, 0xf6, 0x1d, 0x6f, 0x54,
-            0xd2, 0xcb, 0x84, 0x25, 0x6e, 0x57, 0xae, 0x31, 0x6a, 0x73, 0xf2, 0x1c, 0x8a, 0x97, 0x2c, 0x4a,
-            0x8e, 0x01, 0x8b, 0xda, 0x3d, 0xf5, 0x4e, 0xd3, 0x88, 0x3c, 0xd2, 0xe8, 0x3f, 0xb8, 0x13, 0x5f,
-            0xdf, 0xa4, 0x9a, 0x4c, 0x9c, 0x63, 0x67, 0x31, 0x58, 0xbc, 0x5f, 0x4d, 0x42, 0x90, 0x6f, 0xff,
-            0x8f, 0x18, 0x1c, 0x8d, 0x44, 0x15, 0x27, 0x11, 0x32, 0x01, 0x25, 0x54, 0xb1, 0x35, 0x82, 0xb1,
-            0xaf, 0xce, 0x50, 0xe3, 0x9b, 0x19, 0x5b, 0x92, 0x99, 0x7f, 0x7e, 0xcf, 0x47, 0x90, 0x29, 0x26,
-            0x3e, 0xfe, 0xdf, 0xbb, 0x74, 0xca, 0x3a, 0x75, 0xf1, 0x0f, 0xff, 0x30, 0x27, 0xc1, 0x2a, 0xa3,
-            0xce, 0xe9, 0xa6, 0x8a, 0x37, 0x9e, 0xc5, 0x77, 0x70, 0xa7, 0x17, 0x3a, 0x56, 0x94, 0x36, 0x4e,
-            0x73, 0xc2, 0xd6, 0x25, 0xab, 0x01, 0x16, 0x58, 0x73, 0x9a, 0x35, 0x4a, 0x83, 0x31, 0xa4, 0x11,
-            0x0a, 0x4e, 0x8b, 0x33, 0xcf, 0x10, 0x7c, 0xb7, 0x2c, 0x74, 0x96, 0x68, 0x37, 0x99, 0xc0, 0xb9,
-            0xd1, 0x9c, 0x6e, 0x92, 0xb5, 0x0b, 0x5f, 0xf2, 0x88, 0xa0, 0x1a, 0xbf, 0x87, 0x10, 0xaf, 0x18,
-            0x02, 0xe6, 0x24, 0x07, 0x8e, 0xcf, 0x38, 0xc0, 0x0d, 0x7d, 0xa2, 0x22, 0xe2, 0x5a, 0xbc, 0x4d,
-            0x7b, 0xca, 0xaf, 0xc0, 0xf8, 0x45, 0x9c, 0x20, 0x7a, 0xae, 0x44, 0xca, 0x68, 0xbe, 0x8e, 0x98,
-            0xa1, 0x18, 0x90, 0x72, 0x32, 0x83, 0xf1, 0x88, 0xf0, 0x59, 0xe7, 0x7e, 0x50, 0x4b, 0x50, 0x98,
-            0x6a, 0x2b, 0x65, 0x8c, 0x8c, 0x2a, 0xad, 0x6e, 0x58, 0xb6, 0x20, 0xee, 0x8d, 0x94, 0xdf, 0x04,
-            0x21, 0xe2, 0x19, 0xba, 0x76, 0x43, 0x19, 0xb9, 0x10, 0xef, 0xb5, 0x14, 0xad, 0x23, 0x40, 0xfd,
-            0x4f, 0xbf, 0xbf, 0xd0, 0xbf, 0xd2, 0x17, 0x00, 0x17, 0x7a, 0x7a, 0x4c, 0x88, 0x15, 0x2d, 0x2a,
-            0xa5, 0xf0, 0xba, 0x95, 0x28, 0x1d, 0x65, 0x03, 0xad, 0x3d, 0x01, 0xe4, 0xde, 0x64, 0xf6, 0x82,
-            0x02, 0xee, 0xa3, 0x26, 0x64, 0xca, 0x41, 0xa4, 0x80, 0x1c, 0x12, 0x1f, 0xb9, 0xeb, 0x8d, 0xf7,
-            0x6d, 0x90, 0xc6, 0xcb, 0x9d, 0xd0, 0x93, 0x9d, 0x0e, 0xc0, 0x51, 0x18, 0x76, 0x76, 0x03, 0x4d,
-            0xa5, 0x83, 0x31, 0xfa, 0xa2, 0xed, 0xd4, 0xa0, 0x78, 0x48, 0x9d, 0xc8, 0xc1, 0x1c, 0xed, 0x89,
-            0x4c, 0x6f, 0x75, 0x57, 0x27, 0x06, 0x26, 0xf4, 0xd0, 0x91, 0x82, 0x40, 0x06, 0xf6, 0xdb, 0x38,
-            0x1d, 0xbc, 0x35, 0x74, 0x0e, 0x5d, 0x02, 0xc8, 0x44, 0xab, 0x2c, 0xe2, 0x88, 0x7d, 0xb3, 0xa8,
-            0xe3, 0x32, 0xe1, 0x00, 0xb5, 0x79, 0x72, 0xfa, 0x0b, 0x7b, 0xe8, 0x8e, 0xe6, 0x5e, 0x5a, 0x30,
-            0xfa, 0xce, 0x14, 0x27, 0xbe, 0x7f, 0xcc, 0x78, 0x1b, 0x88, 0x51, 0x2c, 0x5e, 0x19, 0x73, 0xa4,
-            0xc4, 0xe4, 0x3b, 0x90, 0xe2, 0xff, 0x84, 0x09, 0xec, 0x82, 0x2c, 0xe8, 0x03, 0x06, 0xa0, 0x83,
-            0x4f, 0x9d, 0x62, 0x6b, 0x52, 0x6d, 0x5b, 0x16, 0xfd, 0xa1, 0x0c, 0xb2, 0xb6, 0xba, 0x6e, 0x1e,
-            0xd6, 0xdc, 0x75, 0x7a, 0x12, 0x0e, 0xbd, 0x02, 0xc9, 0x63, 0x64, 0xb6, 0x83, 0x7e, 0xfc, 0x2b,
-            0x41, 0xa8, 0x68, 0x40, 0xbf, 0x8d, 0x9d, 0x6f, 0xd7, 0x45, 0x75, 0x38, 0x9c, 0x61, 0x2d, 0x6d,
-            0x32, 0x3b, 0x80, 0x8e, 0xaf, 0x82, 0xaa, 0x39, 0x5d, 0x3d, 0x3a, 0x66, 0x04, 0x96, 0xdd, 0x09,
-            0x15, 0x07, 0xc6, 0x0d, 0x1a, 0x67, 0x2e, 0xdb, 0x38, 0x5b, 0xf7, 0x61, 0x92, 0xba, 0x04, 0x0e,
-            0xe9, 0xba, 0xfb, 0x17, 0x1e, 0x2e, 0x53, 0xd5, 0x55, 0xc1, 0xa6, 0x12, 0x83, 0x0d, 0x83, 0x64,
-            0x70, 0x3f, 0x16, 0x36, 0x01, 0x06, 0x7e, 0x43, 0x9e, 0x9a, 0xfa, 0x7b, 0x8e, 0x0d, 0xa8, 0xe2,
-            0x71, 0x3d, 0xff, 0x96, 0xf4, 0xbe, 0xbd, 0x6d, 0x75, 0xb0, 0x57, 0x37, 0x3d, 0x12, 0x96, 0xe2,
-            0x7e, 0xe0, 0x8d, 0x43, 0xd8, 0x7a, 0x95, 0x39, 0x67, 0x5f, 0x4b, 0x66, 0xf2, 0x2c, 0xec, 0x73,
-            0x1a, 0x01, 0x1d, 0xef, 0xa2, 0xab, 0x96, 0x54, 0x0b, 0xb2, 0xb8, 0x40, 0x26, 0x65, 0xd0, 0x69,
-            0x01, 0xc1, 0x03, 0xf5, 0x63, 0x2f, 0x84, 0xc2, 0x31, 0xb6, 0x04, 0x6b, 0xc9, 0x64, 0xae, 0xd5,
-            0xf7, 0x74, 0x1d, 0x6e, 0xe2, 0x94, 0x85, 0x46, 0xc0, 0xe5, 0xe2, 0xb3, 0xf1, 0x78, 0xce, 0x77,
-            0x7a, 0xad, 0x95, 0x8d, 0xb8, 0x30, 0xfd, 0xa2, 0xfd, 0x68, 0x4e, 0x85, 0xac, 0x7c, 0x9f, 0x77,
-            0x9f, 0x05, 0x44, 0x4c, 0xb2, 0x5c, 0x35, 0x13, 0xe9, 0x16, 0xe3, 0xbc, 0x11, 0x1f, 0x58, 0x8b,
-            0x60, 0x8a, 0x69, 0x39, 0xf0, 0x3e, 0xb4, 0x10, 0xe5, 0x1c, 0x3e, 0x3c, 0x24, 0x10, 0xd8, 0xa5,
-            0x4e, 0x8a, 0x78, 0xd4, 0x1d, 0x71, 0x44, 0x21, 0x8f, 0x64, 0xf8, 0xe0, 0x1b, 0xcf, 0xeb, 0xf9,
-            0x03, 0xea, 0x40, 0xae, 0xbb, 0x26, 0x28, 0xd5, 0xfd, 0x8c, 0x0a, 0x6e, 0x10, 0x24, 0x91, 0x83,
-            0xb7, 0x08, 0x84, 0x06, 0x28, 0xe6, 0xa5, 0xe1, 0x85, 0x37, 0x30, 0x19, 0x0a, 0x68, 0x8c, 0x64,
-            0x0c, 0x64, 0xf4, 0xab, 0xbb, 0x44, 0xe1, 0x42, 0x85, 0xb5, 0x64, 0x19, 0x8f, 0xb9, 0x16, 0x3b,
-            0xa1, 0x05, 0x06, 0x7b, 0xd8, 0x2e, 0xe5, 0x2f, 0xd9, 0x39, 0xb5, 0xa1, 0x3a, 0x40, 0x53, 0xe7,
-            0x96, 0xe6, 0x09, 0xc6, 0x1e, 0xd3, 0x49, 0x41, 0xa6, 0xf3, 0xe1, 0xc2, 0xde, 0xe2, 0x0a, 0x6d,
-            0x94, 0x8e, 0xf9, 0x14, 0x76, 0x65, 0x5a, 0x03, 0x0b, 0x2a, 0x6b, 0x7a, 0x21, 0xf6, 0xef, 0x7c,
-            0xf5, 0x88, 0xfe, 0x95, 0x64, 0x9e, 0x49, 0x1a, 0xc7, 0x61, 0x29, 0x48, 0xbd, 0x48, 0xab, 0x76,
-            0xae, 0xf5, 0x70, 0x9a, 0xd7, 0x80, 0x54, 0x06, 0xf6, 0x7c, 0xb7, 0xb8, 0x96, 0x32, 0x6e, 0x44,
-            0x31, 0x91, 0xd5, 0xdb, 0x8b, 0x65, 0xea, 0x50, 0xa9, 0x49, 0x76, 0x02, 0x21, 0xa1, 0xa5, 0x57,
-            0xdc, 0xf3, 0x55, 0x24, 0x48, 0x8e, 0x2e, 0x0d, 0x67, 0xbc, 0x1a, 0x2c, 0xcf, 0x4d, 0xcc, 0xfa,
-            0x8d, 0x32, 0x63, 0x21, 0x98, 0xff, 0x79, 0xd4, 0xe3, 0xc4, 0xd2, 0x22, 0x1f, 0xae, 0x7b, 0x0d,
-            0x12, 0x00, 0x7d, 0xf8, 0x51, 0x14, 0x1b, 0x7e, 0x59, 0x0c, 0x7e, 0x1c, 0xc7, 0xa2, 0xe8, 0x4c,
-            0xf1, 0xea, 0xe7, 0xdf, 0x9c, 0x23, 0xf1, 0xd3, 0xf8, 0x34, 0x44, 0x93, 0x7d, 0x7b, 0x4c, 0x54,
-            0x3f, 0xdf, 0xf6, 0xc9, 0xe4, 0x1f, 0xe5, 0xf8, 0x0b, 0x09, 0x70, 0xe7, 0x08, 0x0a, 0xa2, 0xe7,
-            0xba, 0xb4, 0xbe, 0x5c, 0xa7, 0x77, 0x31, 0x65, 0x27, 0xa1, 0x94, 0x76, 0x31, 0x95, 0xbd, 0x4f,
-            0x51, 0xec, 0xcd, 0x2a, 0x1c, 0xcb, 0x82, 0x35, 0x98, 0x85, 0xe5, 0x70, 0xef, 0xb2, 0xe1, 0xe7,
-            0x51, 0xb0, 0x09, 0x36, 0x34, 0xa6, 0xf4, 0xff, 0x24, 0xa1, 0xdf, 0xc6, 0x33, 0x74, 0x31, 0x26,
-            0xd9, 0x3a, 0xb8, 0xaa, 0x48, 0x76, 0x6a, 0x65, 0x1f, 0x56, 0x86, 0xc6, 0x6f, 0xac, 0x9c, 0x36,
-            0xed, 0xcf, 0xf5, 0x7c, 0xe1, 0x16, 0x9d, 0x41, 0x42, 0x08, 0x06, 0x1b, 0xed, 0xb1, 0x80, 0x27,
-            0xa5, 0xf7, 0xad, 0x06, 0x24, 0x2a, 0xa4, 0x05, 0x1e, 0x0e, 0x9b, 0x9a, 0xc7, 0x3b, 0xef, 0xec,
-            0xc5, 0xab, 0x3d, 0xb2, 0x80, 0x1e, 0xc8, 0x72, 0xca, 0xf5, 0x0e, 0xfc, 0xd8, 0x29, 0x74, 0x00,
-            0x90, 0x3a, 0xf0, 0x7a, 0xe3, 0x1f, 0x66, 0x15, 0x89, 0xfa, 0xf1, 0x17, 0x1c, 0xf2, 0xd0, 0x8a,
-            0x10, 0xe6, 0x96, 0xd8, 0x0a, 0xc9, 0x72, 0x8f, 0x53, 0x40, 0x80, 0xd9, 0x31, 0x10, 0xb3, 0x92,
-            0x43, 0x63, 0xe0, 0x27, 0xf2, 0xd6, 0x62, 0x04, 0x08, 0xbf, 0x91, 0xb2, 0xfc, 0x6e, 0x09, 0xfe,
-            0x94, 0xcb, 0x15, 0x8d, 0x23, 0xca, 0x09, 0x9c, 0x4e, 0xc8, 0xfd, 0x94, 0xea, 0x53, 0x66, 0x1e,
-            0xc0, 0x71, 0xe2, 0xe9, 0x50, 0x42, 0x90, 0xb5, 0xc5, 0x0c, 0xbe, 0x69, 0x4b, 0x53, 0xa4, 0x52,
-            0x2a, 0xf4, 0xc4, 0x1c, 0x90, 0xca, 0x2d, 0x8f, 0xa1, 0x30, 0x91, 0x24, 0xa8, 0x2c, 0x35, 0x84,
-            0xd5, 0xea, 0x8e, 0x85, 0x55, 0xbb, 0xbe, 0x33, 0xf0, 0x5a, 0x28, 0x0e, 0x32, 0x7a, 0xbf, 0x6e,
-            0x9f, 0xfa, 0x9b, 0x0c, 0x23, 0x6d, 0x6d, 0x3c, 0xbd, 0xe7, 0x40, 0xec, 0x56, 0xff, 0x13, 0x53,
-            0x3e, 0xdb, 0xdc, 0x9f, 0xe1, 0x61, 0xa7, 0x24, 0x2a, 0x56, 0x74, 0xf6, 0xee, 0x3f, 0x2b, 0x1c,
-            0xb0, 0x21, 0x7e, 0xac, 0xf0, 0xc9, 0xf9, 0x80, 0x16, 0xa4, 0x65, 0xf7, 0xe7, 0x56, 0x49, 0xe6,
-            0x40, 0x6a, 0x4a, 0x69, 0x7e, 0x69, 0x04, 0x92, 0x9a, 0x4c, 0xbe, 0x03, 0x5d, 0x2a, 0x3e, 0x9c,
-            0x30, 0x44, 0x32, 0xf2, 0x62, 0xbf, 0xdb, 0x99, 0x4e, 0x8b, 0xbb, 0xbe, 0xb7, 0x99, 0x7f, 0xdd,
-            0x00, 0xd6, 0x11, 0x24, 0x3d, 0x6f, 0x9a, 0xb7, 0xbc, 0xa6, 0x00, 0x14, 0x13, 0x01, 0xeb, 0xa0,
-            0xd3, 0x4f, 0x14, 0xc1, 0xd4, 0x54, 0xa7, 0x47, 0x07, 0x14, 0xbc, 0xe1, 0x01, 0xad, 0x55, 0x20,
-            0x1d, 0xbb, 0x9f, 0x53, 0xa2, 0xf6, 0x8d, 0xc7, 0x17, 0x61, 0x39, 0x47, 0x88, 0x4b, 0xa5, 0x78,
-            0x03, 0x4b, 0xb7, 0x04, 0xe1, 0xc8, 0x3d, 0x31, 0x0e, 0xea, 0x8a, 0xd9, 0x6e, 0x55, 0x96, 0x07,
-            0x2b, 0x31, 0xf6, 0x79, 0x16, 0xf1, 0x95, 0xc0, 0x5d, 0xcb, 0xa2, 0x38, 0x35, 0x3d, 0x1a, 0x49,
-            0xa1, 0xc9, 0xa3, 0x7f, 0x4b, 0xc5, 0x92, 0x8f, 0xb0, 0xe7, 0xe2, 0x8e, 0xa6, 0x02, 0xc5, 0x4a,
-            0xa2, 0xa8, 0x17, 0x32, 0xc8, 0xd1, 0x93, 0xc5, 0xdf, 0xe2, 0x0a, 0x04, 0x3a, 0xf2, 0x54, 0x63,
-            0x54, 0xaa, 0x02, 0x72, 0xca, 0x89, 0x22, 0x96, 0x93, 0x9d, 0x99, 0x8b, 0x93, 0xfc, 0x9a, 0xb2,
-            0x79, 0x98, 0x27, 0x31, 0x71, 0x4d, 0x84, 0x84, 0x77, 0xc1, 0x8d, 0x26, 0x15, 0xfc, 0x29, 0xfd,
-            0xcf, 0x04, 0x53, 0xe2, 0x30, 0x05, 0xb3, 0x75, 0x56, 0x74, 0xc9, 0x59, 0xd2, 0x42, 0x46, 0x8c,
-            0x67, 0x06, 0xfb, 0x62, 0xbd, 0x6a, 0xb5, 0x72, 0xb7, 0x24, 0x9e, 0x16, 0x81, 0x87, 0x1f, 0x4d,
-            0x4c, 0x33, 0x64, 0xb9, 0x55, 0xb9, 0xee, 0xd3, 0x2f, 0x42, 0x80, 0xb3, 0x9e, 0x6b, 0xc6, 0x5f,
-            0x31, 0x7f, 0x0d, 0xdf, 0x4e, 0xda, 0xc8, 0x22, 0x10, 0x40, 0xf4, 0x48, 0x6c, 0x25, 0xea, 0xf2,
-            0x57, 0x98, 0x71, 0x91, 0x6d, 0x7f, 0xe8, 0x0d, 0x20, 0x44, 0x63, 0x00, 0x75, 0xc2, 0xf8, 0xa0,
-            0x96, 0xa7, 0xef, 0xf7, 0x94, 0xc8, 0xa3, 0x51, 0x0d, 0xab, 0x0e, 0x09, 0xe6, 0xb6, 0xd7, 0x58,
-            0xf0, 0xa1, 0x21, 0x7a, 0x38, 0x27, 0x2b, 0xc0, 0x96, 0x1a, 0xbe, 0x88, 0xe7, 0xb7, 0x61, 0x22,
-            0x62, 0x83, 0x4d, 0xe7, 0xf0, 0x2a, 0xc7, 0x94, 0x8c, 0x5a, 0x49, 0xd4, 0xd7, 0x5f, 0xa2, 0xbe,
-            0xcd, 0x63, 0xd9, 0x18, 0xa5, 0xee, 0x85, 0xe2, 0x3b, 0x73, 0x4b, 0xa3, 0xce, 0x05, 0x90, 0xe5,
-            0x06, 0xd2, 0xb7, 0x49, 0xc2, 0x62, 0xca, 0x69, 0xad, 0x10, 0x11, 0x7c, 0x7b, 0x63, 0x93, 0xd7,
-            0x7a, 0x05, 0xf9, 0xbe, 0xec, 0x0e, 0xe9, 0x44, 0x8d, 0x67, 0x9a, 0x64, 0x85, 0xda, 0x37, 0x03,
-            0xce, 0x28, 0x10, 0x31, 0x34, 0x4c, 0x83, 0xb5, 0xa8, 0xca, 0x9e, 0x1a, 0x16, 0x56, 0x12, 0x0b,
-            0x1a, 0x21, 0xfd, 0x1e, 0xad, 0x5c, 0xf1, 0x0c, 0xc6, 0x82, 0x01, 0xb6, 0x47, 0x23, 0xa8, 0x2b,
-            0x2f, 0xf0, 0x4a, 0x4b, 0xec, 0x71, 0xef, 0x6b, 0x53, 0xec, 0xd0, 0xe1, 0x3f, 0xe3, 0xce, 0xbf,
-            0x42, 0xf4, 0x5f, 0x3a, 0x91, 0x47, 0x5f, 0x63, 0x8b, 0xb4, 0x5a, 0xe8, 0xe2, 0x19, 0xc1, 0x54,
-            0x1c, 0x00, 0x3a, 0xf4, 0x98, 0xd9, 0x2d, 0x78, 0x00, 0x6a, 0xbf, 0x5d, 0x02, 0xe1, 0x85, 0x12,
-            0xcb, 0x55, 0x98, 0xb0, 0x86, 0x6b, 0x77, 0xd1, 0xbf, 0xca, 0x1d, 0x77, 0x21, 0x2f, 0xe4, 0x09,
-            0xa0, 0x96, 0x0c, 0xaf, 0x1e, 0xbe, 0x79, 0xdb, 0x45, 0xc5, 0xd8, 0x52, 0xa5, 0x15, 0x7d, 0xbd,
-            0xd6, 0x0e, 0xa9, 0x22, 0xf2, 0xb9, 0x64, 0x7e, 0xb2, 0x6a, 0x1a, 0x75, 0x6d, 0x3a, 0x1f, 0x63,
-            0xdc, 0x85, 0x48, 0x9b, 0x76, 0x4d, 0x4d, 0x9a, 0x50, 0xe2, 0x40, 0x28, 0x2b, 0xc8, 0x0f, 0x4f,
-            0x64, 0x86, 0xfb, 0xb8, 0xc4, 0x8a, 0x26, 0x52, 0xb8, 0x06, 0x51, 0x04, 0x54, 0x83, 0xc7, 0xc2,
-            0x0c, 0x82, 0xc7, 0x4c, 0x5e, 0x8a, 0x7a, 0xc5, 0x00, 0x8c, 0xd8, 0xf5, 0x0f, 0xef, 0x6f, 0x50,
-            0x3d, 0xcf, 0x41, 0x81, 0xc7, 0x38, 0xd0, 0x48, 0x20, 0x07, 0xe2, 0x74, 0xc3, 0xaf, 0x01, 0x91,
-            0xbc, 0xd2, 0x0d, 0xcb, 0x0e, 0x80, 0x1b, 0x40, 0x23, 0x08, 0x67, 0x1a, 0x74, 0x50, 0x0c, 0xed,
-            0xd6, 0x28, 0x40, 0xef, 0x16, 0xf1, 0x50, 0xc2, 0xdb, 0xcb, 0x02, 0xe4, 0x68, 0x2b, 0xe1, 0xfb,
-            0x9c, 0x26, 0x13, 0x60, 0x21, 0x14, 0x74, 0xe6, 0x32, 0xf2, 0x68, 0xda, 0xc2, 0xe7, 0xa4, 0x52,
-            0x87, 0x6d, 0xa4, 0xd9, 0x53, 0xbb, 0x32, 0x2a, 0x6d, 0xb6, 0x35, 0xd2, 0xb3, 0xb4, 0x5f, 0x7d,
-            0x72, 0x4b, 0xc0, 0xc6, 0x59, 0xc0, 0xc0, 0x7c, 0xe0, 0xa1, 0x72, 0xe0, 0x62, 0x12, 0xaa, 0x9f,
-            0xad, 0x3a, 0x61, 0xc8, 0xb2, 0xc3, 0x35, 0xa8, 0xa9, 0x47, 0xa8, 0xae, 0x0c, 0x98, 0x07, 0x5e,
-            0x95, 0xf1, 0xfe, 0x12, 0x29, 0xf0, 0xe8, 0xee, 0x7b, 0xbc, 0x14, 0xc0, 0xe2, 0xe2, 0xbf, 0x53,
-            0x35, 0x7c, 0x56, 0x89, 0xd6, 0xfb, 0xb7, 0x52, 0xa2, 0xb3, 0x7f, 0x0e, 0x21, 0xf2, 0xcc, 0x5a,
-            0xf4, 0x8b, 0x65, 0xfc, 0x52, 0x8c, 0x87, 0x69, 0x43, 0xc0, 0x54, 0x58, 0x23, 0x10, 0xca, 0x76,
-            0x99, 0xe8, 0x33, 0xd2, 0x37, 0x72, 0xb1, 0x22, 0x89, 0x3d, 0x47, 0xe3, 0x74, 0x9a, 0x76, 0x31,
-            0x8e, 0x64, 0x19, 0x1c, 0x6a, 0x69, 0x0e, 0x3e, 0x41, 0x5a, 0xf6, 0x0f, 0x2a, 0xea, 0x84, 0x16,
-            0x28, 0x29, 0xfd, 0x70, 0xa0, 0xd0, 0x99, 0x4c, 0x94, 0x55, 0x85, 0x87, 0xf9, 0x81, 0xd4, 0xc8,
-            0xd7, 0x26, 0x48, 0xaa, 0xf1, 0x26, 0x92, 0x8d, 0x12, 0x5a, 0x9e, 0x0a, 0x94, 0x95, 0x20, 0x0f,
-            0x05, 0xeb, 0xa6, 0x1e, 0x8b, 0xad, 0x7c, 0x69, 0x3a, 0x51, 0x78, 0x93, 0x4d, 0x49, 0xe1, 0x60,
-            0x4b, 0xc8, 0x11, 0x7f, 0xb1, 0x9f, 0x51, 0x85, 0x06, 0xe2, 0x8d, 0x39, 0xd6, 0x4e, 0x82, 0x7b,
-            0xea, 0xb6, 0xb6, 0x4f, 0xc9, 0x3c, 0x46, 0x2c, 0x62, 0x51, 0x23, 0x45, 0xc8, 0xb4, 0x1d, 0x41,
-            0x69, 0x40, 0xf8, 0x6c, 0xe0, 0x09, 0xbb, 0xd1, 0xd1, 0xe4, 0xbb, 0x49, 0x60, 0xd7, 0x53, 0x24,
-            0x60, 0x92, 0xa1, 0xa0, 0xd9, 0x49, 0x00, 0x60, 0x6e, 0x21, 0x75, 0x68, 0x9d, 0x29, 0xa4, 0x18,
-            0x73, 0xe0, 0xb9, 0x2e, 0x16, 0x3f, 0x52, 0x7e, 0xf8, 0xb0, 0x0f, 0x98, 0x6d, 0xe0, 0x8f, 0xdf,
-            0x4d, 0x2c, 0x4e, 0x00, 0xe3, 0xd5, 0x2b, 0x91, 0xe0, 0xd8, 0x77, 0x1c, 0x06, 0x1d, 0x5f, 0xf5,
-            0x53, 0x04, 0x2f, 0x27, 0x53, 0x79, 0xbd, 0x37, 0x18, 0x7b, 0xab, 0x03, 0xba, 0x9e, 0x6a, 0x50,
-            0xdf, 0x39, 0x51, 0x19, 0xec, 0x58, 0x24, 0x21, 0xa0, 0x64, 0xf3, 0x02, 0x42, 0x1e, 0x69, 0x80,
-            0x06, 0x8b, 0x26, 0x2d, 0x5d, 0xc7, 0x81, 0x4b, 0x7c, 0x51, 0x6a, 0x1d, 0x51, 0x1f, 0x8d, 0x87,
-            0x98, 0xd9, 0x24, 0xe9, 0x7a, 0xe9, 0x04, 0xfd, 0x52, 0x32, 0xfe, 0x8a, 0xbe, 0x54, 0xd5, 0xe3,
-            0x19, 0x89, 0x23, 0x5c, 0xac, 0x18, 0x17, 0x1b, 0xa2, 0x3a, 0x6a, 0x7a, 0x7c, 0x30, 0x74, 0xc1,
-            0x50, 0x07, 0xe1, 0x9d, 0xea, 0x32, 0x55, 0xec, 0xbd, 0x24, 0xb8, 0x34, 0xa9, 0x96, 0x28, 0xfd,
-            0xd2, 0x9e, 0x12, 0x6b, 0x79, 0x67, 0x91, 0x3f, 0xd7, 0x1a, 0xde, 0x4d, 0x5c, 0x1f, 0x33, 0x24,
-            0x22, 0xcb, 0xee, 0x66, 0xdd, 0x2a, 0xc1, 0x1f, 0x43, 0x30, 0xe2, 0x16, 0x4c, 0xb0, 0x32, 0x35,
-            0x83, 0x06, 0x20, 0xa3, 0xe0, 0x52, 0x55, 0xe9, 0x9b, 0xaa, 0x00, 0x33, 0x1b, 0xd8, 0xd7, 0x72,
-            0xb4, 0xa8, 0x62, 0xdf, 0x01, 0x49, 0xc8, 0xe7, 0xc5, 0x49, 0xae, 0xeb, 0xe2, 0x7f, 0xad, 0x59,
-            0x5c, 0x24, 0xa5, 0x3a, 0x73, 0x88, 0x57, 0xae, 0x58, 0x01, 0x34, 0x16, 0x7d, 0xed, 0xb5, 0x8a,
-            0xc0, 0x68, 0x4d, 0xf2, 0xa7, 0x42, 0x33, 0x55, 0x45, 0xa2, 0x03, 0xac, 0xbd, 0x08, 0xbf, 0xd9,
-            0xf3, 0xbe, 0x7a, 0xe1, 0xc5, 0xe8, 0xfd, 0x5e, 0x01, 0x54, 0x43, 0xbf, 0xdc, 0x64, 0x3a, 0xe3,
-            0xd7, 0x12, 0x6d, 0x69, 0x54, 0x06, 0x46, 0x17, 0x6c, 0x9d, 0xba, 0x97, 0xd3, 0xd0, 0x91, 0x62,
-            0x43, 0x57, 0x5a, 0x29, 0x8b, 0x7a, 0x4b, 0xae, 0xc7, 0xd2, 0xa3, 0xef, 0x6f, 0xd7, 0xe0, 0x13,
-            0xc3, 0x64, 0x43, 0xec, 0x0f, 0x2b, 0xe4, 0x17, 0x82, 0xbd, 0xa9, 0xaa, 0x4d, 0x0d, 0x6a, 0x2c,
-            0x9b, 0x29, 0x2a, 0x06, 0x06, 0x34, 0x7b, 0x0f, 0x35, 0x6f, 0xe2, 0xe0, 0x94, 0x12, 0xed, 0xf9,
-            0xb0, 0x22, 0x0e, 0x0f, 0x4b, 0x1d, 0x17, 0xa7, 0xd0, 0x1d, 0x93, 0xa8, 0x16, 0xbe, 0x94, 0xc6,
-            0x48, 0x54, 0x1d, 0x28, 0xd4, 0x95, 0x98, 0xc9, 0xc6, 0x19, 0xc9, 0x52, 0x0a, 0x04, 0x28, 0x91,
-            0xa5, 0xe7, 0x62, 0x61, 0x2e, 0x20, 0x87, 0x10, 0xcf, 0x1c, 0xb8, 0x6d, 0x2a, 0x98, 0xd2, 0xfd,
-            0x71, 0x80, 0xa0, 0xcf, 0xab, 0xe4, 0x80, 0xe6, 0x7d, 0xb8, 0x34, 0x72, 0x4f, 0xd1, 0x30, 0xa6,
-            0x16, 0x68, 0x57, 0x20, 0x4b, 0x75, 0x0a, 0xb1, 0xde, 0x68, 0xbb, 0xe0, 0xd3, 0xe9, 0x7b, 0x93,
-            0x7e, 0x20, 0x61, 0x28, 0x21, 0x7b, 0x10, 0xee, 0x1b, 0xb7, 0x50, 0x9d, 0x09, 0x66, 0x36, 0xa6,
-            0xdd, 0xf0, 0xd7, 0xea, 0x92, 0x1a, 0x97, 0xc5, 0x33, 0xe8, 0x11, 0xc1, 0x11, 0x01, 0xa5, 0xe7,
-            0x1a, 0x6a, 0xcf, 0x58, 0x51, 0x0f, 0x3f, 0x74, 0x11, 0xda, 0xc8, 0xbb, 0xa3, 0xbe, 0x8d, 0x5d,
-            0xa7, 0xd7, 0xe9, 0xc7, 0x3b, 0xf2, 0x3d, 0x07, 0x04, 0x5f, 0x08, 0xb2, 0x83, 0x5b, 0xf0, 0xbc,
-            0x2d, 0x60, 0x8e, 0x7d, 0xe6, 0xe1, 0xdf, 0xdf, 0xb6, 0x0e, 0x52, 0xee, 0x2e, 0xf6, 0x51, 0xdc,
-            0x2c, 0x9e, 0x1b, 0x84, 0x95, 0x00, 0xd0, 0x18, 0x07, 0x02, 0xf2, 0x43, 0x1c, 0x24, 0x7d, 0xfc,
-            0x63, 0x6a, 0x5b, 0x4c, 0xe9, 0x4e, 0x1d, 0xca, 0xd3, 0xe0, 0x0f, 0x89, 0xb3, 0x2a, 0x41, 0x62,
-            0x23, 0x64, 0xba, 0x54, 0xef, 0x88, 0x5e, 0xbf, 0x01, 0xf3, 0xdd, 0x16, 0xa2, 0x62, 0xf7, 0x22,
-            0x9b, 0xbf, 0xe1, 0x68, 0x40, 0xc0, 0x51, 0x3e, 0xa2, 0x2d, 0x0a, 0x39, 0xf0, 0x66, 0x5d, 0xca,
-            0xb5, 0x81, 0x35, 0x81, 0x46, 0x3e, 0xa5, 0x47, 0xff, 0xb1, 0xb7, 0x2f, 0x2c, 0xae, 0x07, 0x94,
-            0x03, 0x6c, 0x8f, 0xef, 0xe7, 0x25, 0xfe, 0x15, 0x74, 0x32, 0x50, 0x2e, 0x70, 0x95, 0x23, 0xc7,
-            0x66, 0x85, 0xab, 0xee, 0xfb, 0x47, 0x8f, 0x3f, 0xd6, 0x51, 0x35, 0xcc, 0xb9, 0x7a, 0x7d, 0x71,
-            0xc0, 0xbb, 0x00, 0xd3, 0x6b, 0xf5, 0xc0, 0xdc, 0xcb, 0x9f, 0xab, 0xc3, 0x8e, 0xe3, 0xde, 0xf9,
-            0x50, 0x82, 0xf3, 0x16, 0xa5, 0x98, 0xab, 0x01, 0x45, 0x4a, 0x86, 0xce, 0xc4, 0x6f, 0x9e, 0x5f,
-            0x2b, 0xb8, 0x87, 0xd8, 0x1b, 0x87, 0x14, 0x8a, 0xb6, 0x68, 0x79, 0xae, 0xb3, 0xf0, 0xa1, 0x2f,
-            0xa9, 0xd4, 0xff, 0x1d, 0xf0, 0x2c, 0x10, 0x57, 0xbc, 0x87, 0x49, 0x0e, 0x56, 0xf6, 0x90, 0xf3,
-            0x1d, 0xdd, 0x2d, 0x2f, 0x88, 0x7a, 0x01, 0xc1, 0xac, 0x76, 0xfb, 0xd7, 0xb2, 0x90, 0xfd, 0xde,
-            0xfe, 0x11, 0x31, 0x35, 0x0f, 0xb2, 0xb8, 0x37, 0x5a, 0x33, 0x20, 0xf3, 0xdd, 0xe3, 0x61, 0x2e,
-            0x9c, 0xa8, 0x00, 0xca, 0x1e, 0x6f, 0x11, 0x73, 0x2a, 0x1a, 0x71, 0xec, 0x61, 0x75, 0x1a, 0x27,
-            0x04, 0x0f, 0xb9, 0xaa, 0x39, 0x70, 0x10, 0x80, 0xd3, 0x72, 0x32, 0x1c, 0x40, 0xf6, 0xea, 0xe0,
-            0xa1, 0xb3, 0x4c, 0x44, 0x1d, 0xc3, 0x6c, 0x0c, 0xb7, 0x92, 0x8f, 0x4e, 0x46, 0x64, 0x25, 0xdb,
-            0x5a, 0x7e, 0x56, 0xd6, 0x82, 0xce, 0x16, 0xbd, 0xd5, 0xac, 0xcb, 0x61, 0xcb, 0xf6, 0x5e, 0x69,
-            0xa2, 0xcb, 0xea, 0xd7, 0x18, 0x1c, 0xf2, 0xbe, 0x15, 0xa9, 0x4c, 0xc1, 0xc3, 0x13, 0xa5, 0xcb,
-            0x21, 0xa8, 0xc4, 0xb3, 0x58, 0x5a, 0xbc, 0x8a, 0xb2, 0x77, 0x91, 0x31, 0x93, 0x57, 0xb6, 0x65,
-            0x99, 0x75, 0x6d, 0x6f, 0x2d, 0x42, 0x2b, 0x46, 0xc7, 0x40, 0x4b, 0xb2, 0x8b, 0xba, 0x1d, 0x1c,
-            0xb0, 0x79, 0x8d, 0x63, 0x8b, 0x91, 0x2d, 0x2b, 0xe2, 0xdc, 0x7e, 0x55, 0x97, 0x48, 0x88, 0xf2,
-            0x17, 0xa6, 0xf1, 0x0d, 0xc7, 0x6a, 0x83, 0x72, 0x86, 0xd6, 0x1c, 0x96, 0x2e, 0xd5, 0xc9, 0xd0,
-            0x3c, 0x18, 0x0e, 0x3c, 0xa3, 0x09, 0x80, 0xd2, 0x1d, 0x7a, 0x9e, 0x10, 0x66, 0x5a, 0x5f, 0x2b,
-            0xfe, 0x5f, 0xd7, 0x4b, 0x3c, 0x25, 0x61, 0x71, 0x98, 0xc8, 0x86, 0x80, 0x4b, 0x06, 0xf6, 0x2d,
-            0xf6, 0xf8, 0x08, 0x4f, 0xa2, 0xc0, 0xd4, 0xd9, 0x99, 0xda, 0xd5, 0x00, 0x50, 0xa8, 0x52, 0xf6,
-            0x2c, 0x1b, 0x43, 0x58, 0x80, 0xf0, 0xa2, 0x69, 0x5e, 0x89, 0x86, 0xf5, 0xea, 0x07, 0xc3, 0xcb,
-            0xbb, 0x48, 0xc6, 0xfb, 0x93, 0x01, 0xa2, 0xf2, 0x35, 0x91, 0x8d, 0x70, 0x2d, 0x35, 0xa0, 0x85,
-            0x66, 0xcc, 0x66, 0x00, 0x7a, 0x7e, 0xee, 0x11, 0x3a, 0xfa, 0xaf, 0xc2, 0xc9, 0xb6, 0x65, 0xc0,
-            0xb0, 0x1a, 0x9d, 0x67, 0xb5, 0xd8, 0x46, 0xf8, 0x2f, 0x83, 0xaf, 0x57, 0x8f, 0xa8, 0xa9, 0x2c,
-            0x12, 0x3e, 0x84, 0xd1, 0x99, 0xf4, 0x58, 0x74, 0xfa, 0x1a, 0xfa, 0x20, 0x84, 0xdf, 0xa1, 0x6e,
-            0xe2, 0xf3, 0x39, 0xce, 0xce, 0x84, 0x9f, 0xf2, 0x41, 0x7c, 0x17, 0x93, 0xf1, 0xef, 0x62, 0xc2,
-            0x6e, 0x7c, 0x06, 0x25, 0x85, 0x19, 0xe1, 0x7e, 0xbe, 0x98, 0x11, 0xc3, 0xbf, 0x2b, 0x45, 0x2c,
-            0xfa, 0x43, 0x9a, 0xed, 0xcc, 0xc8, 0x4b, 0x20, 0x13, 0x9b, 0x0b, 0x6a, 0x26, 0xd7, 0x75, 0x43,
-            0x90, 0x08, 0x53, 0xb8, 0x7e, 0xdb, 0xf9, 0x00, 0x9d, 0xbc, 0x80, 0x2e, 0x37, 0xa0, 0x68, 0x43,
-            0x46, 0xd2, 0x3a, 0xaa, 0xbc, 0xc7, 0xec, 0x27, 0x28, 0x01, 0xbb, 0x51, 0x06, 0xe6, 0x05, 0x6f,
-            0x50, 0xc1, 0xf4, 0xc4, 0x4a, 0x6d, 0xc2, 0x37, 0x00, 0x30, 0x3b, 0x72, 0xe8, 0x80, 0xe8, 0x81,
-            0x48, 0x8b, 0x34, 0x91, 0xb0, 0xae, 0x40, 0x3e, 0x59, 0x76, 0x3f, 0x75, 0x40, 0xec, 0x0c, 0x85,
-            0xd1, 0x09, 0x35, 0xd9, 0xf0, 0xe6, 0x95, 0x25, 0x70, 0x3d, 0x27, 0x41, 0x9f, 0x96, 0x56, 0x22,
-            0x20, 0xef, 0x28, 0x52, 0xed, 0xee, 0x78, 0xa1, 0xef, 0x32, 0x48, 0x87, 0x3a, 0xd3, 0x7a, 0x71,
-            0x7d, 0x43, 0x31, 0x42, 0x89, 0x73, 0xc7, 0x02, 0x6e, 0x28, 0x27, 0x1e, 0xfc, 0x66, 0x2b, 0x9a,
-            0x99, 0x17, 0x67, 0xe7, 0x2a, 0x8d, 0x19, 0x27, 0x75, 0xf4, 0x56, 0xa8, 0x7a, 0x5d, 0x82, 0xad,
-            0x6d, 0x66, 0x50, 0x94, 0x06, 0xa8, 0x83, 0x32, 0x12, 0x17, 0x77, 0xb5, 0xc3, 0x12, 0x7f, 0xb4,
-            0x60, 0xc9, 0x94, 0xf1, 0x0b, 0x75, 0x32, 0xde, 0x35, 0xf4, 0x49, 0x10, 0x37, 0x40, 0x9b, 0xea,
-            0x0f, 0x31, 0xf8, 0xa3, 0xb2, 0xa1, 0x15, 0xcf, 0xec, 0xb4, 0xa8, 0xa5, 0x50, 0x28, 0xdd, 0x5b,
-            0x87, 0x88, 0xd9, 0xf8, 0xc2, 0x3d, 0xd1, 0x00, 0x1d, 0x0d, 0xb6, 0xf0, 0x63, 0x99, 0xb2, 0xe4,
-            0xc1, 0xcd, 0x26, 0x75, 0x41, 0x11, 0x57, 0xbc, 0x26, 0x40, 0x87, 0x54, 0x5e, 0x4d, 0x22, 0x8a,
-            0xd7, 0x7b, 0x5d, 0x79, 0xf6, 0x91, 0x84, 0x49, 0x68, 0xa4, 0xc5, 0x2d, 0x52, 0x99, 0x3a, 0x58,
-            0x8c, 0x79, 0x87, 0x5d, 0x2a, 0x8a, 0x80, 0x16, 0xff, 0x8e, 0x27, 0xc0, 0x90, 0xe0, 0xc0, 0xd7,
-            0xdc, 0x04, 0x2b, 0x79, 0xf4, 0x4f, 0xf4, 0x22, 0x33, 0x0d, 0x7a, 0x02, 0x3b, 0xb7, 0xef, 0x47,
-            0xa9, 0x63, 0x84, 0x73, 0x47, 0x00, 0xd0, 0x09, 0x8c, 0xb8, 0x01, 0x9f, 0xe4, 0xfd, 0xfa, 0x89,
-            0x38, 0xf7, 0x81, 0xb4, 0x81, 0x67, 0x0a, 0xc4, 0x85, 0xea, 0xd4, 0x81, 0xf9, 0xd7, 0x62, 0xa2,
-            0x7d, 0x70, 0x23, 0x67, 0x53, 0x3c, 0x7b, 0x4c, 0xfa, 0xed, 0x86, 0x4e, 0xda, 0x0a, 0xa9, 0xab,
-            0x33, 0x86, 0xaa, 0x44, 0x7c, 0x4d, 0xad, 0x14, 0xd1, 0xcb, 0x4e, 0xf0, 0x1b, 0xe8, 0xdc, 0x3d,
-            0x29, 0x1b, 0xb4, 0xd2, 0x0b, 0xdc, 0x84, 0xa8, 0xad, 0xe6, 0x8d, 0xea, 0xf3, 0x86, 0x50, 0xfe,
-            0x43, 0xd5, 0xf1, 0xc2, 0x4a, 0x00, 0x31, 0xeb, 0x51, 0x40, 0x22, 0x1d, 0xe1, 0xad, 0x6e, 0x72,
-            0x2a, 0x78, 0xd2, 0xe0, 0xd8, 0x9e, 0x64, 0x06, 0x16, 0x11, 0xf8, 0x94, 0xa2, 0x5f, 0x4d, 0x3a,
-            0xfe, 0xbc, 0xd3, 0x64, 0xa5, 0x86, 0x7b, 0xe1, 0x80, 0x14, 0x94, 0x89, 0x51, 0xed, 0x1d, 0x7a,
-            0x39, 0x60, 0x14, 0x5f, 0x06, 0xec, 0xd5, 0x66, 0x98, 0x8e, 0xd3, 0x42, 0xa4, 0x95, 0x93, 0xc7,
-            0xb8, 0xdc, 0x01, 0x2e, 0x9c, 0x18, 0x4e, 0x91, 0x6b, 0x63, 0x95, 0x46, 0x91, 0xca, 0x15, 0x7e,
-            0x0a, 0xbd, 0x3e, 0xc3, 0xcd, 0x3a, 0x3d, 0xb1, 0x6d, 0xf0, 0x5f, 0x74, 0xfc, 0x8f, 0x03, 0xd1,
-            0xc4, 0xf5, 0x13, 0x76, 0xa1, 0x75, 0x4b, 0xd1, 0x9c, 0x0a, 0xe3, 0xf5, 0x63, 0xf5, 0x9e, 0x26,
-            0x42, 0x78, 0x67, 0x01, 0xb6, 0x20, 0x5f, 0xcb, 0xe6, 0xc8, 0xe7, 0xcb, 0xef, 0x83, 0x15, 0x17,
-            0x0c, 0x48, 0xd3, 0x79, 0x23, 0xec, 0xe9, 0x1b, 0x97, 0xaf, 0x35, 0x9c, 0x47, 0xff, 0xe8, 0xef,
-            0x61, 0x79, 0x68, 0xc2, 0xa0, 0x04, 0x23, 0x87, 0x8a, 0x57, 0xa9, 0x01, 0x5f, 0xbe, 0xce, 0x98,
-            0x91, 0xaf, 0x7e, 0x1a, 0xf1, 0xd0, 0x12, 0x57, 0x33, 0xe8, 0x80, 0x28, 0x6f, 0xe1, 0x4a, 0xef,
-            0x25, 0xa1, 0x45, 0x8d, 0xa3, 0x4b, 0x8f, 0xb2, 0xe2, 0x54, 0x26, 0x1b, 0xed, 0xaa, 0xb8, 0xc9,
-            0xbe, 0xe6, 0x0a, 0x92, 0x22, 0x1c, 0x3f, 0x51, 0x22, 0x0c, 0x2b, 0x36, 0xe1, 0x7c, 0x12, 0x71,
-            0x21, 0xc6, 0x50, 0x75, 0xb7, 0xab, 0xe3, 0x60, 0x84, 0xe8, 0x45, 0x2c, 0x2d, 0x7c, 0xc2, 0xf6,
-            0x4d, 0x8b, 0x0a, 0x51, 0x8a, 0x07, 0xa6, 0x3d, 0x4e, 0x11, 0x55, 0xb6, 0x14, 0x72, 0xac, 0x4a,
-            0xa2, 0xef, 0x65, 0xaf, 0xbd, 0xc7, 0xbc, 0x9a, 0xd6, 0xd2, 0xdd, 0x82, 0x2d, 0x1c, 0x3d, 0xdc,
-            0x74, 0x35, 0x58, 0x97, 0x6a, 0xac, 0x98, 0xf9, 0xab, 0x12, 0x92, 0x17, 0x5a, 0x24, 0x32, 0xea,
-            0x50, 0x4a, 0xb3, 0x21, 0x1d, 0x6f, 0x5b, 0xc8, 0xa4, 0x20, 0xb2, 0xd5, 0xce, 0xa9, 0xf3, 0x62,
-            0x88, 0x97, 0x54, 0x01, 0x55, 0xdd, 0xc0, 0x65, 0xb8, 0xca, 0x52, 0x7d, 0xce, 0x82, 0xd6, 0x30,
-            0x8e, 0x7c, 0xd6, 0x45, 0x6a, 0xd5, 0x59, 0x1d, 0x0b, 0xcf, 0x2c, 0xc0, 0xb2, 0xdd, 0x0c, 0xc6,
-            0xab, 0xbf, 0xeb, 0xa2, 0xf3, 0x44, 0xc6, 0xe5, 0x56, 0x2e, 0xd4, 0x00, 0xa4, 0x87, 0x10, 0x10,
-            0xfb, 0x53, 0x4d, 0x30, 0x03, 0xfb, 0x9d, 0x2c, 0xb4, 0xf8, 0x94, 0xc2, 0x86, 0x28, 0xae, 0x57,
-            0x61, 0x72, 0xa0, 0xfb, 0x9e, 0x19, 0x46, 0xd8, 0xf6, 0x65, 0x09, 0x76, 0x43, 0x6e, 0xb6, 0x20,
-            0xa5, 0xd9, 0x37, 0xfd, 0x72, 0x62, 0xef, 0x48, 0x51, 0xce, 0xc3, 0x2a, 0x41, 0xfa, 0xcf, 0x25,
-            0x10, 0x11, 0x90, 0xfa, 0x72, 0xb8, 0x90, 0x2c, 0xe7, 0x4a, 0x4d, 0xee, 0xcf, 0x7b, 0xbe, 0xb5,
-            0x2f, 0xc6, 0x84, 0x3d, 0xff, 0x44, 0x62, 0xc6, 0x9f, 0x12, 0x4c, 0x61, 0x2f, 0xb4, 0x0a, 0xc3,
-            0xfd, 0xd9, 0xf8, 0x0c, 0x1f, 0x86, 0xf6, 0x55, 0x12, 0x06, 0xf4, 0xae, 0xda, 0x05, 0x3d, 0x27,
-            0x0e, 0xe4, 0x9b, 0x89, 0x58, 0x05, 0xd9, 0x60, 0xd0, 0xe6, 0xda, 0x56, 0x43, 0xa4, 0x01, 0x49,
-            0xa8, 0xf2, 0xa2, 0x61, 0x1d, 0xaf, 0x23, 0x3b, 0x90, 0x68, 0x4e, 0x32, 0x30, 0x43, 0xa1, 0xf0,
-            0xc8, 0x4f, 0xa0, 0x84, 0xba, 0x26, 0xd5, 0x28, 0x03, 0xce, 0x63, 0x53, 0xf7, 0x9e, 0x41, 0x9b,
-            0x4d, 0xed, 0xd1, 0x84, 0xde, 0xc3, 0xe1, 0x13, 0xa6, 0x8a, 0x39, 0xad, 0xb1, 0xf6, 0x6a, 0x69,
-            0x05, 0xb6, 0xf8, 0x1a, 0x18, 0xba, 0x28, 0xcf, 0x65, 0x52, 0x3b, 0x0b, 0xe2, 0xa2, 0x5c, 0x06,
-            0x1a, 0x10, 0x2a, 0x43, 0x2f, 0xbb, 0xfb, 0x12, 0x30, 0x5c, 0x42, 0x8d, 0x92, 0xf4, 0xba, 0x05,
-            0x72, 0x8f, 0x30, 0x74, 0xd5, 0xba, 0xf9, 0x0f, 0x09, 0x87, 0x81, 0xfa, 0xd1, 0xc4, 0xfa, 0xb4,
-            0x9d, 0x2c, 0xb0, 0xbe, 0x04, 0x0c, 0x91, 0xbc, 0x69, 0x0b, 0xf9, 0x2d, 0x56, 0x83, 0x70, 0xb0,
-            0xb6, 0x85, 0x87, 0xb2, 0xfa, 0x8b, 0x44, 0xba, 0x9a, 0x64, 0xb3, 0xd4, 0x07, 0xdc, 0x25, 0x43,
-            0xb2, 0x7e, 0xf2, 0xe7, 0x07, 0x6a, 0x7d, 0x8b, 0x1b, 0x4f, 0xbd, 0xb4, 0x34, 0x31, 0xf8, 0x61,
-            0x3f, 0x7e, 0x62, 0x1d, 0x3e, 0x78, 0x03, 0x41, 0x22, 0xdc, 0x9c, 0xef, 0x5e, 0xf9, 0x0e, 0x5e,
-            0x10, 0x3f, 0x78, 0x08, 0xeb, 0xc1, 0x11, 0x91, 0x12, 0xaf, 0x62, 0x83, 0xe3, 0xef, 0x53, 0xe7,
-            0x33, 0x5b, 0x40, 0x42, 0x1b, 0x0c, 0x3d, 0xe0, 0xcf, 0x11, 0x99, 0xad, 0x5f, 0xd7, 0x39, 0x9b,
-            0xd1, 0x24, 0x48, 0xb4, 0xf2, 0x04, 0x48, 0xde, 0x71, 0x1d, 0xb6, 0x2c, 0xe1, 0x24, 0x22, 0x76,
-            0x5d, 0x1c, 0xb5, 0x21, 0x99, 0xe8, 0x21, 0x5b, 0xf0, 0x15, 0x2b, 0x5b, 0xfc, 0xfa, 0x9d, 0xb6,
-            0x89, 0x20, 0x70, 0xd7, 0x60, 0x35, 0x11, 0xcb, 0xf5, 0x15, 0xf6, 0xc0, 0x79, 0x3f, 0x03, 0x08,
-            0x38, 0x4a, 0xfd, 0xb8, 0xb1, 0x6d, 0xd6, 0x37, 0xba, 0x8b, 0xb7, 0x52, 0xd6, 0xb2, 0x21, 0xef,
-            0x61, 0x7c, 0x57, 0xd8, 0x73, 0xa3, 0x86, 0x1a, 0xcb, 0x20, 0x52, 0xb2, 0x30, 0xa4, 0x01, 0x9f,
-            0x6b, 0x28, 0x35, 0x35, 0x43, 0xa6, 0x06, 0x73, 0xd9, 0x3a, 0xb1, 0xf0, 0x52, 0x8c, 0xfd, 0x97,
-            0x55, 0x37, 0xa2, 0x10, 0x53, 0xe5, 0x90, 0xb7, 0xa9, 0x9f, 0xca, 0xa7, 0xac, 0x4b, 0xf0, 0x29,
-            0xb1, 0x33, 0xc3, 0x1c, 0xf5, 0x40, 0xe4, 0xb1, 0x02, 0xbc, 0x12, 0xb2, 0x89, 0x45, 0xd8, 0xb4,
-            0xd3, 0xa6, 0xf7, 0x01, 0x65, 0xa0, 0xe1, 0xb4, 0x82, 0xc9, 0x66, 0xd3, 0x8a, 0x44, 0xa6, 0xa6,
-            0x0d, 0x2e, 0x48, 0x06, 0xf4, 0xdd, 0x5d, 0x0d, 0xa6, 0x6b, 0x14, 0x28, 0x3e, 0x52, 0x1c, 0x6f,
-            0x45, 0x59, 0x1c, 0x1c, 0xd9, 0x06, 0x02, 0x62, 0x33, 0xb4, 0x62, 0x7f, 0x41, 0xd8, 0xbc, 0xba,
-            0x44, 0x5b, 0x27, 0xad, 0xb6, 0xfe, 0x56, 0x5d, 0xa3, 0x42, 0x92, 0x79, 0x28, 0xa2, 0xa8, 0x3b,
-            0xd6, 0xae, 0x0b, 0x5c, 0xed, 0x1b, 0x61, 0x1c, 0x5c, 0x72, 0x08, 0xeb, 0x04, 0x16, 0x40, 0x5a,
-            0x7e, 0xe8, 0xff, 0x3b, 0x45, 0x78, 0x01, 0x55, 0x9b, 0xcb, 0x34, 0x07, 0x98, 0x32, 0x84, 0x4b,
-            0xba, 0xc8, 0x83, 0x87, 0x53, 0xd8, 0xba, 0xa3, 0x01, 0xda, 0x7f, 0xe3, 0x9c, 0xb2, 0x1d, 0x32,
-            0xd6, 0xa6, 0xa0, 0x57, 0x3e, 0x95, 0xf2, 0x85, 0x5a, 0x09, 0xf3, 0x5e, 0x80, 0x87, 0x07, 0xce,
-            0x9d, 0x69, 0x2d, 0xd4, 0x48, 0xcc, 0x48, 0x24, 0x17, 0xcb, 0x0f, 0xd1, 0x53, 0xe3, 0x14, 0x03,
-            0x3f, 0x73, 0xa7, 0x47, 0x96, 0x63, 0x68, 0xc8, 0x08, 0x94, 0x7c, 0x61, 0x5c, 0x7d, 0x53, 0x05,
-            0xb3, 0xd3, 0x5e, 0xb4, 0x7c, 0xa9, 0x8e, 0x63, 0xf8, 0x7a, 0x87, 0x54, 0xc7, 0xdf, 0x77, 0x91,
-            0x8f, 0x8b, 0xc7, 0xb3, 0xf1, 0xda, 0x84, 0xbf, 0x34, 0x42, 0x0d, 0x23, 0xce, 0x64, 0x73, 0x86,
-            0xba, 0x8d, 0x4a, 0x33, 0xd1, 0xf2, 0x20, 0x8f, 0x93, 0x5e, 0x31, 0x05, 0xd8, 0xf7, 0xde, 0x9e,
-            0xcd, 0xf7, 0xfa, 0x0a, 0xaa, 0x90, 0x8f, 0x34, 0x37, 0x61, 0x6f, 0x2b, 0x53, 0x50, 0xc4, 0x07,
-            0x22, 0xe8, 0xc8, 0x9a, 0xb7, 0xa0, 0xe9, 0x58, 0xa5, 0xb3, 0x28, 0xf2, 0x61, 0x3a, 0x6a, 0x3d,
-            0x56, 0x0e, 0x8c, 0x56, 0xa9, 0x00, 0xb5, 0x77, 0x59, 0x4f, 0x07, 0x4d, 0x23, 0xf3, 0x2e, 0x41,
-            0x38, 0xfe, 0xce, 0x17, 0xda, 0x7c, 0x02, 0xe0, 0x03, 0xd2, 0x07, 0x77, 0x16, 0x03, 0x14, 0x9d,
-            0x4e, 0x47, 0x97, 0x4d, 0x00, 0x7b, 0x61, 0xb1, 0x35, 0x46, 0x4c, 0x41, 0xfd, 0x2b, 0x39, 0xbd,
-            0xc4, 0xfb, 0xd5, 0xcd, 0x8c, 0xa3, 0xa7, 0xb6, 0x19, 0x8a, 0x89, 0x21, 0xf5, 0xd2, 0xb4, 0x25,
-            0x06, 0x32, 0x76, 0xef, 0xdd, 0x83, 0x7d, 0x97, 0x6b, 0xaa, 0xde, 0x75, 0x82, 0x35, 0x78, 0xe3,
-            0xa5, 0x1f
-        };
-
-        private const uint8[] BR_DATA = {
-            0x1b, 0x31, 0xc8, 0x44, 0x51, 0xc1, 0x2a, 0x04, 0xac, 0x0b, 0x78, 0x30, 0xa4, 0x8c, 0xfe, 0x9b,
-            0x28, 0x60, 0xcd, 0x4e, 0x99, 0x31, 0xc7, 0x5f, 0xec, 0x8b, 0xcd, 0xf8, 0x55, 0xd6, 0xb6, 0x15,
-            0xa0, 0x23, 0xf4, 0xd8, 0x39, 0xa9, 0x5f, 0xbd, 0xcd, 0xea, 0xeb, 0xd7, 0x54, 0x10, 0x81, 0x35,
-            0xb3, 0xbb, 0x86, 0x39, 0x6e, 0x3a, 0x16, 0x7c, 0x1c, 0x07, 0x6e, 0x33, 0x85, 0xf4, 0x24, 0x25,
-            0x2e, 0x65, 0xca, 0x59, 0x29, 0x10, 0x56, 0xd8, 0x2f, 0x9b, 0xfa, 0xa7, 0xab, 0xb5, 0xf6, 0x3c,
-            0x23, 0x4b, 0x40, 0xe4, 0xfc, 0x4a, 0x8c, 0xf9, 0xa5, 0x9e, 0x5a, 0x83, 0xa4, 0x6f, 0x62, 0x52,
-            0x24, 0x8f, 0x50, 0xfa, 0x1a, 0xf2, 0x4b, 0xd5, 0xaf, 0x5a, 0xf2, 0xc6, 0x43, 0x11, 0xe2, 0x53,
-            0xa8, 0x0d, 0x9f, 0x54, 0xb9, 0x0f, 0x3f, 0xc4, 0xd8, 0x81, 0x9b, 0x2b, 0x29, 0x27, 0x10, 0x96,
-            0x39, 0xab, 0x9e, 0x70, 0x33, 0x0b, 0x0b, 0x23, 0xc0, 0x51, 0x72, 0xa8, 0x1a, 0xab, 0x74, 0x88,
-            0x9d, 0xbb, 0x3f, 0xb3, 0x54, 0xb3, 0x6a, 0x1d, 0x39, 0x58, 0xdf, 0x0a, 0x0e, 0xe5, 0xeb, 0xf1,
-            0xb6, 0xa7, 0x77, 0x15, 0x12, 0x9f, 0x05, 0x3d, 0x5a, 0x39, 0x69, 0x70, 0x1f, 0xe0, 0xcc, 0xe3,
-            0xf9, 0xfe, 0xc7, 0x5a, 0xaa, 0xcb, 0xc7, 0x56, 0x0c, 0x2a, 0x5c, 0x08, 0x91, 0xd3, 0xc9, 0x03,
-            0x3e, 0xd8, 0x43, 0xcc, 0x2f, 0x5f, 0xd5, 0xbe, 0x7e, 0xe5, 0x9d, 0x1b, 0xfa, 0xed, 0x05, 0xb8,
-            0xfa, 0xb7, 0xcc, 0x5a, 0x6e, 0x25, 0x91, 0x52, 0xba, 0xe2, 0xc9, 0xb0, 0xc0, 0x1a, 0xdd, 0xd1,
-            0x20, 0x07, 0xd8, 0x54, 0x11, 0x7f, 0x6f, 0x66, 0xa6, 0xe4, 0x7b, 0x80, 0x35, 0x32, 0xce, 0x24,
-            0x89, 0x94, 0xc1, 0x70, 0x29, 0x5b, 0xb9, 0x94, 0x2a, 0x89, 0x0e, 0xcf, 0xfc, 0x27, 0xb4, 0x15,
-            0xa6, 0x7b, 0x66, 0x8a, 0xe3, 0x56, 0x84, 0xd9, 0xad, 0xf5, 0x75, 0xbb, 0x5c, 0x2e, 0xe9, 0xff,
-            0xfb, 0xdd, 0x58, 0xfe, 0xee, 0x19, 0xf2, 0x66, 0x06, 0xbc, 0xab, 0x01, 0x70, 0x06, 0xe0, 0x6d,
-            0x95, 0x68, 0x12, 0x39, 0x63, 0x42, 0x45, 0x4a, 0x72, 0xdd, 0x45, 0x17, 0x2b, 0x55, 0x96, 0x28,
-            0x0d, 0xa5, 0xdb, 0x10, 0xbb, 0x75, 0x28, 0x7b, 0xe0, 0x74, 0xf6, 0xfd, 0x61, 0xda, 0xf7, 0xd2,
-            0x49, 0xcf, 0x4c, 0x9b, 0xbf, 0x0d, 0x06, 0x71, 0x18, 0x84, 0x2e, 0x30, 0xf1, 0xec, 0x21, 0xb9,
-            0xfd, 0xd7, 0x40, 0x7d, 0x28, 0xf2, 0xcf, 0xdd, 0x94, 0x4d, 0x9d, 0xb4, 0x69, 0xa0, 0x07, 0xd9,
-            0x3d, 0x57, 0xe6, 0xf1, 0x87, 0x8f, 0xff, 0x05, 0xee, 0xfa, 0x36, 0x2c, 0x62, 0xd2, 0xae, 0x33,
-            0xaa, 0xb4, 0xc7, 0x6c, 0x8b, 0x6b, 0x9d, 0xe4, 0x33, 0x69, 0x7a, 0xe1, 0x9f, 0xc3, 0xe0, 0x3c,
-            0xa3, 0x6b, 0x47, 0xf2, 0xe7, 0xe2, 0xf8, 0x70, 0xe6, 0x10, 0xd2, 0x0b, 0xe4, 0x95, 0x3e, 0x20,
-            0x45, 0x3f, 0x64, 0x78, 0x12, 0x86, 0x67, 0x86, 0x3d, 0x5f, 0x44, 0x31, 0xcd, 0x24, 0x40, 0xb7,
-            0x41, 0x43, 0x82, 0x31, 0x60, 0xd9, 0xbe, 0xfe, 0x26, 0x34, 0xe1, 0x99, 0xa4, 0x7e, 0xc1, 0x6b,
-            0x97, 0x45, 0xa9, 0xa8, 0x91, 0x6f, 0x42, 0x1e, 0x42, 0x7b, 0xc8, 0xd4, 0xbe, 0x51, 0x82, 0xff,
-            0xb0, 0xb9, 0xf5, 0xff, 0xb7, 0xfd, 0xf8, 0xbb, 0x99, 0xb6, 0x28, 0x9f, 0x05, 0x19, 0x4d, 0xf9,
-            0xe9, 0x32, 0x18, 0x86, 0xbe, 0x8d, 0x19, 0x6d, 0x83, 0x99, 0x9a, 0x9c, 0x25, 0x4d, 0xa8, 0x9c,
-            0x75, 0xa4, 0xcb, 0x22, 0x66, 0xe6, 0x14, 0x49, 0x89, 0xe7, 0xfd, 0x88, 0x6b, 0x06, 0xd6, 0x5d,
-            0x0f, 0xc8, 0x28, 0x54, 0x95, 0xcf, 0xce, 0x9a, 0x8b, 0x19, 0x58, 0xdf, 0x71, 0x35, 0xe3, 0x2c,
-            0xdc, 0x7b, 0xbd, 0x6e, 0xa6, 0xe2, 0xdb, 0x13, 0xc7, 0xe8, 0x50, 0x59, 0x40, 0x74, 0xbe, 0x9e,
-            0x0c, 0x2f, 0xb7, 0x61, 0x36, 0x84, 0xf7, 0xd1, 0x4f, 0x61, 0xa1, 0xcf, 0x6e, 0xf8, 0xcb, 0xe7,
-            0x63, 0xf2, 0x2e, 0xce, 0x81, 0x4a, 0xe9, 0x85, 0x52, 0x27, 0x74, 0xb5, 0x25, 0xf3, 0x2f, 0x1d,
-            0xb2, 0x90, 0x29, 0x1b, 0xfc, 0x95, 0x93, 0x65, 0x57, 0x99, 0xe2, 0x57, 0x9f, 0x8c, 0x49, 0x38,
-            0xb6, 0x8b, 0x5b, 0x63, 0xb3, 0x3f, 0xa2, 0xb4, 0x6f, 0x9c, 0x6c, 0xf0, 0x4b, 0x4e, 0xd6, 0x64,
-            0x30, 0x71, 0xc4, 0x20, 0xd2, 0x2e, 0xaa, 0xaf, 0x60, 0x2a, 0x48, 0x06, 0x04, 0x59, 0xe8, 0x1c,
-            0xae, 0x9a, 0xd8, 0x48, 0x1c, 0x3d, 0x63, 0xf4, 0xe4, 0x62, 0x01, 0x87, 0xe2, 0x8d, 0xa4, 0xcb,
-            0x40, 0x66, 0x8e, 0x43, 0x5f, 0xae, 0x63, 0x9c, 0x97, 0xeb, 0x38, 0xf3, 0x15, 0x3a, 0xd8, 0xd2,
-            0xa7, 0xae, 0xe6, 0xf7, 0xe7, 0x9c, 0x69, 0xe8, 0x43, 0xb4, 0x5d, 0x33, 0x64, 0x07, 0xb4, 0xa5,
-            0x3f, 0x63, 0xfc, 0x6a, 0x32, 0x74, 0x7d, 0xfb, 0x0a, 0x95, 0x9f, 0x92, 0x39, 0x74, 0x8d, 0xf1,
-            0xaf, 0xf7, 0xe7, 0xdf, 0xcc, 0x42, 0x22, 0xd7, 0xb7, 0xa7, 0x14, 0x9b, 0xf4, 0x13, 0x41, 0xbc,
-            0x46, 0xdc, 0xd1, 0x69, 0x6c, 0x49, 0x7a, 0x1d, 0x02, 0x64, 0xaf, 0x1a, 0x93, 0xb8, 0xb6, 0xfc,
-            0xe3, 0x0d, 0xf6, 0xee, 0x6b, 0xab, 0x6d, 0x6c, 0xec, 0xb7, 0xa2, 0xd9, 0x4a, 0x6c, 0x90, 0xff,
-            0x3a, 0xe2, 0x5a, 0x11, 0xc9, 0x79, 0x04, 0xf4, 0xc4, 0xe9, 0x8b, 0x03, 0x39, 0x28, 0x64, 0x45,
-            0xeb, 0x81, 0xd3, 0x26, 0x5b, 0x48, 0xc8, 0xa7, 0x6c, 0x4a, 0x20, 0x01, 0x50, 0x9c, 0x85, 0x27,
-            0x68, 0xa2, 0xc6, 0xf0, 0x0c, 0x0c, 0x1c, 0x1f, 0x78, 0x1b, 0xc3, 0x5b, 0x1d, 0x1c, 0xff, 0x29,
-            0x59, 0x66, 0xee, 0x4c, 0x46, 0x3a, 0xa0, 0xd8, 0xa7, 0x2e, 0x1c, 0x66, 0x70, 0x41, 0xc1, 0xbe,
-            0x90, 0xb2, 0x83, 0x25, 0xcd, 0x20, 0x32, 0x22, 0x79, 0xca, 0x81, 0x07, 0x33, 0x4e, 0x88, 0xf4,
-            0xc1, 0x35, 0x9f, 0xca, 0x98, 0xcd, 0x81, 0x81, 0x1c, 0xac, 0x51, 0x7d, 0x94, 0x83, 0x4b, 0xcf,
-            0x1c, 0xf1, 0xee, 0x0d, 0xcb, 0x56, 0xec, 0xc6, 0xce, 0x3b, 0x03, 0x13, 0x0d, 0xaa, 0x68, 0x5f,
-            0x66, 0x1d, 0x5a, 0xbb, 0x2d, 0x6e, 0x1e, 0x57, 0x65, 0x89, 0x2c, 0x77, 0x4a, 0x99, 0x3d, 0xd4,
-            0xfe, 0x74, 0xe9, 0xbd, 0xff, 0x83, 0x68, 0xad, 0xcb, 0xd7, 0xfe, 0x72, 0xcd, 0x47, 0x40, 0xe8,
-            0x49, 0x36, 0xe3, 0x17, 0x65, 0xed, 0xa5, 0x2b, 0x64, 0x0b, 0xfd, 0x5a, 0xda, 0x66, 0x55, 0xcf,
-            0x95, 0x96, 0xb9, 0xd6, 0x1d, 0x9c, 0xc4, 0xeb, 0x36, 0x21, 0xc8, 0x0a, 0x81, 0x70, 0x44, 0x2c,
-            0xbd, 0xb5, 0xb3, 0x9f, 0xeb, 0x1c, 0x99, 0xd3, 0x84, 0x0c, 0x5b, 0x60, 0x83, 0x02, 0x4b, 0xf1,
-            0x35, 0xf7, 0xef, 0xc8, 0x6c, 0x14, 0x6e, 0x6e, 0xc8, 0x30, 0xfd, 0x4f, 0x15, 0x37, 0x3f, 0x0e,
-            0x8f, 0x7f, 0xac, 0xa6, 0xaf, 0x1d, 0x24, 0xef, 0xe8, 0x03, 0xe4, 0xcb, 0x40, 0x0f, 0xca, 0xac,
-            0xaf, 0xad, 0x7e, 0xdf, 0x3d, 0x3e, 0xe8, 0xe2, 0x95, 0x5f, 0xdb, 0xea, 0x1d, 0xe0, 0xf2, 0x8c,
-            0x9e, 0xe5, 0x07, 0x97, 0x5c, 0xf3, 0x0b, 0x5e, 0x76, 0xb4, 0x3d, 0x7c, 0xd9, 0xd1, 0x42, 0x08,
-            0xcc, 0xed, 0xe8, 0x7c, 0x1a, 0x78, 0xda, 0xd3, 0x53, 0x33, 0xda, 0xd7, 0x3a, 0x24, 0x68, 0x4a,
-            0xcf, 0xad, 0x47, 0xbc, 0xe0, 0x57, 0xeb, 0x05, 0xbe, 0xda, 0xfa, 0x19, 0xbd, 0xeb, 0x79, 0xac,
-            0x73, 0xef, 0xa1, 0x6d, 0xb0, 0xf2, 0x49, 0x2f, 0xb9, 0x2e, 0x37, 0xf1, 0xb2, 0xa3, 0xfd, 0xa5,
-            0x13, 0x6d, 0x47, 0xb3, 0xe8, 0x68, 0x5e, 0x57, 0x1b, 0x15, 0xf0, 0xc8, 0x1f, 0x7a, 0xd6, 0x78,
-            0xcc, 0x6a, 0x70, 0x57, 0x6e, 0xcb, 0x75, 0x7b, 0x06, 0x6f, 0xf8, 0xb9, 0x12, 0xe5, 0xd2, 0x35,
-            0xf6, 0x47, 0x10, 0x49, 0x96, 0x59, 0xf3, 0xe5, 0xf2, 0xd4, 0x2a, 0x81, 0xa5, 0x2d, 0xf7, 0xf6,
-            0xf6, 0xe5, 0x56, 0xae, 0xb1, 0x8c, 0xdf, 0x9d, 0x8a, 0x4d, 0x16, 0x90, 0xe7, 0x7f, 0xca, 0x95,
-            0x6b, 0x3e, 0x81, 0x1e, 0xc7, 0x24, 0xb2, 0x19, 0x46, 0x07, 0xb9, 0xf8, 0x0a, 0x47, 0xa9, 0xe9,
-            0x32, 0x9e, 0x65, 0x9d, 0x11, 0x41, 0xb8, 0x2d, 0x1f, 0xae, 0x16, 0x7a, 0x2f, 0x98, 0x8d, 0xf7,
-            0xe5, 0x26, 0x3f, 0xa9, 0x7f, 0xf2, 0xa1, 0xc8, 0x6a, 0x85, 0xf8, 0xbc, 0x1c, 0xa2, 0x28, 0x7b,
-            0x35, 0xd8, 0xc7, 0x60, 0xcd, 0x9b, 0x8b, 0xf8, 0x0e, 0xd5, 0x53, 0xaf, 0x8d, 0xe5, 0xb2, 0xb0,
-            0xee, 0xbf, 0xa9, 0x5f, 0x7d, 0x89, 0x75, 0x21, 0xb6, 0x80, 0xbb, 0xb2, 0x1f, 0x1c, 0x29, 0xb1,
-            0x77, 0xa9, 0xcd, 0x36, 0xf2, 0xb3, 0x7b, 0xbc, 0x7b, 0xa5, 0xcc, 0x2f, 0xb0, 0x90, 0x60, 0x85,
-            0x40, 0x24, 0x3c, 0x55, 0xaa, 0xfd, 0xdb, 0x74, 0x52, 0x0f, 0xf6, 0xe4, 0x4e, 0xae, 0x93, 0x65,
-            0x80, 0xd7, 0x73, 0x2e, 0x5a, 0x93, 0x46, 0x40, 0xde, 0x0f, 0xc8, 0xc6, 0xfb, 0xf2, 0x5c, 0xae,
-            0x93, 0x15, 0x9e, 0xb5, 0xe1, 0x6b, 0x83, 0x94, 0x55, 0xe3, 0xf1, 0x8e, 0x5d, 0xf5, 0xbc, 0xf6,
-            0x8d, 0x34, 0x8d, 0x06, 0x79, 0x2e, 0x78, 0x6b, 0xa1, 0x7d, 0x1f, 0xc8, 0x43, 0x95, 0x2c, 0x1f,
-            0x65, 0xa5, 0x60, 0x08, 0xe8, 0x01, 0xfc, 0xd1, 0xff, 0x09, 0x93, 0x72, 0x1d, 0xab, 0xdd, 0xa4,
-            0x6f, 0x3d, 0xc8, 0x6f, 0x76, 0x23, 0xd3, 0x1f, 0xd5, 0x3a, 0x81, 0xb6, 0x30, 0xe4, 0x22, 0xe2,
-            0xdb, 0x7b, 0x64, 0xb8, 0xd1, 0x9b, 0x38, 0xf6, 0xdb, 0x46, 0x27, 0x5f, 0xe5, 0x11, 0x67, 0xb7,
-            0x68, 0xd3, 0x52, 0x61, 0x06, 0xe2, 0x11, 0x3a, 0x02, 0x31, 0x26, 0x17, 0x0d, 0xfb, 0x29, 0xb7,
-            0x3f, 0xae, 0x7c, 0x97, 0x2d, 0xcc, 0xc5, 0xba, 0xfa, 0xdb, 0x3f, 0x9e, 0x13, 0x98, 0x3f, 0xf9,
-            0xbf, 0x73, 0xba, 0x71, 0x75, 0x4b, 0xc4, 0xa2, 0x56, 0xdf, 0xbb, 0x0c, 0x63, 0x63, 0x7e, 0x76,
-            0x86, 0xbe, 0x6d, 0xc1, 0x76, 0xaa, 0xa0, 0x2b, 0xae, 0xf2, 0x35, 0x70, 0x4f, 0xb2, 0x75, 0xaf,
-            0xff, 0xde, 0xaf, 0xf0, 0x6a, 0xb0, 0x7b, 0x16, 0x9f, 0x2e, 0xbf, 0x1d, 0x90, 0xb9, 0xd7, 0xd3,
-            0xdb, 0xca, 0xaf, 0xb6, 0x0d, 0xe7, 0x5c, 0x5e, 0x15, 0x1b, 0xe5, 0x52, 0xa0, 0xe8, 0x35, 0x0e,
-            0x90, 0xc2, 0x4e, 0xa7, 0x33, 0x3e, 0x8c, 0xa0, 0x3e, 0x56, 0x81, 0xcf, 0x59, 0xcb, 0x8c, 0x01,
-            0x46, 0x2d, 0x5e, 0xcf, 0x1d, 0x28, 0xf6, 0xa6, 0x36, 0xae, 0x90, 0x39, 0x4a, 0xf0, 0x45, 0xab,
-            0x7c, 0x47, 0x6e, 0x4e, 0xe6, 0x65, 0x93, 0x00, 0x7a, 0xad, 0xe7, 0x84, 0xc2, 0x1f, 0x7c, 0x20,
-            0x81, 0xec, 0x6b, 0xd0, 0x18, 0x9a, 0x73, 0xd9, 0x60, 0x11, 0xcf, 0x9c, 0x07, 0xd8, 0x95, 0x61,
-            0x2f, 0x27, 0x36, 0x6d, 0xaf, 0xb2, 0x4a, 0x73, 0x74, 0xc2, 0x20, 0x83, 0x84, 0xe3, 0x54, 0xbe,
-            0x0d, 0xc5, 0x6a, 0x97, 0x5b, 0x60, 0xf2, 0x61, 0x98, 0x04, 0xcb, 0x47, 0x7d, 0x93, 0x7c, 0x2c,
-            0x3e, 0x80, 0x0f, 0xf0, 0xea, 0x4b, 0x97, 0x2e, 0xba, 0x67, 0x31, 0xf6, 0x8b, 0xdb, 0xd0, 0xa5,
-            0x09, 0x99, 0x8a, 0x3f, 0x20, 0x21, 0x8b, 0xf2, 0x39, 0x02, 0x13, 0x54, 0x32, 0x40, 0x41, 0x34,
-            0xbb, 0xb7, 0x8f, 0x3f, 0xe9, 0x6a, 0xac, 0x90, 0x2b, 0xd2, 0x25, 0x17, 0xc7, 0xae, 0xf2, 0xe6,
-            0x74, 0xc1, 0xab, 0x12, 0x3b, 0xaa, 0x44, 0x8e, 0x73, 0x1c, 0x13, 0x83, 0x98, 0xd1, 0x66, 0xf9,
-            0xc0, 0x16, 0xb0, 0x77, 0xb7, 0x96, 0x76, 0x53, 0x5c, 0xfb, 0x42, 0x6b, 0x4b, 0xfa, 0x76, 0xf4,
-            0xf3, 0xf7, 0xd0, 0x84, 0x8c, 0x62, 0x6c, 0xcc, 0x48, 0xa4, 0x97, 0xe8, 0xcc, 0xd0, 0xc3, 0x9c,
-            0x1f, 0x61, 0x9c, 0xfa, 0x96, 0xc2, 0x89, 0xb5, 0xe2, 0xb2, 0x0b, 0x66, 0xe5, 0xb5, 0x7c, 0x39,
-            0x42, 0x26, 0x64, 0x02, 0xeb, 0x0a, 0xc3, 0xeb, 0xe9, 0x3f, 0x73, 0x30, 0x9a, 0x80, 0x96, 0x02,
-            0x19, 0x70, 0xe1, 0xda, 0x0e, 0x7a, 0x83, 0x58, 0x3e, 0xa0, 0xfe, 0x30, 0x23, 0x3e, 0xf9, 0x97,
-            0x1c, 0xa8, 0x4c, 0x43, 0xcc, 0x98, 0x0a, 0x40, 0x31, 0x44, 0x09, 0xb4, 0x94, 0xe3, 0xb0, 0x93,
-            0x6e, 0xdd, 0xde, 0x7c, 0xd9, 0x7c, 0x58, 0xea, 0xa1, 0x5b, 0x4e, 0x6d, 0x52, 0x65, 0xff, 0xd3,
-            0x3b, 0x8b, 0xed, 0x99, 0xdf, 0x3d, 0x2c, 0xcf, 0xde, 0xba, 0xb2, 0xdb, 0x7a, 0x7a, 0x7e, 0xf7,
-            0x2c, 0x5e, 0xd2, 0x65, 0xbc, 0xf4, 0x97, 0xa7, 0xcb, 0x56, 0x1f, 0xfa, 0xee, 0xf2, 0x65, 0xe6,
-            0xf8, 0x13, 0x3a, 0x20, 0x81, 0x19, 0x47, 0x7e, 0x9e, 0x2f, 0x47, 0xcd, 0x40, 0xd6, 0x92, 0xe2,
-            0x9d, 0xa5, 0x55, 0xaa, 0x93, 0x33, 0x2c, 0x18, 0x39, 0x6c, 0x01, 0x4c, 0x47, 0xfb, 0x6d, 0x9c,
-            0x6a, 0xbb, 0xfb, 0x99, 0x46, 0x81, 0x06, 0xb6, 0x38, 0x36, 0xfd, 0x11, 0x00, 0x2a, 0xa1, 0x49,
-            0xbf, 0x39, 0x26, 0x58, 0x7e, 0xf1, 0x7c, 0x54, 0x52, 0x96, 0x9a, 0x0b, 0x85, 0x82, 0x11, 0x2d,
-            0x2c, 0x1b, 0xec, 0x83, 0x8e, 0x8b, 0x0d, 0xff, 0x9c, 0x9e, 0xdc, 0x2e, 0x8b, 0xda, 0x45, 0x4d,
-            0x8f, 0x6c, 0x51, 0x3e, 0xd0, 0x3c, 0x64, 0xf4, 0xfd, 0x9d, 0xa3, 0x23, 0x81, 0xd8, 0x4a, 0xfb,
-            0x01, 0x89, 0x8f, 0x9d, 0xb7, 0x9a, 0x96, 0x29, 0x34, 0x26, 0x17, 0x27, 0x6d, 0x89, 0x23, 0xce,
-            0x90, 0x80, 0xd5, 0x05, 0xe9, 0x1a, 0xd1, 0x60, 0xec, 0x76, 0x88, 0x55, 0xfa, 0x14, 0x0e, 0xac,
-            0x2a, 0xd4, 0x8b, 0xb6, 0x79, 0x4e, 0x98, 0xb9, 0x9f, 0x53, 0xb8, 0xe4, 0xb5, 0xad, 0x55, 0x88,
-            0x24, 0x3c, 0xb5, 0xba, 0xd5, 0x38, 0x99, 0x1b, 0x8c, 0x2d, 0xe4, 0x07, 0x53, 0xaa, 0xbf, 0x09,
-            0x05, 0xf5, 0x7c, 0x2b, 0x4d, 0x21, 0x55, 0xcb, 0xca, 0x1e, 0x22, 0x5c, 0x14, 0x80, 0x15, 0x63,
-            0x25, 0x6e, 0x4d, 0x16, 0x3e, 0xb3, 0xc8, 0x76, 0x12, 0x2d, 0x68, 0x67, 0xb5, 0x5f, 0xc2, 0xe3,
-            0xa8, 0x70, 0x38, 0x15, 0x9c, 0x92, 0x9c, 0x79, 0x38, 0xc1, 0xb0, 0x74, 0x12, 0x86, 0x78, 0x6f,
-            0x6a, 0x7f, 0xec, 0xe9, 0xbc, 0x45, 0x0e, 0x10, 0xdf, 0x50, 0xc1, 0x92, 0x01, 0x7b, 0x03, 0x76,
-            0x8d, 0xd4, 0x60, 0x8d, 0x58, 0x6f, 0xdb, 0xcd, 0xcf, 0x3d, 0x9f, 0xa1, 0x12, 0x12, 0x38, 0x3d,
-            0x0f, 0x46, 0x00, 0x19, 0xd0, 0x43, 0x39, 0x32, 0x00, 0xb9, 0x49, 0x67, 0x0f, 0x9a, 0xf3, 0xdd,
-            0x48, 0x80, 0xe4, 0xd6, 0xf7, 0x30, 0xbf, 0x25, 0x9d, 0x31, 0x87, 0xc4, 0xfb, 0x43, 0xf1, 0x3a,
-            0xcc, 0x6f, 0xcb, 0x17, 0x5b, 0x7d, 0x5e, 0x3e, 0x83, 0x3f, 0x77, 0xf9, 0x43, 0x8f, 0x37, 0x8b,
-            0xd7, 0x63, 0x30, 0xbe, 0xeb, 0xd0, 0xd3, 0x51, 0xea, 0x6e, 0x4d, 0x60, 0x30, 0xa6, 0xc0, 0xc6,
-            0x05, 0x85, 0x42, 0x95, 0xb5, 0x88, 0x56, 0x72, 0x6e, 0x0c, 0x86, 0xe0, 0xe2, 0xc0, 0x6d, 0xd2,
-            0xa4, 0xee, 0xf3, 0x85, 0x29, 0x69, 0x99, 0x46, 0x03, 0xb6, 0x2e, 0xe0, 0xa8, 0x50, 0xfa, 0x9d,
-            0x3a, 0x76, 0x03, 0x17, 0xbc, 0x1d, 0xfa, 0x72, 0x85, 0xe6, 0xed, 0x43, 0xc4, 0x03, 0x01, 0x62,
-            0x7a, 0x25, 0x24, 0x66, 0x39, 0xbb, 0x91, 0x71, 0x45, 0x9e, 0x1d, 0x97, 0x15, 0x2c, 0x3e, 0xcf,
-            0xa4, 0x46, 0x8b, 0x9d, 0x4b, 0xe3, 0xd1, 0x18, 0x13, 0x90, 0xcc, 0x2c, 0x08, 0xda, 0xdb, 0x5d,
-            0x38, 0x9f, 0x1d, 0xe2, 0xc4, 0x93, 0x38, 0x53, 0x84, 0x1d, 0xc8, 0x89, 0x42, 0x43, 0xa3, 0x87,
-            0x21, 0x61, 0xac, 0xee, 0x87, 0xdd, 0xff, 0xa8, 0x8e, 0xbd, 0x22, 0xb2, 0x57, 0x05, 0xaa, 0x2f,
-            0x27, 0x14, 0x04, 0x46, 0xbb, 0x61, 0x6f, 0xd0, 0xa0, 0x7d, 0x8f, 0x4b, 0x6e, 0x70, 0x97, 0x73,
-            0x0c, 0x45, 0x76, 0x15, 0x6b, 0xa9, 0xbe, 0x5a, 0x55, 0x69, 0xa2, 0xfa, 0x8c, 0xae, 0x16, 0x8d,
-            0x78, 0x0e, 0x81, 0xa1, 0x98, 0xba, 0x21, 0x7b, 0x5a, 0xd6, 0xb3, 0x1c, 0xbe, 0xc3, 0x48, 0x61,
-            0xe1, 0x54, 0xff, 0x3c, 0x0c, 0x74, 0x46, 0xbb, 0x8a, 0xdf, 0x5c, 0xa2, 0x4a, 0x05, 0x5e, 0x70,
-            0x25, 0x6f, 0xac, 0xcf, 0xc1, 0x66, 0x68, 0x3e, 0x6c, 0xef, 0xeb, 0xde, 0x01, 0x8f, 0x52, 0xec,
-            0xea, 0x67, 0x4e, 0xaa, 0x19, 0x90, 0xe8, 0x45, 0xf6, 0x3e, 0x1c, 0x2e, 0x00, 0x2b, 0xf7, 0x03,
-            0x0c, 0xb3, 0x2d, 0xc4, 0xd0, 0xd0, 0x23, 0x2e, 0xbd, 0xfe, 0x5b, 0x10, 0x6b, 0x78, 0xf6, 0x7c,
-            0x2a, 0xbc, 0x0b, 0x67, 0xc1, 0xc0, 0x71, 0x37, 0xef, 0x09, 0xb0, 0x1e, 0x85, 0x61, 0xe1, 0xdc,
-            0x66, 0xc3, 0x79, 0x0e, 0x9a, 0xd1, 0x61, 0x81, 0xec, 0x07, 0xda, 0x8c, 0x45, 0x50, 0x13, 0xea,
-            0x8a, 0x0f, 0x0b, 0xcd, 0x00, 0xb2, 0x00, 0xd4, 0x0e, 0xb2, 0x88, 0x14, 0x14, 0x8e, 0xeb, 0x44,
-            0x61, 0xd3, 0x7f, 0x73, 0x17, 0xa2, 0xbd, 0x42, 0x67, 0x48, 0x7a, 0xc9, 0x91, 0xf5, 0xc9, 0xa5,
-            0xa5, 0x24, 0x25, 0x16, 0xa1, 0x63, 0x7c, 0x2a, 0x84, 0xa5, 0xca, 0x46, 0x32, 0xee, 0x5f, 0xa4,
-            0x42, 0xbc, 0xe8, 0xdb, 0x3f, 0xb3, 0xb1, 0x0a, 0xbe, 0x0a, 0xc9, 0x46, 0x22, 0x06, 0xd8, 0xd5,
-            0x25, 0x14, 0x60, 0x7d, 0x0a, 0x02, 0x94, 0x15, 0x1d, 0x24, 0x94, 0xcc, 0xbb, 0x77, 0xba, 0xa1,
-            0x95, 0xfb, 0xaf, 0x15, 0x12, 0x16, 0x0b, 0x67, 0xe2, 0xf6, 0x84, 0x7a, 0x61, 0xc5, 0x05, 0x84,
-            0xf2, 0x78, 0xbd, 0x8e, 0x83, 0x44, 0xff, 0x01, 0x30, 0x14, 0xcc, 0xbc, 0xf4, 0xcc, 0xbc, 0x94,
-            0xf5, 0x1a, 0x84, 0xab, 0x17, 0xc0, 0xad, 0xbc, 0x19, 0x84, 0xf1, 0x78, 0xb6, 0x90, 0x9c, 0xb7,
-            0xba, 0x29, 0x2f, 0x81, 0xd2, 0x7d, 0x9a, 0x96, 0x77, 0x8c, 0xea, 0x94, 0x88, 0x64, 0x9b, 0x79,
-            0x6e, 0x38, 0x1b, 0x3f, 0x88, 0xbe, 0x1d, 0xdb, 0xa0, 0xeb, 0x84, 0x93, 0xec, 0xf9, 0x5e, 0x10,
-            0xf0, 0x76, 0xd3, 0xec, 0xe8, 0x2e, 0x91, 0x63, 0x21, 0x4a, 0xb2, 0x5c, 0xe6, 0xde, 0x76, 0x92,
-            0xc2, 0xfb, 0xed, 0x8a, 0xd8, 0x80, 0xe7, 0xef, 0x31, 0x02, 0x9d, 0x22, 0x72, 0x74, 0x77, 0x8f,
-            0x1a, 0xda, 0x47, 0xd8, 0x32, 0xbb, 0xa0, 0xcb, 0xee, 0x3c, 0x49, 0xaa, 0xb9, 0xb8, 0x90, 0xb0,
-            0xfd, 0x51, 0x92, 0x27, 0xbb, 0x83, 0xb8, 0xd9, 0x95, 0x66, 0x52, 0xf6, 0x01, 0x65, 0xe5, 0xa8,
-            0x2a, 0xc0, 0x83, 0x97, 0x0d, 0x13, 0x12, 0x4c, 0x6c, 0x91, 0x0a, 0xe2, 0x05, 0x9e, 0xb0, 0xfd,
-            0x1c, 0xd0, 0x25, 0x7d, 0xcb, 0xc3, 0xd4, 0xa0, 0x7b, 0x1f, 0x4a, 0xa2, 0x24, 0xe1, 0x30, 0x21,
-            0x0e, 0x6a, 0x63, 0x68, 0xf0, 0x55, 0x83, 0xff, 0x4a, 0x70, 0x32, 0x46, 0x4e, 0xcf, 0xee, 0x72,
-            0x9a, 0x44, 0x98, 0x82, 0x82, 0x20, 0x25, 0x5c, 0xe7, 0x06, 0xc5, 0xaa, 0x99, 0x0e, 0xe7, 0x01,
-            0x78, 0x87, 0x8e, 0x74, 0x9e, 0xdc, 0x8a, 0x6a, 0x7d, 0x50, 0x0e, 0x8e, 0x61, 0x25, 0x47, 0x78,
-            0x06, 0x19, 0xb5, 0x76, 0x68, 0xcd, 0xc5, 0x56, 0x66, 0x5d, 0xf8, 0x7d, 0xde, 0x40, 0xbd, 0x47,
-            0x79, 0x49, 0xcd, 0x15, 0x70, 0xe6, 0x5b, 0xd8, 0x02, 0x17, 0xd4, 0xed, 0xbc, 0x6f, 0xd6, 0x7a,
-            0x8b, 0xdd, 0x40, 0x2d, 0xda, 0xfa, 0x89, 0xe7, 0x51, 0xdf, 0x45, 0xac, 0x0d, 0xf5, 0x63, 0xab,
-            0xa4, 0xdc, 0x60, 0xa2, 0x9d, 0xb9, 0xc7, 0x18, 0xc5, 0x92, 0x56, 0xe4, 0xc0, 0x61, 0xd9, 0xe7,
-            0x26, 0x4a, 0xdf, 0x91, 0x47, 0xa8, 0x4c, 0xf3, 0x9f, 0xb0, 0xe4, 0xb3, 0x62, 0x9e, 0xea, 0x33,
-            0x10, 0x90, 0xd4, 0x95, 0x02, 0x4e, 0x3e, 0xe9, 0x26, 0xa4, 0x10, 0xdd, 0x61, 0xde, 0x4c, 0x9d,
-            0xb2, 0xb9, 0x59, 0xb6, 0x08, 0xf9, 0x51, 0x72, 0x13, 0xaa, 0xa4, 0x3c, 0x69, 0xe9, 0x69, 0x05,
-            0xbc, 0x89, 0x48, 0x85, 0x72, 0xc6, 0xd7, 0xac, 0x97, 0x00, 0x68, 0x76, 0x53, 0x73, 0xb1, 0x23,
-            0x14, 0xeb, 0xfb, 0x22, 0x47, 0x58, 0x5e, 0x1b, 0x0c, 0x99, 0x9f, 0xad, 0xe0, 0x00, 0x32, 0xcc,
-            0x39, 0xd8, 0x4e, 0x38, 0x7b, 0x38, 0x05, 0xf9, 0x3a, 0x9d, 0x94, 0xa7, 0x27, 0x7e, 0xc3, 0xa1,
-            0xe9, 0x46, 0x0a, 0x74, 0x87, 0x75, 0x9f, 0xe5, 0x38, 0x18, 0xe2, 0x61, 0xab, 0x52, 0xfb, 0x34,
-            0x7d, 0xd8, 0xb7, 0xe9, 0xd8, 0x36, 0xd1, 0x9b, 0x2d, 0xdf, 0xc0, 0xef, 0x63, 0x04, 0xad, 0xb2,
-            0xfe, 0x58, 0x55, 0x55, 0x9e, 0x49, 0x2c, 0xab, 0xb9, 0xc5, 0x86, 0x97, 0x7a, 0xbd, 0x48, 0x10,
-            0x70, 0xc8, 0x2a, 0xf7, 0x14, 0x8e, 0x81, 0xb2, 0x42, 0xd4, 0x52, 0x9c, 0x1a, 0x5f, 0xab, 0xc0,
-            0x5e, 0x2c, 0x54, 0x11, 0xaa, 0x5a, 0x64, 0x24, 0xca, 0x90, 0x16, 0xd5, 0x59, 0xc8, 0xb5, 0x21,
-            0xf0, 0xbe, 0xb6, 0x0e, 0xb4, 0x3b, 0xb4, 0x54, 0x02, 0xf6, 0x75, 0x8d, 0xd3, 0x3d, 0x07, 0x4b,
-            0xf0, 0x36, 0x8d, 0x0f, 0x5d, 0xaf, 0xa9, 0x1c, 0xee, 0x56, 0x31, 0xd9, 0xf7, 0x05, 0x33, 0xba,
-            0x05, 0xf3, 0x13, 0xfe, 0x7b, 0x74, 0xbd, 0x5c, 0x36, 0x1d, 0xcb, 0x5a, 0x1b, 0x8f, 0xb4, 0xf7,
-            0x86, 0x39, 0x8e, 0xf1, 0x6d, 0xcf, 0xdc, 0xa9, 0xa6, 0x46, 0x45, 0xaf, 0x9e, 0xea, 0x66, 0x79,
-            0xbd, 0xe8, 0xf1, 0xbb, 0x99, 0x02, 0x53, 0x00, 0x96, 0xc6, 0xf5, 0x7f, 0xa7, 0xba, 0xb4, 0x47,
-            0x99, 0xff, 0xb1, 0x36, 0x93, 0xb7, 0x00, 0x01, 0x85, 0x55, 0x75, 0xd7, 0x0c, 0xeb, 0xab, 0xc5,
-            0x0e, 0x0a, 0x68, 0xbd, 0x52, 0xd8, 0x07, 0x02, 0x9d, 0xb1, 0x64, 0x11, 0x9a, 0xfd, 0x6d, 0xeb,
-            0x80, 0x14, 0x7d, 0x2c, 0xb4, 0x96, 0xaf, 0xb9, 0xfb, 0x73, 0x99, 0x80, 0xcc, 0x81, 0xe6, 0x4a,
-            0xc9, 0x9d, 0x94, 0xe0, 0x50, 0x3a, 0xfb, 0xb1, 0x66, 0xf8, 0x10, 0xb3, 0xe1, 0x4c, 0x49, 0x40,
-            0xe4, 0x1f, 0xe6, 0xdd, 0x40, 0x9c, 0x6f, 0x08, 0x7b, 0x7b, 0xb8, 0x0c, 0x34, 0xd8, 0xe5, 0x9b,
-            0x36, 0x24, 0xfe, 0x2a, 0x44, 0x0e, 0x54, 0xb4, 0xe1, 0x43, 0xd2, 0x99, 0xc8, 0x36, 0x8c, 0x0f,
-            0x89, 0x9f, 0xf7, 0x85, 0x89, 0x37, 0x24, 0x59, 0x58, 0x6f, 0x42, 0x3d, 0x7f, 0x81, 0x84, 0xe7,
-            0x0a, 0xa0, 0x0b, 0x9c, 0x2b, 0x9f, 0xdc, 0xfa, 0x88, 0xa2, 0x0e, 0x07, 0x36, 0xae, 0x85, 0xef,
-            0xde, 0x1f, 0xc8, 0x5a, 0x35, 0x00, 0x30, 0x9c, 0xb1, 0x3e, 0x4e, 0xca, 0xad, 0xbe, 0xae, 0xff,
-            0x15, 0x72, 0x0d, 0x47, 0xdf, 0xea, 0x2e, 0xf2, 0xd8, 0xb4, 0xab, 0xc1, 0x6b, 0x6a, 0x15, 0x9b,
-            0xdc, 0x4e, 0x4e, 0x31, 0xec, 0x3d, 0x94, 0xa6, 0x02, 0x7c, 0xaa, 0xf4, 0x6f, 0x0d, 0x57, 0x1a,
-            0xde, 0xa9, 0x7a, 0xca, 0xa7, 0xc3, 0xd8, 0x1a, 0x70, 0x5a, 0xc4, 0xad, 0x5a, 0x7a, 0xc4, 0xd3,
-            0xe1, 0xd2, 0x64, 0x7c, 0xdb, 0xe9, 0xda, 0xa8, 0xda, 0xfc, 0x4f, 0x43, 0xda, 0x62, 0xcc, 0xc6,
-            0xc1, 0xe1, 0x8d, 0xfa, 0x5f, 0xfc, 0x4b, 0x0f, 0xd5, 0x5f, 0xe1, 0x77, 0x17, 0x20, 0x86, 0x36,
-            0x3a, 0xfc, 0x7d, 0x67, 0xec, 0xa3, 0x9d, 0xb6, 0x31, 0x4b, 0xc8, 0x70, 0xd5, 0xf3, 0x9f, 0xba,
-            0x51, 0xe2, 0xed, 0x64, 0xbf, 0x91, 0x9a, 0x72, 0x12, 0x6b, 0x67, 0x01, 0xb0, 0x58, 0x4c, 0x6e,
-            0x01, 0xe0, 0xb5, 0x39, 0xd6, 0xc3, 0x31, 0x44, 0xe5, 0x80, 0x88, 0x00, 0xae, 0xa5, 0x6a, 0x4b,
-            0x44, 0x47, 0x86, 0xf2, 0x2b, 0xf8, 0x9f, 0xfb, 0x2b, 0x4b, 0x69, 0x94, 0x25, 0x40, 0xb2, 0xf5,
-            0xf0, 0x9f, 0xff, 0xed, 0x15, 0x45, 0x9f, 0x11, 0x01, 0x26, 0x75, 0x9e, 0x61, 0x6f, 0x8d, 0x52,
-            0x58, 0x87, 0x45, 0x07, 0x97, 0x25, 0x91, 0x13, 0x6e, 0x64, 0xfa, 0x69, 0x73, 0x0a, 0x68, 0x6f,
-            0x1a, 0x3a, 0x65, 0x93, 0xfe, 0xf1, 0x6c, 0x95, 0xd2, 0x2f, 0x4f, 0x0f, 0x29, 0xfb, 0xf2, 0x24,
-            0xa1, 0x04, 0x75, 0xed, 0xc9, 0x3f, 0x70, 0xed, 0x1f, 0xe1, 0x2a, 0xe5, 0x16, 0x1e, 0xf9, 0xff,
-            0xa2, 0x70, 0xd1, 0xb7, 0x85, 0x5d, 0x7e, 0x97, 0xa7, 0xbd, 0xb4, 0x9e, 0x2d, 0x81, 0xff, 0x9b,
-            0x2f, 0x1a, 0x33, 0xac, 0x7c, 0xe2, 0x44, 0xab, 0x1a, 0xef, 0xfb, 0x15, 0x65, 0x1f, 0xc1, 0x87,
-            0xd5, 0x0f, 0x34, 0xaf, 0x61, 0x6f, 0x86, 0xb0, 0x4b, 0x77, 0x95, 0xea, 0x7d, 0xdc, 0x01, 0xb1,
-            0xf8, 0x80, 0x5a, 0x6c, 0x8a, 0x6a, 0xc9, 0xa9, 0xa0, 0xaf, 0x5e, 0x99, 0xf5, 0x53, 0xc5, 0xde,
-            0xb4, 0x79, 0x76, 0x92, 0x50, 0x87, 0x06, 0x14, 0x60, 0x5c, 0x06, 0x55, 0x77, 0x42, 0x12, 0xe3,
-            0xbf, 0x0a, 0xde, 0x2c, 0x8f, 0x98, 0x04, 0x02, 0x74, 0xe2, 0x12, 0x78, 0xad, 0x5d, 0xe6, 0x40,
-            0x6d, 0xf2, 0x3c, 0x2f, 0x24, 0xe9, 0x17, 0xa5, 0x20, 0x87, 0x49, 0x19, 0x49, 0x33, 0xf1, 0x36,
-            0xbe, 0x86, 0x86, 0x47, 0xe5, 0x9e, 0x2c, 0x21, 0x87, 0x47, 0x3c, 0x76, 0xf0, 0x8f, 0x6f, 0x76,
-            0x70, 0x20, 0x3e, 0x0c, 0xc4, 0xa5, 0x2b, 0x63, 0x06, 0xe7, 0xec, 0xb9, 0x3f, 0x53, 0x6a, 0x9e,
-            0x23, 0x3b, 0x54, 0x62, 0xe4, 0xcd, 0x90, 0x62, 0x87, 0xba, 0xdb, 0x3c, 0x15, 0x24, 0x01, 0x63,
-            0x26, 0xc0, 0x47, 0xaf, 0x4a, 0x42, 0x4c, 0x56, 0x61, 0x01, 0x59, 0xb5, 0x01, 0xe3, 0xb7, 0xd2,
-            0xb3, 0xca, 0x44, 0x2d, 0x19, 0x3d, 0x62, 0xdb, 0x38, 0xc6, 0xa3, 0x79, 0x2b, 0x36, 0xb7, 0xfe,
-            0xa8, 0xca, 0x49, 0x9b, 0x02, 0x72, 0xc1, 0x03, 0x65, 0xf0, 0x67, 0xed, 0x64, 0x6f, 0x62, 0x93,
-            0xf9, 0x75, 0x78, 0xa4, 0xb5, 0x2d, 0xf8, 0x78, 0x67, 0xee, 0x67, 0xe2, 0x83, 0x11, 0x1f, 0xf1,
-            0x2f, 0x81, 0x98, 0x4e, 0xf6, 0xe3, 0x48, 0x05, 0xe5, 0x05, 0xd6, 0xfd, 0xbb, 0x99, 0x30, 0xd8,
-            0xed, 0x2b, 0xd1, 0x36, 0xb1, 0x04, 0x9b, 0xed, 0xfe, 0x16, 0xa8, 0x51, 0x93, 0x64, 0x4d, 0x53,
-            0xad, 0xc7, 0x8f, 0x6c, 0xb0, 0xbc, 0xce, 0x24, 0x36, 0xf4, 0xbf, 0x7f, 0xe1, 0x32, 0xdc, 0xa6,
-            0x34, 0x0a, 0xbd, 0x18, 0xf0, 0x8d, 0x46, 0x0d, 0x74, 0xf8, 0x69, 0xf6, 0xe6, 0xec, 0xc0, 0x8a,
-            0xeb, 0x84, 0xcd, 0x4a, 0xed, 0xab, 0xae, 0xb4, 0x6e, 0xc3, 0xad, 0x7a, 0x11, 0x73, 0xb2, 0x29,
-            0x32, 0x4f, 0xa8, 0xc6, 0x23, 0x59, 0xae, 0xb4, 0x81, 0x0b, 0xf6, 0x4b, 0x14, 0x90, 0x03, 0xaa,
-            0x2a, 0xaa, 0x14, 0xf4, 0xc5, 0xcd, 0xd6, 0xbd, 0x57, 0x82, 0x85, 0x2b, 0x84, 0x9d, 0x62, 0x41,
-            0x25, 0x35, 0xf6, 0xd9, 0x35, 0x26, 0x52, 0xb2, 0xfc, 0xa2, 0xbe, 0xe8, 0x63, 0x36, 0x35, 0xb1,
-            0xb4, 0x56, 0x57, 0x93, 0xb7, 0xff, 0xd4, 0x76, 0xb9, 0x44, 0x91, 0x5f, 0x96, 0x58, 0x2d, 0x99,
-            0x73, 0x87, 0xe6, 0x23, 0xbf, 0xe9, 0xa5, 0xb8, 0x6c, 0x56, 0x10, 0xc2, 0xfb, 0x06, 0xa3, 0xce,
-            0x65, 0x88, 0x32, 0x3d, 0xd1, 0xa8, 0xda, 0x8a, 0x8b, 0xeb, 0x3c, 0xe1, 0xed, 0xe3, 0xae, 0xd2,
-            0x78, 0xdc, 0x5e, 0x73, 0xe0, 0x2b, 0x7c, 0x8e, 0xc5, 0x79, 0xd5, 0xb0, 0xaa, 0x2b, 0x49, 0xb4,
-            0x78, 0x3e, 0x3e, 0x12, 0xea, 0x4b, 0xd1, 0x1e, 0x71, 0x92, 0x1d, 0xdf, 0x66, 0xfc, 0x0d, 0x8a,
-            0x47, 0x76, 0xf3, 0x93, 0x18, 0x8f, 0x6f, 0x8f, 0x38, 0x09, 0xc6, 0x0b, 0x06, 0x81, 0x8a, 0x14,
-            0xc9, 0xa5, 0x32, 0x30, 0xbd, 0x33, 0xd6, 0x86, 0x51, 0xf8, 0x69, 0x66, 0x75, 0x56, 0xc2, 0x82,
-            0xbb, 0x7f, 0x03, 0x28, 0x24, 0x1a, 0x62, 0x61, 0x9b, 0x24, 0x21, 0x21, 0xd0, 0x1f, 0x76, 0x63,
-            0x32, 0x6f, 0x5f, 0xbf, 0x3e, 0xb9, 0x58, 0xaf, 0x86, 0x20, 0x74, 0xfd, 0x81, 0xc8, 0xd5, 0x5a,
-            0x84, 0x9a, 0x15, 0x12, 0xf8, 0xfa, 0x9b, 0xaf, 0xc1, 0x56, 0xe0, 0x0b, 0x01, 0xd6, 0xaf, 0x9c,
-            0x26, 0x3e, 0x16, 0xc4, 0xe0, 0x91, 0x1c, 0xbe, 0x8e, 0xcb, 0xfc, 0xe6, 0x78, 0xeb, 0x2c, 0xae,
-            0xd2, 0x7e, 0x40, 0x0c, 0x8c, 0x5f, 0x0c, 0x66, 0xbc, 0x32, 0xb3, 0xfb, 0x95, 0xf9, 0xd0, 0x5b,
-            0xc2, 0x9e, 0xc8, 0x34, 0x42, 0xfb, 0x54, 0xa8, 0xa9, 0xc3, 0xb4, 0x48, 0xb7, 0x71, 0x03, 0x56,
-            0xc0, 0x9a, 0x56, 0x04, 0x62, 0x64, 0xb2, 0x93, 0x36, 0x02, 0x2c, 0x62, 0x1e, 0x03, 0x3d, 0x86,
-            0xbc, 0x4f, 0xdd, 0x5a, 0x37, 0xa7, 0x24, 0x61, 0x1b, 0x1c, 0x6d, 0xbb, 0x1a, 0x33, 0xc7, 0x7e,
-            0xeb, 0x93, 0x10, 0x59, 0xaf, 0x9e, 0x17, 0xb5, 0x31, 0x48, 0x5b, 0xdc, 0x19, 0x9d, 0xa4, 0xaf,
-            0xed, 0xbd, 0x12, 0xd7, 0xd7, 0x8d, 0xc1, 0xdc, 0xdc, 0x25, 0xb7, 0x01, 0x25, 0x38, 0x2c, 0x40,
-            0x21, 0xdb, 0x50, 0x7a, 0xab, 0x48, 0x82, 0xa0, 0x77, 0x48, 0x85, 0xec, 0xd7, 0x47, 0x08, 0xed,
-            0x3e, 0x28, 0x9f, 0x56, 0x04, 0x03, 0xce, 0x07, 0x4b, 0x1f, 0xf5, 0xd3, 0xf2, 0x3f, 0x83, 0xa0,
-            0x91, 0xe0, 0x1b, 0x21, 0xe1, 0x8b, 0x40, 0x8e, 0x93, 0x35, 0x07, 0x47, 0x94, 0x38, 0x95, 0x9f,
-            0xb9, 0x86, 0x74, 0x3a, 0x4a, 0xcf, 0xa1, 0xa5, 0x48, 0x89, 0xec, 0xc8, 0xaa, 0x9e, 0x96, 0x9d,
-            0x8b, 0x32, 0x91, 0x88, 0xd0, 0xb0, 0xa6, 0x58, 0x89, 0xd5, 0xcf, 0x88, 0xec, 0xf4, 0x30, 0xa7,
-            0x8a, 0x0c, 0xf9, 0xe5, 0xec, 0x4d, 0xf5, 0x9f, 0xb7, 0x73, 0x73, 0xe3, 0x5c, 0xfd, 0x93, 0xac,
-            0x4d, 0x8a, 0x5f, 0xed, 0xd7, 0x6b, 0xb4, 0xf4, 0xd3, 0xe7, 0xea, 0x7d, 0x25, 0x7c, 0x7e, 0xbd,
-            0x4d, 0xe4, 0x6a, 0xf3, 0x3f, 0x77, 0x89, 0x14, 0xd2, 0x7b, 0x78, 0xab, 0xfc, 0x5b, 0x91, 0x49,
-            0x4e, 0x07, 0x36, 0x67, 0x04, 0xde, 0x44, 0x81, 0x17, 0xb2, 0x07, 0x51, 0xd5, 0x79, 0x1f, 0x1e,
-            0xda, 0x76, 0x0d, 0xa4, 0x64, 0xe9, 0x0b, 0x6d, 0x71, 0xf6, 0xda, 0x32, 0x7d, 0xda, 0x62, 0x52,
-            0xdc, 0xeb, 0x0d, 0xe1, 0x49, 0x37, 0x30, 0xf4, 0x86, 0xc6, 0x69, 0x49, 0xfe, 0x4f, 0x13, 0x92,
-            0xf1, 0x8c, 0xb1, 0xe1, 0x71, 0xea, 0x54, 0x10, 0x99, 0xa9, 0x34, 0x53, 0xc5, 0x3e, 0x7c, 0x51,
-            0x25, 0x01, 0x45, 0xf6, 0x11, 0x6b, 0x2e, 0x5f, 0x72, 0x92, 0xfd, 0xd7, 0x74, 0x21, 0x1a, 0x52,
-            0xc8, 0xe1, 0x4c, 0xbb, 0x7f, 0xd9, 0x21, 0xf6, 0xa4, 0x9b, 0x9f, 0x6d, 0xaa, 0x01, 0x70, 0x6f,
-            0xba, 0x80, 0x99, 0x4f, 0xa8, 0x69, 0xa7, 0xa2, 0x4e, 0x41, 0xe7, 0xcc, 0xe4, 0x50, 0x95, 0x5a,
-            0x03, 0x11, 0x70, 0xd3, 0xed, 0x24, 0x26, 0x74, 0xa5, 0x2f, 0x99, 0x14, 0x02, 0xc1, 0x74, 0x07,
-            0x94, 0xeb, 0x74, 0x8f, 0xb5, 0x74, 0x28, 0x72, 0xa5, 0x07, 0xda, 0x87, 0x60, 0x37, 0x2c, 0xd4,
-            0xd3, 0x26, 0x78, 0xf6, 0x3e, 0xe3, 0x63, 0x75, 0x3f, 0x3a, 0x25, 0xeb, 0xba, 0x6e, 0xba, 0x8b,
-            0x02, 0xd9, 0x75, 0x5b, 0xb7, 0x83, 0x03, 0x2c, 0x8f, 0xab, 0xd5, 0xe5, 0xea, 0x2e, 0xd4, 0x16,
-            0x1c, 0xde, 0x8f, 0x60, 0x42, 0x4a, 0xfb, 0x90, 0x76, 0x7d, 0xa5, 0x0e, 0xc8, 0xc4, 0x46, 0xd3,
-            0xdd, 0x14, 0x05, 0x74, 0xbd, 0xbf, 0x5b, 0xab, 0x20, 0xcb, 0x91, 0x61, 0xa8, 0x3c, 0x71, 0x9f,
-            0xba, 0x47, 0x70, 0xba, 0xe6, 0x62, 0xa2, 0x8a, 0x6c, 0x6a, 0x13, 0xfd, 0x9c, 0x14, 0x41, 0x91,
-            0xd5, 0xce, 0x3a, 0x72, 0x2d, 0x3b, 0x9c, 0x01, 0xfb, 0x75, 0x31, 0x95, 0xde, 0x67, 0x1f, 0x14,
-            0x15, 0xf3, 0x80, 0x7c, 0x21, 0xd4, 0x0f, 0x18, 0x65, 0x88, 0x0a, 0x40, 0xb5, 0x85, 0x86, 0x0b,
-            0xc5, 0xdd, 0xad, 0xd6, 0xff, 0xb4, 0x71, 0x0d, 0x40, 0x59, 0xab, 0xd7, 0xc5, 0xa7, 0x59, 0x98,
-            0x9c, 0x72, 0xe6, 0x33, 0x21, 0xbc, 0xa3, 0x7e, 0x67, 0x7c, 0x58, 0x01, 0xfb, 0xe6, 0xa5, 0xac,
-            0xc7, 0xde, 0x24, 0x00, 0x8f, 0x58, 0x3c, 0x33, 0x05, 0x9b, 0x5a, 0x98, 0x3d, 0x16, 0xf1, 0xf2,
-            0x82, 0xb1, 0x3a, 0x91, 0x08, 0x31, 0x90, 0xf2, 0x9c, 0x37, 0x40, 0x87, 0x3f, 0x14, 0x1a, 0xf1,
-            0x0a, 0xeb, 0x50, 0x06, 0x5b, 0xe9, 0xe4, 0x80, 0xcb, 0x83, 0x27, 0x30, 0x18, 0x7e, 0x79, 0x76,
-            0x8a, 0x47, 0x54, 0xf0, 0xc0, 0xff, 0x18, 0x23, 0xf8, 0x79, 0x8c, 0xa3, 0x7b, 0x2b, 0x3c, 0x8b,
-            0x5f, 0x2b, 0x34, 0x92, 0x63, 0xb2, 0x92, 0x65, 0x6a, 0x26, 0x57, 0xbd, 0x73, 0xf4, 0x60, 0xff,
-            0xcb, 0x2c, 0xb6, 0xed, 0xfc, 0x9f, 0x5f, 0xd9, 0xa5, 0xc6, 0x9e, 0x7e, 0x6d, 0xd2, 0x99, 0xf4,
-            0xe1, 0xc4, 0xc0, 0xcd, 0xe8, 0x75, 0xcb, 0xb2, 0x62, 0xbc, 0x57, 0x00, 0xea, 0x16, 0xd2, 0x29,
-            0xea, 0xab, 0x9c, 0x5e, 0x51, 0x9e, 0x98, 0xed, 0x4d, 0x94, 0x22, 0x7a, 0x6e, 0x38, 0x8e, 0x03,
-            0x94, 0x4c, 0x1a, 0x32, 0xec, 0x44, 0x1e, 0x8e, 0x76, 0xac, 0x2d, 0x6d, 0x5d, 0xd5, 0x40, 0x8c,
-            0x5e, 0xb4, 0x8e, 0xa4, 0x79, 0x6c, 0x63, 0x56, 0xa2, 0xaa, 0xed, 0xe5, 0xa9, 0xb4, 0x3d, 0xe1,
-            0x05, 0x19, 0xaf, 0x44, 0xd9, 0xa6, 0xb5, 0x4a, 0xe3, 0x64, 0x55, 0x18, 0xbf, 0xa8, 0xa3, 0x75,
-            0xb5, 0x15, 0x3a, 0xb9, 0x63, 0x6e, 0x44, 0x3f, 0xc7, 0x19, 0x71, 0x64, 0x6f, 0x8b, 0xf0, 0x69,
-            0xa2, 0x02, 0x6b, 0xd4, 0x28, 0x63, 0x22, 0x87, 0xbb, 0x9b, 0xf2, 0xec, 0xc3, 0x45, 0x8c, 0x1f,
-            0xe9, 0x41, 0xd7, 0xc1, 0x20, 0x5a, 0x33, 0x7a, 0x77, 0x10, 0x37, 0x92, 0x8c, 0x93, 0x76, 0x1c,
-            0x4e, 0x58, 0x60, 0xb3, 0x11, 0xca, 0x28, 0x22, 0xc0, 0xaa, 0x0d, 0xb3, 0x12, 0xcb, 0x69, 0xc2,
-            0x4b, 0xc8, 0x38, 0xa8, 0x9e, 0x15, 0x12, 0x68, 0xba, 0xed, 0xf4, 0x69, 0x44, 0x10, 0xce, 0x85,
-            0xdc, 0xf9, 0x3a, 0xf5, 0x34, 0xd7, 0x08, 0xbf, 0xa7, 0x60, 0x0a, 0x48, 0xe2, 0x01, 0x94, 0x02,
-            0x1d, 0x9d, 0xd3, 0xc5, 0x2c, 0x67, 0x36, 0x98, 0x11, 0x69, 0x49, 0x58, 0x6f, 0x82, 0xa0, 0x9d,
-            0x74, 0xe9, 0x37, 0xc6, 0x30, 0x45, 0x90, 0xa9, 0xc8, 0xff, 0x58, 0xf0, 0x27, 0x48, 0x33, 0x69,
-            0xaa, 0x4b, 0xb7, 0xd7, 0x03, 0xba, 0x55, 0xde, 0x19, 0xf1, 0x95, 0x1a, 0xa6, 0xe9, 0xca, 0x96,
-            0x35, 0xa8, 0x91, 0x33, 0x33, 0x93, 0x87, 0x48, 0x39, 0x19, 0x72, 0x5e, 0x7e, 0x52, 0x40, 0xb1,
-            0xfe, 0x4a, 0xff, 0xdf, 0x63, 0xaa, 0xc4, 0x81, 0xa6, 0x03, 0xb7, 0x5c, 0xd7, 0x09, 0xd1, 0x64,
-            0x70, 0x92, 0xaa, 0xa2, 0x0a, 0x0e, 0x54, 0x11, 0xdc, 0x1d, 0xff, 0x1b, 0x1a, 0x77, 0x78, 0x2f,
-            0x27, 0x9e, 0x51, 0x0f, 0x72, 0x4d, 0x0e, 0x24, 0x29, 0x1c, 0x3b, 0xa1, 0x38, 0x1f, 0x79, 0x41,
-            0x0f, 0x56, 0x98, 0x4d, 0xa6, 0x51, 0x23, 0x2b, 0x71, 0xf9, 0xdd, 0xe4, 0x29, 0x42, 0x3f, 0xeb,
-            0xba, 0x4c, 0x75, 0x0f, 0x53, 0x65, 0xc1, 0x15, 0xae, 0xfb, 0x50, 0xd5, 0x20, 0x75, 0xd3, 0x49,
-            0x9b, 0xab, 0xc0, 0x9a, 0xd2, 0xf4, 0x8d, 0xc1, 0xd2, 0x65, 0xcf, 0x59, 0x03, 0x76, 0x86, 0xd4,
-            0x46, 0xfa, 0x81, 0x88, 0xc7, 0xd8, 0xd1, 0xe9, 0x42, 0x85, 0x24, 0x38, 0x1c, 0xeb, 0xa6, 0x3e,
-            0x5d, 0x1e, 0xb6, 0xa9, 0x70, 0xfb, 0x52, 0xc9, 0x4a, 0xfa, 0x75, 0x93, 0x24, 0x48, 0x34, 0x46,
-            0x0d, 0x32, 0x04, 0xab, 0x58, 0x78, 0xe8, 0xaf, 0xc7, 0x40, 0x49, 0x7b, 0xa3, 0xab, 0xc5, 0x33,
-            0xed, 0xe7, 0xb9, 0x10, 0xd2, 0xb7, 0x27, 0x22, 0x9c, 0x70, 0x4d, 0x0c, 0x47, 0xe7, 0xc1, 0x8d,
-            0x1a, 0x1f, 0xdf, 0x9e, 0xea, 0x14, 0xc8, 0xaf, 0xb7, 0x99, 0x4f, 0x31, 0xa1, 0x9f, 0xcd, 0xef,
-            0x09, 0x0f, 0x7c, 0xc8, 0x5a, 0x0f, 0xb2, 0x95, 0xff, 0x95, 0x3d, 0xc9, 0x3e, 0xb6, 0x94, 0x81,
-            0xdd, 0x8c, 0xbe, 0x39, 0x22, 0xd1, 0xe8, 0xc4, 0xf1, 0x64, 0xc7, 0xd1, 0x9d, 0xca, 0x0f, 0x77,
-            0x1b, 0x11, 0xa6, 0xc4, 0xea, 0xe7, 0x74, 0xfb, 0xfb, 0x56, 0xdc, 0x89, 0xe3, 0x27, 0x85, 0x98,
-            0x46, 0xa9, 0xd0, 0xdf, 0x4c, 0x9d, 0x76, 0xb7, 0x57, 0x72, 0xbc, 0x91, 0xac, 0xa6, 0x54, 0x06,
-            0x6e, 0xee, 0x9a, 0x65, 0x2c, 0xf6, 0x60, 0xb5, 0x31, 0x59, 0x16, 0x29, 0x61, 0x92, 0x99, 0x3e,
-            0x1b, 0x6c, 0x39, 0x47, 0xb9, 0x49, 0xcd, 0x51, 0x1d, 0x7a, 0x30, 0xc7, 0x4d, 0x34, 0x98, 0xb3,
-            0x6b, 0x38, 0x03, 0x61, 0x59, 0xe5, 0xa2, 0xdc, 0xc9, 0x8e, 0xb3, 0xd1, 0xd0, 0xbc, 0x44, 0x5f,
-            0x36, 0xee, 0x67, 0xd1, 0x2c, 0x8a, 0xd3, 0x54, 0x31, 0xa2, 0xe6, 0x2b, 0xec, 0x98, 0x58, 0xb6,
-            0x64, 0xa8, 0xac, 0xec, 0xae, 0xf2, 0x1b, 0x89, 0xd1, 0x9b, 0x02, 0x47, 0x7e, 0xc5, 0xf0, 0x10,
-            0x56, 0x66, 0x46, 0x8e, 0xd9, 0x06, 0x04, 0xaf, 0x2c, 0x94, 0xcc, 0x58, 0xb3, 0x10, 0xf7, 0x6c,
-            0xb9, 0x7b, 0x45, 0x74, 0x5f, 0x3d, 0x43, 0x5c, 0x19, 0x35, 0xc3, 0xc3, 0x35, 0x3c, 0x0f, 0xc6,
-            0x2a, 0xd7, 0x51, 0xf8, 0x82, 0x37, 0x36, 0x73, 0xd3, 0xff, 0x62, 0xec, 0x32, 0xd6, 0x56, 0x8a,
-            0x03, 0x92, 0xe2, 0x9c, 0xd4, 0x19, 0x9b, 0x84, 0x85, 0xf7, 0xe6, 0xcc, 0xc2, 0x02, 0x94, 0x57,
-            0x73, 0x58, 0x5b, 0xbd, 0x43, 0x63, 0x56, 0xd9, 0x3b, 0xa6, 0xe5, 0x3f, 0x6a, 0xba, 0x2f, 0x5b,
-            0x74, 0x38, 0x99, 0x80, 0xb1, 0x9a, 0x64, 0x82, 0xe7, 0xbc, 0x70, 0xf6, 0xe8, 0xb5, 0x33, 0xa2,
-            0xdb, 0x13, 0x90, 0xfd, 0xf6, 0xe4, 0x62, 0xc8, 0x69, 0x56, 0x3a, 0xbf, 0xbd, 0xdb, 0x44, 0xb9,
-            0x57, 0xc6, 0xb5, 0xc7, 0x6a, 0x05, 0x35, 0xd2, 0xb6, 0xc1, 0xdd, 0xda, 0xf5, 0xd2, 0x42, 0x97,
-            0xfb, 0x37, 0x2a, 0xa4, 0x87, 0xf6, 0x2c, 0x83, 0xc5, 0xd8, 0x30, 0x2e, 0x7e, 0x1f, 0xce, 0xe2,
-            0x5f, 0x01, 0x78, 0x52, 0x9c, 0x79, 0x3b, 0x1e, 0x0b, 0x06, 0x24, 0x5c, 0x13, 0xd3, 0xde, 0x58,
-            0x3f, 0xd9, 0xeb, 0xcf, 0x7b, 0x3e, 0xd9, 0x91, 0xab, 0xda, 0xf2, 0x40, 0xd3, 0xab, 0xf8, 0x01,
-            0x97, 0xb2, 0xb5, 0xb4, 0xbe, 0x3c, 0x95, 0xe7, 0xda, 0x1b, 0x8c, 0x81, 0x7b, 0x60, 0x05, 0xbf,
-            0xb4, 0x6c, 0x8d, 0x6d, 0x60, 0x5d, 0x5b, 0xc2, 0xdd, 0xa9, 0x9c, 0xfd, 0x89, 0xdd, 0x0e, 0x06,
-            0xd1, 0xa2, 0x1a, 0xd7, 0x72, 0xa8, 0x6c, 0xac, 0xfc, 0xd3, 0xdf, 0x57, 0x47, 0x80, 0xa2, 0x6e,
-            0xcf, 0xa3, 0x5e, 0x45, 0x96, 0x25, 0x4a, 0x31, 0x57, 0xe6, 0x51, 0x04, 0x40, 0xbd, 0x57, 0x94,
-            0xb6, 0x87, 0x1f, 0x0c, 0x4c, 0x29, 0xb7, 0x78, 0xc5, 0xc6, 0x8f, 0x23, 0xb3, 0xf6, 0x01, 0x8b,
-            0xdd, 0x68, 0x09, 0x25, 0x66, 0x0c, 0x49, 0xcf, 0x54, 0xd8, 0x67, 0x17, 0x04, 0x51, 0x97, 0x9d,
-            0xef, 0xac, 0x5c, 0x84, 0xe6, 0x63, 0xfa, 0x46, 0xd4, 0xc4, 0xb2, 0x4c, 0x37, 0x7b, 0x2b, 0x90,
-            0x74, 0x8a, 0xea, 0x8d, 0x58, 0x0a, 0xed, 0xbb, 0x6f, 0x71, 0x34, 0xe3, 0x4f, 0x37, 0x30, 0xd7,
-            0xe7, 0xba, 0xd6, 0xec, 0xda, 0xc3, 0xdd, 0x92, 0x4c, 0x91, 0x17, 0x7d, 0xc3, 0x11, 0x76, 0xbb,
-            0x82, 0x1a, 0xf4, 0xf0, 0xbb, 0x78, 0x02, 0x33, 0xef, 0x6c, 0x32, 0xf1, 0xb6, 0x72, 0x63, 0xb7,
-            0x5d, 0x61, 0x2e, 0x78, 0xe4, 0x75, 0x83, 0xf9, 0x79, 0x54, 0x68, 0x5c, 0x33, 0x7b, 0xe4, 0xe2,
-            0x1f, 0x0c, 0x64, 0x9a, 0x5f, 0xaa, 0xcd, 0x33, 0xd2, 0x43, 0xc6, 0xee, 0xb1, 0xa5, 0x28, 0x40,
-            0x4b, 0x72, 0x32, 0x14, 0x5b, 0xe7, 0x33, 0x15, 0x4e, 0xb5, 0x6b, 0xaf, 0x3f, 0xf1, 0xd8, 0x15,
-            0x64, 0x4e, 0x58, 0xb6, 0xd1, 0x84, 0xfc, 0x45, 0x9d, 0x39, 0xb2, 0x37, 0x2e, 0x1c, 0x7d, 0xf1,
-            0x91, 0x19, 0xdd, 0xf6, 0x7d, 0xc2, 0x67, 0x03, 0x1a, 0x49, 0x98, 0x1e, 0x2f, 0x8c, 0x3b, 0xaf,
-            0x2e, 0x32, 0x37, 0xa9, 0x34, 0xca, 0x22, 0xc7, 0x69, 0x1b, 0x24, 0x10, 0xf5, 0xd8, 0xe4, 0x59,
-            0x86, 0x74, 0xf7, 0xbc, 0xa0, 0x2e, 0x2e, 0xb8, 0x1e, 0xe0, 0x37, 0x60, 0x87, 0x23, 0x7a, 0x34,
-            0x5e, 0xe4, 0x8b, 0xc8, 0xe8, 0xd9, 0xb5, 0x0f, 0x81, 0xbd, 0xc3, 0x79, 0x4a, 0x20, 0x0f, 0xd3,
-            0x72, 0x6a, 0x8c, 0x68, 0x03, 0xe2, 0xce, 0x54, 0xe7, 0x20, 0x86, 0x3d, 0xf0, 0xc7, 0x38, 0x21,
-            0x8b, 0xba, 0xcc, 0x0e, 0x7f, 0x07, 0x2f, 0x8d, 0xe1, 0x9b, 0x9a, 0x11, 0xcd, 0x9d, 0xf0, 0x25,
-            0x64, 0xf6, 0x83, 0x6d, 0x5a, 0x36, 0xa3, 0x67, 0x4c, 0xb5, 0x63, 0x9c, 0x6f, 0x8e, 0xee, 0xcc,
-            0x64, 0x44, 0x6e, 0x8f, 0x5f, 0x25, 0x17, 0x03, 0x97, 0x61, 0xe1, 0x34, 0x20, 0x37, 0xe9, 0x5e,
-            0xc7, 0xdc, 0x65, 0x75, 0xb1, 0x4a, 0x9a, 0xcc, 0x37, 0x6e, 0x1d, 0x55, 0x00, 0x85, 0x5b, 0xe3,
-            0xd8, 0x17, 0x1f, 0x1d, 0xed, 0xb4, 0xe6, 0x99, 0xbe, 0x98, 0xb8, 0x08, 0x19, 0x2d, 0x70, 0xd7,
-            0x22, 0xe5, 0x52, 0x3e, 0x02, 0x9a, 0xe2, 0x71, 0x19, 0xcf, 0x7a, 0x6e, 0x19, 0x35, 0x24, 0x73,
-            0xf6, 0xdc, 0x75, 0xaa, 0xd2, 0x11, 0xb2, 0x7e, 0x00, 0x5a, 0xca, 0x2f, 0x39, 0xe1, 0x50, 0x50,
-            0x76, 0xd0, 0x8a, 0xd7, 0x51, 0xf4, 0x9d, 0x09, 0xca, 0x63, 0x5e, 0x4c, 0x0b, 0xf0, 0x9e, 0xd2,
-            0x52, 0xaf, 0xd2, 0x00, 0x12, 0xc0, 0x82, 0x75, 0xe4, 0xc0, 0x16, 0xc3, 0x74, 0xf5, 0x1d, 0x48,
-            0x03, 0x66, 0x55, 0xf8, 0x4d, 0xab, 0xc0, 0x9e, 0xc3, 0x86, 0xb8, 0xac, 0xbe, 0xef, 0xf7, 0x2b,
-            0x47, 0x52, 0x43, 0xd5, 0xcd, 0x8c, 0xfa, 0x08, 0x65, 0x77, 0xb2, 0xce, 0x25, 0xaf, 0x9f, 0x37,
-            0x50, 0xdc, 0x03, 0x45, 0x05, 0x4c, 0x58, 0x69, 0x87, 0x05, 0x30, 0x7e, 0xe4, 0xef, 0x0a, 0x04,
-            0x2b, 0x78, 0x79, 0xd1, 0x81, 0x67, 0x14, 0x69, 0x3b, 0xca, 0x2c, 0xb7, 0x62, 0xdd, 0xf7, 0xda,
-            0xd7, 0x34, 0x7e, 0xd7, 0x9d, 0x4f, 0x3a, 0xe1, 0x80, 0xc6, 0x85, 0xec, 0x78, 0x3a, 0x34, 0xcc,
-            0xf6, 0x24, 0x18, 0x8c, 0x88, 0x92, 0xc7, 0x4e, 0x4f, 0x8a, 0x73, 0xb8, 0x32, 0xed, 0x60, 0xb9,
-            0xcc, 0xc0, 0xc8, 0x7a, 0x55, 0x36, 0x94, 0x16, 0x51, 0xa7, 0x3a, 0x90, 0x99, 0x48, 0x6c, 0xb0,
-            0xc1, 0x47, 0x8b, 0x79, 0xd6, 0x23, 0x68, 0xb4, 0x6b, 0x36, 0x74, 0x84, 0xb3, 0x9f, 0x47, 0x77,
-            0xa2, 0x3e, 0x3e, 0x73, 0x0c, 0xde, 0x08, 0x4c, 0x22, 0x80, 0x82, 0xf1, 0xe4, 0x48, 0xfb, 0x7d,
-            0xa1, 0xf6, 0xd7, 0x47, 0x84, 0x32, 0x8e, 0x33, 0x3a, 0xf7, 0xbc, 0x66, 0xb6, 0xf1, 0x04, 0xeb,
-            0xe1, 0xd3, 0xd2, 0x9d, 0x6e, 0x78, 0x5c, 0x0f, 0x5e, 0xb3, 0x6f, 0xa7, 0x7d, 0x1d, 0xf8, 0xdd,
-            0x6d, 0xe7, 0xb0, 0xfa, 0xeb, 0xe6, 0x93, 0xc3, 0xdd, 0xc3, 0xcb, 0xff, 0xfe, 0xdf, 0xb2, 0xee,
-            0xf1, 0xea, 0x93, 0xc3, 0xcb, 0xcf, 0xe0, 0xe5, 0xd6, 0x6c, 0x40, 0x53, 0x2b, 0xbc, 0xcd, 0xca,
-            0xe1, 0xb7, 0xdb, 0xbb, 0x25, 0x57, 0xdf, 0xba, 0xc1, 0x6b, 0xf8, 0x0c, 0xa3, 0xd7, 0x6d, 0xbb,
-            0xad, 0x5c, 0x7f, 0xf9, 0x97, 0x64, 0xbf, 0xcd, 0x22, 0x72, 0x22, 0x30, 0x07, 0xab, 0x24, 0xa9,
-            0xc3, 0x7d, 0x50, 0x1c, 0x6a, 0x44, 0x1b, 0xbd, 0x80, 0x94, 0xae, 0x80, 0xb8, 0x81, 0x91, 0xe2,
-            0x60, 0xcd, 0x8f, 0xfe, 0xda, 0xcd, 0xbd, 0xdf, 0xe6, 0x66, 0x36, 0xff, 0x99, 0x17, 0x45, 0xdb,
-            0xe4, 0x4a, 0x3f, 0xa2, 0x91, 0xcb, 0x5e, 0x5e, 0x75, 0x4c, 0xef, 0x1a, 0x6b, 0x2b, 0x57, 0x4d,
-            0xec, 0xcd, 0xa9, 0x93, 0x70, 0x32, 0x37, 0x93, 0xf2, 0x99, 0x0a, 0xbe, 0x01, 0x0e, 0x55, 0x25,
-            0xdb, 0x3d, 0xe8, 0xfb, 0xa3, 0xeb, 0x28, 0x89, 0x87, 0x4d, 0x26, 0xa7, 0x62, 0x3d, 0x71, 0xb8,
-            0x9c, 0x00, 0xa5, 0x6c, 0xfc, 0x69, 0x53, 0xc4, 0x11, 0xee, 0xb2, 0x0c, 0x86, 0xd7, 0x26, 0xf0,
-            0x5d, 0x0d, 0x25, 0x3e, 0x36, 0xf3, 0xf9, 0x98, 0x8d, 0xdf, 0xfc, 0x75, 0x97, 0x77, 0x7b, 0x42,
-            0x72, 0xf6, 0x0b, 0x55, 0xe9, 0x77, 0x70, 0xa0, 0xd4, 0x56, 0xf2, 0x79, 0x68, 0x21, 0xd8, 0x6a,
-            0xc5, 0x84, 0x8f, 0xae, 0x1d, 0x23, 0xcc, 0x6c, 0x6c, 0x05, 0xac, 0x43, 0x02, 0x3c, 0xea, 0x4c,
-            0xdf, 0x48, 0x67, 0xa3, 0x4f, 0xec, 0x4a, 0x35, 0x3b, 0xc1, 0x9d, 0xe8, 0x8f, 0xd8, 0xfc, 0xc2,
-            0x18, 0x6d, 0x6b, 0x77, 0x8c, 0x5d, 0xae, 0x71, 0x8d, 0xb6, 0x69, 0xca, 0x98, 0x81, 0xdb, 0xb7,
-            0xb0, 0x96, 0x4f, 0x6f, 0x26, 0xee, 0xb7, 0xb4, 0x56, 0x0f, 0x8d, 0x1a, 0x23, 0xfe, 0xe9, 0x2e,
-            0x23, 0xd4, 0x8c, 0xdf, 0x3b, 0x50, 0x79, 0x9c, 0x36, 0x27, 0x78, 0xa2, 0xb1, 0x1e, 0x1d, 0x87,
-            0xf3, 0x42, 0x99, 0x1a, 0xde, 0xac, 0x05, 0x44, 0xe7, 0x56, 0xdf, 0xbd, 0x22, 0xfe, 0x8d, 0xd6,
-            0xfc, 0x10, 0xe0, 0xbc, 0xa8, 0xfb, 0x7d, 0x28, 0x20, 0xa0, 0x93, 0xc4, 0xc6, 0x18, 0x0c, 0xa9,
-            0xb3, 0x69, 0x2c, 0xeb, 0x01, 0x9a, 0xa1, 0x2e, 0xff, 0xb6, 0x42, 0x24, 0x93, 0xa0, 0x58, 0xab,
-            0x47, 0x56, 0xb0, 0x3f, 0x5b, 0x78, 0xc1, 0xf0, 0x0e, 0x7a, 0x68, 0x06, 0xb7, 0xa4, 0x3a, 0xde,
-            0x31, 0xbf, 0xe6, 0x6a, 0xc0, 0xb1, 0xa8, 0xae, 0x0d, 0xe3, 0x67, 0x7c, 0x68, 0x3e, 0xbc, 0x76,
-            0x29, 0x53, 0xef, 0x38, 0x7a, 0xcd, 0xb0, 0x77, 0x60, 0xf0, 0x31, 0x5b, 0xa6, 0x6c, 0x35, 0x6c,
-            0x7e, 0xdd, 0xba, 0x80, 0x95, 0x89, 0xb1, 0x67, 0x34, 0x5a, 0xe3, 0x79, 0x3a, 0xbe, 0xfc, 0xd8,
-            0x7f, 0x92, 0x8f, 0xbe, 0x2d, 0x52, 0x32, 0xbe, 0x16, 0x33, 0x32, 0xb2, 0x99, 0x32, 0x41, 0x7e,
-            0x66, 0xf6, 0xb9, 0x45, 0x70, 0xf3, 0x1d, 0x44, 0xdd, 0x6a, 0x09, 0xcc, 0xc2, 0x0d, 0x88, 0xe2,
-            0xf7, 0x08, 0x33, 0x05, 0xe4, 0xea, 0x4d, 0xc4, 0x66, 0xf5, 0xdf, 0x21, 0x50, 0x30, 0x38, 0xeb,
-            0xfb, 0x4b, 0x08, 0x77, 0xe1, 0x4a, 0x63, 0xaa, 0xa7, 0xb0, 0x45, 0xe0, 0xe7, 0xe6, 0x4e, 0xfb,
-            0x9f, 0xd7, 0x16, 0x2d, 0x12, 0x3b, 0x04, 0x2d, 0x27, 0xa2, 0x6a, 0xd9, 0x4a, 0xa3, 0xb1, 0x64,
-            0x2c, 0x8b, 0x61, 0x49, 0xbb, 0x19, 0x95, 0x78, 0x6b, 0x67, 0x3a, 0x9e, 0xb0, 0x79, 0xbe, 0x2f,
-            0xd6, 0x9c, 0x18, 0x0d, 0x06, 0x3f, 0x95, 0x5f, 0x12, 0x3f, 0xe5, 0x5c, 0x66, 0x0b, 0x00, 0x68,
-            0x1c, 0x8d, 0x0c, 0x7c, 0xe2, 0xa6, 0x1f, 0xa5, 0x75, 0x21, 0x8d, 0x94, 0x86, 0xc1, 0x4f, 0xbd,
-            0x41, 0x2e, 0x5e, 0x9e, 0x8e, 0xb7, 0x9f, 0x0e, 0x90, 0x1b, 0xe5, 0xf4, 0x97, 0x2b, 0xc4, 0x5a,
-            0x81, 0x26, 0x0a, 0x79, 0xcf, 0x6c, 0x66, 0x33, 0x5f, 0xb7, 0x10, 0x60, 0xe8, 0x8b, 0x83, 0x9f,
-            0x21, 0x23, 0x00, 0xe7, 0xc7, 0x91, 0x36, 0x27, 0xaa, 0xec, 0xec, 0x73, 0x2f, 0x64, 0x17, 0x3e,
-            0xe0, 0x41, 0xd9, 0x8f, 0x39, 0xaa, 0x37, 0xbe, 0xd0, 0xe3, 0xd2, 0x3b, 0x2e, 0x79, 0x8c, 0x52,
-            0xd7, 0xea, 0xf5, 0x0a, 0x55, 0xe5, 0xb9, 0xfb, 0xe1, 0x82, 0x3e, 0x61, 0x9f, 0x05, 0x00, 0x4c,
-            0x6c, 0xca, 0xbe, 0x24, 0x47, 0xa6, 0xda, 0xb6, 0x84, 0x3b, 0xa8, 0xeb, 0x91, 0x96, 0x5a, 0x9f,
-            0x1c, 0x09, 0xbc, 0x60, 0x2e, 0x7e, 0x4e, 0x9e, 0xf9, 0x22, 0x4e, 0x60, 0x9a, 0x4c, 0x3f, 0x62,
-            0x73, 0x5c, 0x1b, 0x6c, 0x7d, 0x75, 0xbc, 0x54, 0xae, 0x51, 0x19, 0x0f, 0x42, 0xf5, 0x4b, 0x3c,
-            0xf9, 0x92, 0xd8, 0xea, 0x31, 0x22, 0xab, 0x36, 0x8c, 0xd6, 0x41, 0x0b, 0x34, 0x66, 0x89, 0x88,
-            0x92, 0xaa, 0x05, 0x42, 0x9e, 0x24, 0x17, 0x2a, 0xf8, 0xaf, 0xf6, 0xd7, 0x34, 0x9a, 0x0d, 0xe1,
-            0x9d, 0xbd, 0x55, 0x2a, 0x50, 0x9c, 0xc5, 0xae, 0x2a, 0x0c, 0xf4, 0x43, 0x05, 0xe6, 0x0a, 0xfd,
-            0x84, 0xb1, 0x8f, 0x76, 0xfd, 0x78, 0x66, 0xbf, 0xa4, 0xba, 0x1d, 0xf2, 0x8c, 0x6a, 0xd5, 0x5f,
-            0x54, 0x9c, 0x80, 0xae, 0xa7, 0x00, 0x9a, 0xc6, 0x13, 0x53, 0x23, 0xc1, 0x3b, 0xa8, 0x19, 0x98,
-            0xc6, 0x15, 0xe7, 0x62, 0x50, 0x4f, 0x0c, 0xe8, 0x82, 0x87, 0xc7, 0x0d, 0x92, 0x5a, 0x95, 0x49,
-            0xf2, 0xf7, 0x5a, 0x07, 0x98, 0x81, 0xfd, 0x21, 0x0f, 0xcf, 0x4c, 0x5f, 0xaf, 0x6b, 0x14, 0xd0,
-            0x67, 0x89, 0xd4, 0x92, 0x5b, 0xf9, 0xd6, 0x9c, 0x0b, 0x1a, 0xb6, 0x29, 0x18, 0x4f, 0xb8, 0x26,
-            0xf7, 0x5c, 0x4d, 0xbb, 0x35, 0x87, 0x8e, 0x01, 0x38, 0xb0, 0x65, 0x15, 0x4c, 0x99, 0x2b, 0x7e,
-            0xec, 0x8a, 0x67, 0xd0, 0xbc, 0xec, 0x80, 0xb0, 0x8c, 0x1c, 0xd6, 0xa5, 0x96, 0xe2, 0xc3, 0xdb,
-            0xe0, 0x3b, 0xb3, 0x76, 0x80, 0xf9, 0xf9, 0x22, 0x4c, 0x34, 0x40, 0xd5, 0x0d, 0x9b, 0xe3, 0x07,
-            0x2d, 0x77, 0x6d, 0x6d, 0x31, 0x81, 0x8f, 0xec, 0x0d, 0x64, 0x9c, 0xbb, 0xcf, 0x79, 0x3d, 0x52,
-            0xca, 0x3b, 0xe1, 0x1c, 0x73, 0xab, 0x0a, 0xce, 0x2a, 0xdc, 0xd5, 0x80, 0x7a, 0xcd, 0xda, 0xfe,
-            0xbc, 0x83, 0xa5, 0x03, 0xd2, 0x12, 0x7f, 0xcd, 0x69, 0x4f, 0x42, 0x7a, 0xd0, 0x54, 0x3f, 0xa6,
-            0xd4, 0x21, 0x47, 0x80, 0x1c, 0x20, 0xc0, 0xd2, 0x84, 0x18, 0x47, 0x7e, 0x50, 0xbf, 0x93, 0x70,
-            0xf7, 0xdf, 0xb3, 0x2e, 0x30, 0xc1, 0xa7, 0x82, 0x5b, 0xfd, 0x91, 0xba, 0x0f, 0x83, 0xec, 0xdb,
-            0x59, 0xbb, 0x7d, 0xd7, 0x13, 0x36, 0x89, 0x1a, 0x0c, 0x69, 0x28, 0x61, 0x0f, 0x24, 0xef, 0x3c,
-            0x14, 0xf7, 0x2f, 0x6a, 0x8e, 0x14, 0x3f, 0xba, 0x3b, 0x7d, 0x04, 0xfa, 0xfd, 0x9e, 0x2d, 0xaa,
-            0x21, 0xb3, 0x72, 0x18, 0x56, 0xe0, 0xca, 0xfd, 0x3e, 0x37, 0xe1, 0x81, 0xb8, 0x69, 0xf1, 0x62,
-            0x6b, 0xb4, 0x62, 0x59, 0x97, 0xd7, 0x0a, 0x6b, 0x09, 0xd7, 0x54, 0x69, 0x76, 0xca, 0x02, 0xbf,
-            0x6f, 0x64, 0x96, 0x44, 0xa3, 0x0d, 0x91, 0xa3, 0x75, 0x9f, 0xc9, 0x6c, 0x1a, 0xaf, 0xbd, 0x2e,
-            0x18, 0x26, 0x64, 0x86, 0xca, 0xa0, 0x0f, 0x9e, 0x13, 0x71, 0x0a, 0xf7, 0x97, 0x64, 0x17, 0xb3,
-            0x41, 0x14, 0xac, 0x78, 0xa6, 0x0d, 0xba, 0x03, 0xd3, 0x51, 0xc0, 0x25, 0x76, 0xcf, 0xc9, 0x74,
-            0x01, 0x9a, 0x3c, 0x03, 0xfa, 0x37, 0x7a, 0x1e, 0xaa, 0x1d, 0x62, 0x04, 0xca, 0xf5, 0x01, 0xdb,
-            0xd8, 0x40, 0x97, 0x72, 0x55, 0x51, 0x44, 0xaf, 0xc7, 0xf5, 0xe3, 0xcc, 0x46, 0xc3, 0x92, 0x78,
-            0xa1, 0x12, 0x73, 0x50, 0xfa, 0x2a, 0x72, 0x1a, 0x72, 0xbf, 0xe0, 0x79, 0x9f, 0x82, 0x86, 0x4b,
-            0x40, 0xf4, 0x74, 0x4f, 0x95, 0x0e, 0x77, 0x7f, 0x96, 0x10, 0xa4, 0xc7, 0xbc, 0xc4, 0x3c, 0x92,
-            0x69, 0x19, 0x39, 0xc1, 0x9d, 0x80, 0x65, 0x63, 0xba, 0xeb, 0x1a, 0xd2, 0x41, 0x7c, 0x19, 0x05,
-            0xfb, 0x9c, 0xa6, 0x7d, 0x1b, 0xef, 0x2e, 0x9f, 0x3d, 0x3e, 0x0c, 0x93, 0x57, 0x32, 0xaa, 0xb0,
-            0xd8, 0x3d, 0x15, 0xa6, 0x74, 0x4c, 0x53, 0x0b, 0x80, 0x28, 0x67, 0xa9, 0x66, 0x72, 0xab, 0x3b,
-            0x1b, 0x94, 0xcf, 0x62, 0x1f, 0x5e, 0xcd, 0x34, 0x50, 0x4c, 0x0c, 0x8f, 0xaa, 0x69, 0xe6, 0x94,
-            0x34, 0x96, 0xf6, 0x32, 0x67, 0x85, 0xa0, 0x80, 0x23, 0x06, 0xf6, 0x9e, 0x54, 0x2c, 0x4d, 0x00,
-            0x48, 0x70, 0x6e, 0xd5, 0x56, 0x12, 0x33, 0x1b, 0xc3, 0x36, 0x71, 0x80, 0x64, 0xe2, 0x5a, 0xa2,
-            0x83, 0x77, 0x68, 0xd3, 0x04, 0x18, 0x0d, 0x7e, 0x77, 0x24, 0xc8, 0x15, 0x39, 0x45, 0xb1, 0x56,
-            0x97, 0xdd, 0xe1, 0x3d, 0xdb, 0xee, 0x9b, 0x7b, 0xe3, 0xa2, 0x95, 0x60, 0x03, 0x8d, 0xe2, 0x7e,
-            0xd9, 0xaf, 0xa0, 0x02, 0x0d, 0xd1, 0xa0, 0x73, 0x28, 0x71, 0x15, 0x71, 0x1a, 0xb4, 0xea, 0xa1,
-            0xd0, 0x72, 0x6d, 0xc8, 0x26, 0x20, 0x20, 0x54, 0xc5, 0x95, 0xf3, 0x13, 0xa9, 0xc0, 0x0d, 0xa7,
-            0x29, 0x15, 0x15, 0xb6, 0xa1, 0xfb, 0xd3, 0x4a, 0xc3, 0x1d, 0x7e, 0x36, 0x95, 0x67, 0x2b, 0x59,
-            0x03, 0xed, 0x76, 0xd9, 0x5c, 0x63, 0xbb, 0x1a, 0x28, 0x44, 0xcc, 0xa5, 0x1e, 0x6b, 0x1e, 0xab,
-            0xb8, 0x13, 0x82, 0x31, 0x62, 0x13, 0x06, 0xc9, 0x1a, 0x13, 0xc2, 0x5c, 0x54, 0xa9, 0xb1, 0xa3,
-            0x1d, 0x41, 0x25, 0xb6, 0xa9, 0x25, 0x87, 0x2d, 0xae, 0xbc, 0x88, 0x7a, 0xe2, 0xdd, 0x60, 0xc3,
-            0x9c, 0x46, 0x0d, 0x65, 0x5e, 0x26, 0x6c, 0x49, 0xd4, 0x90, 0x4f, 0xc0, 0x41, 0xee, 0x57, 0x16,
-            0xe8, 0x22, 0xcc, 0xc6, 0xee, 0x2c, 0x2c, 0xf8, 0x33, 0xa4, 0x2b, 0xa1, 0xe8, 0x24, 0x3b, 0x31,
-            0x69, 0xb8, 0x2c, 0xc6, 0xd7, 0x7f, 0xe6, 0xc2, 0xcf, 0x14, 0xef, 0xce, 0x28, 0xb2, 0x83, 0x63,
-            0x58, 0x7f, 0xd0, 0x73, 0x3f, 0x95, 0xff, 0x0d, 0x8a, 0x00, 0xd9, 0xa1, 0x40, 0xfa, 0xb4, 0x00,
-            0x0d, 0x24, 0xe8, 0x3f, 0x96, 0xd1, 0x10, 0xde, 0x1c, 0xe3, 0x65, 0xa5, 0x88, 0xe0, 0x53, 0x4d,
-            0x4b, 0xd3, 0x80, 0x3e, 0xd4, 0x23, 0x6e, 0xda, 0x99, 0x86, 0x7c, 0x90, 0x8a, 0x79, 0x32, 0x8d,
-            0xa3, 0xc8, 0x1a, 0x23, 0x9b, 0x34, 0x96, 0x36, 0x94, 0xc5, 0x2f, 0x95, 0x15, 0x02, 0x81, 0xc1,
-            0xb5, 0x83, 0x7c, 0x93, 0x46, 0x0c, 0x8c, 0x69, 0x23, 0x26, 0xaf, 0x45, 0x0a, 0x22, 0xac, 0xf3,
-            0xa2, 0x83, 0x3a, 0x4c, 0x87, 0x6a, 0x46, 0x8d, 0x14, 0xda, 0xe0, 0x54, 0x9e, 0xb9, 0x7b, 0x7c,
-            0x29, 0x89, 0xc3, 0xd7, 0xee, 0x27, 0xcd, 0xbe, 0xe3, 0x55, 0x7a, 0xa3, 0xf3, 0x01, 0x57, 0xc3,
-            0x10, 0x4c, 0xb6, 0x15, 0x01, 0x7b, 0x9c, 0xd9, 0x87, 0x93, 0x38, 0x58, 0xc0, 0x5a, 0x9c, 0xfc,
-            0xa5, 0x3e, 0x64, 0x54, 0x81, 0x1f, 0x51, 0x99, 0x45, 0x2b, 0xb3, 0x3e, 0xe3, 0x9c, 0x96, 0x57,
-            0x2b, 0x67, 0x04, 0x20, 0x95, 0x49, 0xb0, 0x52, 0x9f, 0xb5, 0x41, 0xe8, 0xd7, 0xee, 0xe4, 0x95,
-            0x6a, 0x97, 0xcb, 0x03, 0xb5, 0x14, 0x47, 0x6d, 0x13, 0x1c, 0x66, 0xe2, 0x15, 0x1d, 0x2d, 0xcf,
-            0x95, 0x2b, 0xe8, 0xa6, 0xa4, 0x6a, 0xa4, 0x96, 0x69, 0xf6, 0xc1, 0xe8, 0x00, 0x3a, 0x85, 0x64,
-            0x52, 0xd9, 0x6b, 0x52, 0xa2, 0x5f, 0xd5, 0x27, 0x61, 0x2a, 0x2f, 0xf1, 0x27, 0x62, 0xd7, 0x65,
-            0xbb, 0x25, 0xdb, 0xc8, 0xa7, 0xd0, 0xfd, 0xaa, 0x16, 0x64, 0xcd, 0x96, 0xe2, 0xe8, 0x58, 0x5c,
-            0xca, 0xef, 0x81, 0x17, 0x42, 0xe3, 0xb6, 0xc8, 0xd3, 0x28, 0xad, 0x4a, 0x9e, 0xff, 0x54, 0xa5,
-            0x98, 0xe4, 0xc7, 0x8c, 0x14, 0xb7, 0xe2, 0xf4, 0x58, 0x5c, 0x12, 0x37, 0x89, 0x85, 0x54, 0x48,
-            0xba, 0xab, 0x01, 0xae, 0x9e, 0xb2, 0x0e, 0x05, 0x8f, 0x10, 0x41, 0x75, 0xef, 0x1d, 0x10, 0x6c,
-            0x28, 0xf3, 0x35, 0x53, 0x69, 0x5d, 0x9b, 0xe0, 0xee, 0x72, 0xa6, 0xca, 0x29, 0xf4, 0xa8, 0x34,
-            0x3c, 0x6b, 0xe0, 0x56, 0x10, 0x1f, 0x4d, 0xa1, 0x21, 0xd3, 0xa8, 0xab, 0xf2, 0x76, 0x5a, 0x20,
-            0x43, 0x80, 0x38, 0x53, 0x4e, 0xe1, 0x77, 0xb1, 0xc9, 0xab, 0xa0, 0xc4, 0xa0, 0xa5, 0x7d, 0xf4,
-            0xec, 0x7d, 0x71, 0x18, 0x76, 0x99, 0x14, 0x55, 0x55, 0xc3, 0xc4, 0x52, 0x23, 0x77, 0x84, 0xb1,
-            0x7b, 0xba, 0xc9, 0x4f, 0xe8, 0xa6, 0xd8, 0x23, 0x4d, 0x22, 0xfe, 0x45, 0xf6, 0x3c, 0xdf, 0x2e,
-            0x02, 0xf8, 0x7a, 0x55, 0x9c, 0xd4, 0xc6, 0xd4, 0x09, 0x94, 0xda, 0x21, 0x5b, 0x1c, 0xcd, 0xc9,
-            0xbf, 0xd7, 0x87, 0xc7, 0xc3, 0xce, 0x0e, 0x35, 0xed, 0xe5, 0x3e, 0x9c, 0x86, 0xe2, 0xc3, 0x45,
-            0x81, 0xe4, 0x38, 0x5f, 0x3f, 0x45, 0x4c, 0x1d, 0x91, 0x05, 0x19, 0x02, 0x49, 0x6b, 0xc0, 0x1a,
-            0x60, 0x40, 0xec, 0xc6, 0x1f, 0x66, 0xd9, 0x73, 0x8c, 0x73, 0x29, 0xf1, 0x9d, 0x38, 0xf2, 0x63,
-            0x92, 0x2d, 0x22, 0x77, 0x29, 0x77, 0xb6, 0xba, 0x02, 0x63, 0x41, 0x28, 0x01, 0xc5, 0x70, 0xdb,
-            0x5d, 0x90, 0xb6, 0x32, 0x8f, 0x97, 0xfa, 0x08, 0xe7, 0x71, 0xd9, 0xca, 0x59, 0x19, 0xbc, 0xbc,
-            0xba, 0xf9, 0x90, 0x71, 0x37, 0x6a, 0x91, 0x5e, 0x6f, 0x15, 0xdb, 0x5f, 0xe9, 0x7f, 0x05, 0x98,
-            0x19, 0x33, 0x44, 0x33, 0xaa, 0x77, 0x38, 0x8f, 0x98, 0xc4, 0xa5, 0x88, 0x5c, 0x75, 0x1f, 0x4b,
-            0x14, 0x7f, 0x26, 0xa9, 0x16, 0x68, 0x2c, 0xd4, 0xf1, 0x0d, 0xda, 0x00, 0x39, 0x5b, 0x93, 0xf6,
-            0x3b, 0x41, 0x6a, 0xed, 0xfd, 0x99, 0x4c, 0x59, 0x8b, 0x95, 0x39, 0xe2, 0x99, 0x07, 0xcf, 0x90,
-            0x89, 0x48, 0xb6, 0xef, 0xb7, 0x14, 0xa6, 0x34, 0x46, 0x3c, 0xcd, 0xcb, 0x8e, 0x0a, 0xf8, 0xd5,
-            0x58, 0x29, 0xb5, 0xaa, 0x7b, 0xe2, 0x75, 0xe5, 0xf6, 0x53, 0x09, 0x32, 0x01, 0x3b, 0x27, 0x2c,
-            0x74, 0x3c, 0xfa, 0x0e, 0x6e, 0x67, 0x94, 0x33, 0xb1, 0x88, 0x79, 0xea, 0xb2, 0x8e, 0xed, 0xa6,
-            0x30, 0x0d, 0xb0, 0xed, 0xc2, 0x7f, 0x8b, 0xf7, 0x00, 0x2f, 0xec, 0xc4, 0x33, 0x95, 0x9c, 0xe8,
-            0xe0, 0x3c, 0x65, 0xd7, 0xbb, 0x72, 0xe8, 0x8c, 0x8a, 0x22, 0xe9, 0x50, 0xce, 0x83, 0xda, 0x47,
-            0xe3, 0xc8, 0xef, 0x6d, 0x6d, 0x12, 0xca, 0xee, 0x11, 0x5e, 0x44, 0x1a, 0x02, 0xfe, 0xc4, 0x41,
-            0x4d, 0x08, 0xaa, 0x5e, 0xcc, 0xd0, 0x7d, 0x24, 0x5d, 0xb0, 0xd5, 0xf2, 0xfc, 0xf5, 0xbc, 0x78,
-            0xd0, 0x2c, 0xdd, 0x0f, 0x35, 0x65, 0x93, 0x10, 0xdd, 0x6c, 0x91, 0x76, 0x86, 0x9d, 0x6e, 0x81,
-            0xe6, 0x71, 0x5b, 0x79, 0x03, 0xb5, 0xb3, 0x17, 0x79, 0xe2, 0xfc, 0x41, 0x01, 0x43, 0x38, 0x3e,
-            0x5d, 0xc1, 0x54, 0x38, 0x58, 0x64, 0xf8, 0x88, 0x8b, 0x4d, 0x0a, 0xeb, 0x94, 0x5e, 0x72, 0x03,
-            0xde, 0xf9, 0x0a, 0x65, 0x48, 0x86, 0xf6, 0x86, 0xa3, 0xfe, 0x06, 0x50, 0x69, 0x4b, 0xa4, 0x29,
-            0x52, 0xae, 0x43, 0xc7, 0xa4, 0xa3, 0x31, 0xc8, 0xdf, 0xda, 0x2d, 0x9a, 0x87, 0x86, 0x6a, 0x1f,
-            0x99, 0xeb, 0x70, 0x17, 0xb7, 0x35, 0x31, 0x4b, 0x61, 0xc8, 0xc8, 0x5f, 0x7b, 0x47, 0xfb, 0x0c,
-            0x5d, 0x5c, 0x17, 0xa9, 0x79, 0x8b, 0x7a, 0x69, 0xca, 0x23, 0x29, 0x48, 0xdb, 0x9a, 0xfc, 0xf1,
-            0x0c, 0x95, 0x43, 0x03, 0x73, 0x9a, 0x0e, 0x23, 0xd2, 0x46, 0xd3, 0x0f, 0x29, 0x2c, 0x30, 0x3a,
-            0x31, 0xf2, 0x12, 0x77, 0xf1, 0xb6, 0x91, 0xa7, 0x4b, 0x75, 0x8e, 0x84, 0xf5, 0x82, 0xfd, 0xe8,
-            0x76, 0xcd, 0x09, 0x9f, 0x16, 0x35, 0x91, 0x5e, 0xac, 0xc3, 0x7e, 0x6c, 0x63, 0x32, 0xcb, 0xb1,
-            0xfe, 0xa9, 0x63, 0x5e, 0x39, 0x28, 0x1e, 0x97, 0xb3, 0xf6, 0xff, 0xb3, 0x76, 0x5d, 0x47, 0xa1,
-            0x3f, 0xf7, 0x89, 0x90, 0xe0, 0xeb, 0x48, 0x6a, 0x2b, 0xb1, 0xa7, 0x0f, 0xe1, 0xd5, 0x13, 0xa7,
-            0x4d, 0x7c, 0xf2, 0x69, 0xe5, 0xa9, 0x0a, 0xed, 0x8a, 0xbc, 0x5c, 0x96, 0x77, 0x7b, 0x33, 0xce,
-            0xd7, 0xbb, 0x64, 0x46, 0x71, 0x8f, 0x75, 0x14, 0x05, 0x1c, 0x5e, 0x2c, 0x8b, 0x8f, 0xee, 0x6e,
-            0x9d, 0x89, 0xef, 0x04, 0x93, 0x05, 0x2a, 0x5d, 0x16, 0x50, 0x69, 0x9f, 0x03, 0x55, 0x48, 0x8d,
-            0x85, 0x15, 0x7e, 0x18, 0x12, 0xc1, 0x0a, 0xd4, 0x1e, 0x17, 0xa9, 0xeb, 0x05, 0x49, 0xeb, 0x2a,
-            0x4f, 0xc3, 0xe3, 0x9a, 0x1f, 0x6c, 0x8b, 0xe4, 0x63, 0xfc, 0xc6, 0x2f, 0xc2, 0xb9, 0x34, 0xf0,
-            0x20, 0x56, 0xce, 0x52, 0x99, 0xde, 0x30, 0xb9, 0xeb, 0xff, 0xca, 0x86, 0xff, 0x58, 0x2d, 0xb9,
-            0xef, 0xec, 0x56, 0x2f, 0x8c, 0xdc, 0xe5, 0xf8, 0x7e, 0x38, 0x34, 0xbf, 0xd4, 0xce, 0xde, 0xa1,
-            0x2f, 0x70, 0x70, 0x7c, 0xcd, 0xb4, 0x1d, 0x25, 0x8b, 0x53, 0xed, 0x3e, 0xb3, 0x6c, 0xe6, 0xa4,
-            0xb3, 0x4c, 0x15, 0x7b, 0x18, 0x69, 0x55, 0x93, 0x9e, 0x34, 0x5b, 0x82, 0x3a, 0xb6, 0xb0, 0x19,
-            0x86, 0x0c, 0x69, 0xf6, 0x4c, 0x13, 0x7e, 0x84, 0xc8, 0xd2, 0xfd, 0xb8, 0x69, 0xbe, 0x91, 0x7d,
-            0xda, 0x9c, 0xc4, 0xfd, 0x5f, 0x18, 0x04, 0x87, 0x03, 0x67, 0x28, 0x9f, 0x57, 0xf9, 0x8f, 0x99,
-            0x97, 0x8a, 0x93, 0x4d, 0x82, 0x88, 0x07, 0xdb, 0xb9, 0xdf, 0x4c, 0x3c, 0x71, 0xe2, 0x51, 0x32,
-            0x29, 0xf5, 0x6b, 0x11, 0xdf, 0x9a, 0xdd, 0x22, 0x3c, 0xdb, 0xf4, 0x0c, 0x69, 0xa3, 0x0a, 0x2d,
-            0x7e, 0x54, 0xd2, 0xc6, 0xfa, 0x4d, 0x25, 0x98, 0x99, 0x18, 0x8f, 0x21, 0x63, 0x7f, 0x66, 0x2e,
-            0x6a, 0x8e, 0xd7, 0x88, 0x89, 0x7d, 0x3a, 0xf2, 0x09, 0x1e, 0x7e, 0x04, 0xfa, 0x6b, 0x1b, 0xe4,
-            0xfa, 0x0f, 0x09, 0x1d, 0xd8, 0x66, 0xe6, 0x9a, 0xf0, 0xad, 0x3e, 0x91, 0xd9, 0xf1, 0x28, 0x6c,
-            0x16, 0xd0, 0xca, 0x9b, 0x2e, 0xc3, 0x5a, 0x1b, 0x26, 0xb5, 0x36, 0x11, 0xa4, 0x28, 0xe3, 0x59,
-            0xce, 0xc4, 0xc3, 0x7a, 0x9a, 0xd7, 0x8a, 0xf9, 0xd6, 0x38, 0x51, 0x9a, 0xdc, 0xe8, 0xac, 0xb0,
-            0xfd, 0xb2, 0xb7, 0x04, 0x20, 0x3e, 0x83, 0x5f, 0x39, 0x2e, 0xa7, 0xab, 0x48, 0xe0, 0xf1, 0x81,
-            0xde, 0x14, 0xdb, 0x0b, 0x9a, 0xaa, 0x7d, 0x34, 0xbb, 0xf8, 0xfd, 0x4b, 0x8d, 0x5f, 0x8d, 0xfc,
-            0xa8, 0x39, 0x47, 0x1b, 0x33, 0x63, 0x46, 0x57, 0x94, 0x60, 0x87, 0x35, 0x77, 0x4d, 0xc7, 0xed,
-            0xcc, 0x2a, 0x4e, 0xc8, 0x1c, 0x00, 0x1e, 0xc9, 0xc4, 0x8e, 0x47, 0x91, 0x30, 0x5f, 0x7e, 0x19,
-            0x1d, 0x64, 0xdb, 0xf9, 0xbc, 0x60, 0x7c, 0xf8, 0x7e, 0x2f, 0x20, 0x96, 0x42, 0xa2, 0xc5, 0x66,
-            0xa5, 0xde, 0x5d, 0x19, 0xfc, 0x92, 0xc9, 0x20, 0x31, 0x3c, 0xd1, 0xf3, 0x37, 0x9c, 0x25, 0xc1,
-            0xc9, 0x32, 0xcc, 0x09, 0x4d, 0x25, 0xe1, 0xe1, 0x63, 0x99, 0x86, 0x46, 0x28, 0xad, 0x04, 0xc7,
-            0x29, 0x3d, 0xc6, 0xa1, 0x52, 0xeb, 0x59, 0xba, 0xae, 0x2a, 0xe3, 0xa8, 0x88, 0xe1, 0xa5, 0x8e,
-            0xed, 0x22, 0xd3, 0x75, 0x1d, 0xfb, 0x44, 0x32, 0x7a, 0x2c, 0x9a, 0xc6, 0xad, 0xbd, 0x65, 0xbb,
-            0x78, 0x13, 0x9e, 0xeb, 0xe6, 0xa6, 0x50, 0x9a, 0xdb, 0x59, 0x34, 0x51, 0xf5, 0x4a, 0x6e, 0xb4,
-            0x46, 0x94, 0x19, 0xf1, 0xcd, 0x6f, 0xbb, 0xc1, 0x40, 0x2f, 0x1d, 0x65, 0x42, 0xc4, 0x0e, 0xed,
-            0x25, 0x90, 0xc6, 0xc3, 0xda, 0x7c, 0x5b, 0x3a, 0x03, 0x99, 0x1f, 0xe1, 0x15, 0xbd, 0x54, 0xf1,
-            0x1e, 0xfc, 0xca, 0xd5, 0xaa, 0x41, 0xa7, 0x09, 0x8b, 0xde, 0xcb, 0xbb, 0xe5, 0xb5, 0xe9, 0x99,
-            0x62, 0x12, 0x04, 0x6d, 0x70, 0x3d, 0x94, 0x59, 0x6e, 0xbc, 0x72, 0xe9, 0x2a, 0x72, 0x5c, 0xa6,
-            0x49, 0x03, 0xec, 0x42, 0xa0, 0x19, 0x77, 0xcf, 0x12, 0x83, 0xd9, 0x8d, 0x50, 0x5e, 0xb2, 0x21,
-            0x44, 0xba, 0xf0, 0x05, 0x1f, 0x13, 0x85, 0xf6, 0xbe, 0x9d, 0xe4, 0x4b, 0x28, 0xcf, 0x4a, 0x24,
-            0xbb, 0x38, 0x9f, 0x7b, 0x60, 0xb0, 0x82, 0xeb, 0x3a, 0x62, 0x60, 0x8c, 0xd6, 0x68, 0x99, 0xc2,
-            0xe3, 0x2c, 0x1d, 0xc5, 0x4f, 0x22, 0x50, 0x58, 0x97, 0x96, 0x95, 0xf3, 0x51, 0x6a, 0xf8, 0x95,
-            0xb0, 0x80, 0x47, 0x66, 0x18, 0x9e, 0x54, 0x46, 0x99, 0x09, 0x7b, 0x27, 0x85, 0x3d, 0x61, 0x8f,
-            0xd9, 0x03, 0x2b, 0x9a, 0x02, 0x19, 0x0c, 0x66, 0x6d, 0x99, 0x53, 0x16, 0x59, 0x56, 0xb9, 0x06,
-            0x07, 0x35, 0x4c, 0x58, 0xb8, 0x97, 0x17, 0xc0, 0x94, 0x5c, 0x86, 0x83, 0x5c, 0xa8, 0x9f, 0x13,
-            0x2a, 0x11, 0xe4, 0x7f, 0xd8, 0xbd, 0x6b, 0x2e, 0xb8, 0x02, 0xb4, 0x52, 0x10, 0x64, 0x9f, 0x1a,
-            0x1d, 0xdd, 0x3b, 0x57, 0x35, 0xb4, 0x62, 0xee, 0xbd, 0xc6, 0x52, 0x39, 0x30, 0xbd, 0x28, 0x11,
-            0x70, 0xce, 0x72, 0x30, 0x24, 0xeb, 0x6b, 0x9e, 0x19, 0x9a, 0x7d, 0x36, 0x74, 0x38, 0xa3, 0x9b,
-            0xb8, 0xc3, 0x64, 0xbe, 0x52, 0xaa, 0xa8, 0xf1, 0x56, 0x2b, 0x11, 0x33, 0x7e, 0x03, 0x0c, 0x46,
-            0xf2, 0xce, 0x00, 0x3f, 0xc1, 0xf6, 0x7b, 0xdd, 0xe2, 0x67, 0xdb, 0x4a, 0x31, 0xa2, 0xc5, 0x32,
-            0xd0, 0x1d, 0xd1, 0x3e, 0xcd, 0x7f, 0x35, 0x76, 0x7f, 0x71, 0x03, 0x35, 0x83, 0x51, 0x59, 0x8e,
-            0x36, 0x18, 0xfb, 0xad, 0x51, 0x10, 0x26, 0x93, 0x77, 0x6c, 0xa4, 0x14, 0x4d, 0x97, 0x8e, 0xdb,
-            0xc7, 0x63, 0xac, 0x10, 0x59, 0xa7, 0xe0, 0x81, 0x0f, 0x10, 0x10, 0x0c, 0x09, 0x7a, 0x0f, 0x67,
-            0xdf, 0x8b, 0x53, 0x9f, 0xe6, 0xc5, 0x9b, 0x8c, 0xdf, 0xaa, 0x93, 0x33, 0x86, 0x3f, 0xe5, 0xd9,
-            0x89, 0xe1, 0xd3, 0x3c, 0x40, 0x38, 0xf0, 0x35, 0x2e, 0x1a, 0x29, 0xcf, 0x31, 0xed, 0x73, 0x74,
-            0x5f, 0xe4, 0x79, 0x9e, 0x02, 0xd0, 0xde, 0x53, 0xf1, 0xa6, 0x31, 0x8c, 0x3e, 0xf7, 0x2b, 0xa8,
-            0x5f, 0xad, 0x86, 0xd9, 0x4b, 0x1e, 0xd3, 0xf2, 0x2e, 0x1d, 0x19, 0x92, 0x67, 0x36, 0xd5, 0xe8,
-            0x5f, 0xcf, 0xc1, 0xa3, 0xe8, 0x90, 0x84, 0xa7, 0x9b, 0xfa, 0x02, 0xca, 0x3c, 0x94, 0xd1, 0x41,
-            0xb9, 0xe6, 0x29, 0x22, 0x6a, 0x3a, 0x6d, 0xb6, 0x63, 0x21, 0xca, 0xbe, 0x1c, 0x48, 0xe4, 0x88,
-            0xa8, 0x0c, 0x4f, 0x9f, 0x65, 0x4b, 0xd0, 0x9c, 0xbe, 0xed, 0x46, 0xf0, 0x90, 0xb7, 0x72, 0x16,
-            0x67, 0x74, 0x80, 0x54, 0xa0, 0x64, 0xf7, 0x21, 0xa3, 0x62, 0xac, 0xa5, 0x2b, 0x8e, 0xa1, 0x22,
-            0x86, 0xbb, 0xe8, 0xdd, 0x64, 0x33, 0xff, 0x89, 0x24, 0xe4, 0x4b, 0xcb, 0xd4, 0x14, 0x6c, 0x98,
-            0xf1, 0x83, 0x65, 0x69, 0x03, 0xf3, 0x44, 0x4f, 0x96, 0x88, 0x95, 0x2d, 0x81, 0x6d, 0x96, 0xcf,
-            0x16, 0x7a, 0xd1, 0xc3, 0x35, 0x7f, 0xda, 0x13, 0xa1, 0x47, 0x44, 0x83, 0xbd, 0xab, 0x17, 0xc9,
-            0x16, 0xe1, 0x84, 0xff, 0xac, 0xec, 0x25, 0x36, 0xb4, 0xf6, 0x78, 0x23, 0x98, 0x5b, 0x88, 0xd8,
-            0x81, 0x7d, 0x44, 0x12, 0xfa, 0x12, 0xcf, 0xe2, 0x1f, 0x64, 0x31, 0xc5, 0xa6, 0x1a, 0x82, 0x82,
-            0x62, 0x60, 0x87, 0xb1, 0x74, 0xf5, 0xaf, 0x82, 0x53, 0x0f, 0x0d, 0x04, 0x7a, 0x42, 0x64, 0x30,
-            0xa6, 0x39, 0xe5, 0xe9, 0x3e, 0x9a, 0x01, 0xac, 0x7f, 0x64, 0x65, 0xef, 0x14, 0x74, 0x16, 0x3e,
-            0x35, 0xca, 0x2b, 0x67, 0xf8, 0x2b, 0x09, 0x69, 0x45, 0x20, 0x3c, 0x0e, 0x29, 0x9f, 0xbf, 0x48,
-            0xf9, 0x1f, 0xf7, 0xb0, 0x32, 0xb4, 0x68, 0x65, 0x7e, 0x7d, 0x9c, 0x85, 0xec, 0x23, 0x92, 0x10,
-            0xc3, 0xca, 0x14, 0x79, 0xd0, 0xd5, 0x03, 0x39, 0x81, 0xfa, 0x0f, 0x62, 0x89, 0x24, 0xa1, 0x14,
-            0x50, 0xcb, 0x7a, 0x1c, 0x4d, 0x44, 0x98, 0x62, 0xba, 0xdd, 0x51, 0xc7, 0x62, 0xe4, 0xb0, 0x91,
-            0x33, 0x93, 0x65, 0x28, 0xca, 0x94, 0xf8, 0x00, 0x91, 0x61, 0xbf, 0x74, 0xc5, 0x01, 0x83, 0xa4,
-            0xf2, 0x9f, 0xe7, 0x5f, 0xdb, 0xee, 0x54, 0xe3, 0xe5, 0x91, 0xef, 0x34, 0x97, 0x4b, 0x10, 0x37,
-            0x8d, 0x08, 0x55, 0x97, 0xa8, 0x5a, 0xd2, 0x62, 0x80, 0x19, 0x77, 0x44, 0xdc, 0x09, 0x4a, 0x46,
-            0x29, 0x03, 0xe6, 0xaa, 0xe9, 0x15, 0xc9, 0x08, 0x9a, 0xf0, 0x4f, 0xf3, 0xdd, 0x03, 0x9e, 0x33,
-            0xa5, 0x40, 0x75, 0x1c, 0x46, 0x15, 0x2c, 0x46, 0xdc, 0x8e, 0xba, 0x87, 0x88, 0xaf, 0x86, 0xe8,
-            0x95, 0xe2, 0x14, 0x9e, 0x3d, 0x09, 0xac, 0x08, 0x2a, 0x5c, 0x47, 0x9d, 0xef, 0x3f, 0xd2, 0xbc,
-            0x21, 0xaf, 0x65, 0x39, 0x3e, 0x6c, 0x98, 0x02, 0x5e, 0xa6, 0xf5, 0xd3, 0xe1, 0x89, 0xe4, 0x8a,
-            0x12, 0x90, 0x27, 0x41, 0x6e, 0x04, 0xeb, 0x1b, 0x21, 0x7a, 0xfa, 0xe0, 0xe2, 0x9e, 0x49, 0xe0,
-            0xc0, 0x2a, 0xd6, 0xa8, 0x3e, 0x1b, 0xf1, 0x8e, 0x03, 0x7f, 0xf4, 0x97, 0xe9, 0x87, 0x73, 0xfe,
-            0xba, 0x94, 0x6c, 0x90, 0x9d, 0xf9, 0x04, 0xdd, 0x7c, 0x56, 0xbc, 0xd1, 0x66, 0x8e, 0xab, 0x60,
-            0x0c, 0x20, 0x1c, 0xc6, 0xce, 0xed, 0x2d, 0x0b, 0xe0, 0x2d, 0xb2, 0x78, 0x7f, 0x1a, 0x8a, 0x1c,
-            0xd8, 0x25, 0x1d, 0xee, 0x22, 0xc9, 0x55, 0x06, 0xe2, 0xd6, 0x0e, 0x8c, 0x6c, 0xe1, 0x5a, 0x0f,
-            0xe8, 0xdc, 0xe6, 0xd9, 0x66, 0x1c, 0xe8, 0xac, 0x80, 0xd2, 0x25, 0x66, 0xe9, 0x8a, 0x70, 0xd6,
-            0xee, 0xdb, 0x76, 0x69, 0x1b, 0x8b, 0x51, 0x46, 0x63, 0x14, 0x10, 0x65, 0x12, 0x43, 0xc5, 0x66,
-            0xa0, 0x99, 0x88, 0x71, 0x4c, 0x78, 0x97, 0xe9, 0xe2, 0xe0, 0xaf, 0xdd, 0x2a, 0xea, 0x8e, 0x45,
-            0x12, 0xe7, 0x2c, 0x58, 0x59, 0x77, 0x88, 0x17, 0x3e, 0xf3, 0xf5, 0x6d, 0x0c, 0x2d, 0x6a, 0x99,
-            0xf0, 0x3e, 0x17, 0x33, 0xf2, 0x9b, 0xe1, 0x66, 0xfb, 0xb9, 0x88, 0x2a, 0xff, 0x5c, 0x94, 0xf4,
-            0xdc, 0x1f, 0x59, 0x7f, 0x89, 0xce, 0xde, 0xb0, 0xbb, 0x45, 0x63, 0xa2, 0x41, 0x98, 0x88, 0x37,
-            0x0d, 0x74, 0xe0, 0x83, 0x70, 0x2b, 0x68, 0xc8, 0x33, 0x5b, 0x18, 0xd4, 0xd4, 0xc4, 0x31, 0xc9,
-            0x19, 0xc1, 0x51, 0xc9, 0x77, 0xe8, 0x3a, 0x35, 0xb8, 0xd6, 0xc0, 0x7a, 0x58, 0xe2, 0xf4, 0xd8,
-            0x13, 0x4e, 0xbc, 0xde, 0xc8, 0x17, 0x9e, 0x4f, 0x15, 0x40, 0x31, 0x65, 0x09, 0xe6, 0x52, 0xfd,
-            0xa6, 0x45, 0xd7, 0xe1, 0x05, 0xef, 0x50, 0x0d, 0x59, 0xca, 0xde, 0xd1, 0x5d, 0x14, 0xaa, 0xe9,
-            0x47, 0x69, 0x9a, 0x44, 0x60, 0xc4, 0x7b, 0xb2, 0xd9, 0x18, 0x52, 0xf9, 0x79, 0x1f, 0xb0, 0xfd,
-            0x9a, 0x4a, 0x11, 0xb4, 0x26, 0xf4, 0x84, 0x30, 0xb0, 0x80, 0xa3, 0xbe, 0x4f, 0xae, 0x42, 0x84,
-            0x3b, 0x4a, 0xae, 0xc1, 0x70, 0x71, 0xb7, 0x94, 0xe5, 0xd2, 0x05, 0x99, 0x83, 0x1a, 0xef, 0x61,
-            0x22, 0x96, 0x03, 0xf7, 0xe9, 0x83, 0xdf, 0x2b, 0x6b, 0x4b, 0xd3, 0x60, 0x97, 0x4b, 0x7c, 0xe2,
-            0xbd, 0x77, 0xbb, 0x7d, 0x2a, 0x4e, 0xde, 0x56, 0xee, 0x77, 0xf8, 0xf5, 0xea, 0x19, 0x95, 0x61,
-            0x08, 0xc6, 0xc2, 0xcc, 0x1d, 0xb3, 0x0e, 0x28, 0x82, 0x98, 0x24, 0xcd, 0xfe, 0xe2, 0x47, 0xfd,
-            0x38, 0x62, 0x60, 0xef, 0xe8, 0xe9, 0x2f, 0xc1, 0xef, 0x9a, 0xe8, 0x71, 0x22, 0x35, 0x37, 0x7b,
-            0x3e, 0x8a, 0xda, 0xb7, 0x29, 0x70, 0x28, 0xd4, 0xe8, 0xd9, 0xcc, 0xfc, 0x6f, 0xa2, 0xf0, 0xa7,
-            0xa0, 0x9e, 0xe4, 0x9e, 0xf3, 0xf8, 0x1d, 0x1c, 0xb3, 0x23, 0xca, 0xaa, 0x8b, 0x6d, 0x07, 0xc5,
-            0x2e, 0x15, 0x3b, 0x2c, 0x71, 0x91, 0xc2, 0xa8, 0x69, 0x39, 0x28, 0x94, 0x86, 0x02, 0x35, 0xc6,
-            0x60, 0x1a, 0x36, 0x1a, 0x5f, 0xd0, 0x4a, 0x88, 0xa1, 0x36, 0xf2, 0x24, 0x5c, 0x59, 0x41, 0x25,
-            0x3d, 0x7c, 0x2c, 0xb9, 0xf5, 0x4c, 0x74, 0x11, 0xed, 0xb0, 0x69, 0x03, 0x01, 0xa8, 0xa8, 0xcc,
-            0xc7, 0x7e, 0x51, 0x2d, 0x46, 0xd3, 0xf2, 0xeb, 0xa9, 0x90, 0x18, 0x01, 0x78, 0xbc, 0x6c, 0x4e,
-            0x26, 0x06, 0xdf, 0x90, 0xba, 0x62, 0xfa, 0x42, 0x85, 0xf9, 0x46, 0x49, 0xdd, 0xc1, 0xae, 0x4f,
-            0xe5, 0xcf, 0x43, 0xa7, 0xc2, 0xf0, 0x9a, 0xec, 0xe4, 0x2c, 0x19, 0x99, 0x51, 0x0b, 0x1f, 0xe6,
-            0x42, 0x7d, 0xb7, 0xd8, 0xc0, 0xf5, 0xe3, 0x2d, 0x12, 0x42, 0xdf, 0xaf, 0xaa, 0x74, 0xa9, 0x24,
-            0x5f, 0x1a, 0x5c, 0x71, 0x9a, 0x93, 0x88, 0x6a, 0xea, 0x16, 0x90, 0x17, 0x08, 0xb3, 0x54, 0xbf,
-            0xc8, 0x33, 0x4e, 0x7a, 0x85, 0xf5, 0x78, 0x4b, 0x09, 0xe4, 0xa5, 0x2c, 0xb2, 0x08, 0x5b, 0x80,
-            0x66, 0x71, 0x73, 0x39, 0x70, 0xa1, 0xd1, 0x48, 0x3f, 0xe5, 0x97, 0x21, 0x5f, 0xa3, 0xe9, 0xf6,
-            0xbe, 0x5f, 0xde, 0x2c, 0x5b, 0x2c, 0xae, 0x88, 0x66, 0x09, 0xcc, 0xda, 0x06, 0x93, 0x5d, 0xa7,
-            0x47, 0x3a, 0x1b, 0x7a, 0x15, 0x61, 0x22, 0x47, 0x43, 0xfa, 0x34, 0xa7, 0xf0, 0xc9, 0x6e, 0xff,
-            0x27, 0x4e, 0xa7, 0x46, 0x59, 0xa7, 0x08, 0x1b, 0x48, 0xa7, 0x8d, 0xf2, 0xae, 0x16, 0x5a, 0x2f,
-            0x8f, 0x59, 0xa0, 0xb4, 0x08, 0xc4, 0x14, 0xe9, 0xbf, 0xa1, 0xba, 0xc6, 0x60, 0x08, 0xf6, 0xbe,
-            0x63, 0xe7, 0xba, 0x7e, 0xd3, 0xc1, 0x27, 0x4a, 0x2c, 0xc7, 0xed, 0xd4, 0xb1, 0x2d, 0x15, 0xf0,
-            0xe3, 0xc9, 0x36, 0x3a, 0xee, 0xd3, 0x6c, 0xd5, 0xbb, 0x9d, 0x35, 0xdb, 0xa8, 0x9e, 0xca, 0x8e,
-            0x89, 0x0e, 0xd0, 0x1e, 0x7f, 0xd4, 0xe4, 0xf7, 0xcb, 0xda, 0xd2, 0xe1, 0x6b, 0xff, 0xd8, 0xc7,
-            0x7e, 0x0b, 0x18, 0x3b, 0xb2, 0x1e, 0xe3, 0x1a, 0x23, 0x9e, 0x80, 0x11, 0x19, 0x3b, 0x98, 0x76,
-            0x50, 0xb1, 0x84, 0x9b, 0x09, 0x3a, 0x28, 0x2b, 0x02, 0x23, 0xa1, 0xee, 0xe3, 0x60, 0x1b, 0xb3,
-            0x85, 0xf7, 0x6d, 0x2a, 0x10, 0x7d, 0x35, 0x48, 0x94, 0xb4, 0x3c, 0x82, 0x7e, 0xbb, 0x90, 0x45,
-            0x5d, 0x38, 0xc7, 0x28, 0xd8, 0xdd, 0x69, 0xf0, 0x33, 0x46, 0xe5, 0x60, 0xf0, 0xe4, 0x53, 0x2a,
-            0x1f, 0xd7, 0x28, 0x18, 0xa0, 0xdf, 0x51, 0x66, 0xbc, 0xe5, 0x34, 0xb1, 0x5f, 0xd4, 0x80, 0x5f,
-            0xd2, 0xcd, 0xc6, 0x70, 0x17, 0x2e, 0xdf, 0x16, 0x57, 0x93, 0x61, 0x05, 0xde, 0x28, 0xe3, 0x43,
-            0x33, 0x1d, 0x66, 0x79, 0x33, 0x16, 0xc6, 0x37, 0x26, 0xd0, 0x20, 0x3a, 0x0c, 0x14, 0x17, 0xba,
-            0x4e, 0xe3, 0xa4, 0x8e, 0x7d, 0xc9, 0x53, 0xe1, 0x40, 0xe4, 0x58, 0x12, 0xfe, 0xd2, 0xec, 0xd0,
-            0xac, 0x70, 0x37, 0xc0, 0x84, 0x6a, 0x09, 0xf1, 0x6d, 0xb2, 0x3f, 0x84, 0xe5, 0x1f, 0x85, 0xc2,
-            0x61, 0x2d, 0xfa, 0x30, 0x2b, 0x5b, 0xf0, 0xf7, 0xcf, 0xfe, 0x32, 0xb1, 0x2a, 0xb9, 0x95, 0xae,
-            0xfd, 0x0d, 0xee, 0x5a, 0xa5, 0xcd, 0xe4, 0xa9, 0x1b, 0xa3, 0x96, 0x06, 0x31, 0xf2, 0x9c, 0xf2,
-            0x83, 0x06, 0x20, 0x39, 0x30, 0xf9, 0x9c, 0xa7, 0x22, 0xfd, 0x75, 0x61, 0x70, 0xe6, 0x7c, 0x3c,
-            0x84, 0x24, 0xd9, 0x26, 0x0b, 0x6c, 0x4e, 0xb8, 0x96, 0x05, 0x01, 0xe5, 0x07, 0xdb, 0x17, 0xd4,
-            0x5f, 0x40, 0x7f, 0xd0, 0xde, 0x06, 0x7c, 0xb4, 0xe7, 0x45, 0x39, 0x23, 0xf6, 0x09, 0x4a, 0x2c,
-            0x05, 0x97, 0x3c, 0xce, 0xa4, 0x50, 0xa8, 0x8a, 0x6a, 0x7a, 0x39, 0x3f, 0xa2, 0x8a, 0xd5, 0x84,
-            0xc2, 0x1e, 0x00, 0x2e, 0x5b, 0x76, 0x2b, 0x24, 0x88, 0x49, 0xd7, 0x2d, 0xe6, 0x58, 0x3d, 0xf4,
-            0x89, 0xb5, 0x8c, 0xd2, 0xd8, 0xc0, 0x51, 0xb4, 0xe9, 0x62, 0x60, 0x6e, 0x8c, 0x3d, 0x6e, 0xce,
-            0x08, 0xbe, 0xe5, 0x73, 0x74, 0x22, 0xe7, 0x4e, 0x92, 0xd9, 0xb0, 0x1c, 0xb4, 0x24, 0xc0, 0x3a,
-            0x0c, 0x6d, 0x99, 0x51, 0x80, 0x58, 0xe1, 0x28, 0xcb, 0xa7, 0x01, 0x28, 0xd1, 0x47, 0xd0, 0x32,
-            0x1d, 0x96, 0x82, 0x09, 0x25, 0x2d, 0x60, 0x44, 0x12, 0x48, 0xea, 0x91, 0x46, 0x66, 0x6f, 0xf0,
-            0xe8, 0x45, 0x04, 0x85, 0x42, 0x3e, 0x11, 0x04, 0x46, 0x29, 0x4d, 0x22, 0xe6, 0xe6, 0x4e, 0x47,
-            0xb4, 0x32, 0x80, 0xe0, 0x66, 0xb3, 0x13, 0x68, 0xa0, 0x4b, 0xd5, 0xd8, 0x08, 0x1d, 0xcf, 0x91,
-            0x04, 0xb0, 0x82, 0x73, 0x7a, 0x0c, 0x6e, 0x3a, 0x76, 0x7f, 0x0e, 0x1a, 0x33, 0xec, 0x36, 0xe2,
-            0xe7, 0xfb, 0x3b, 0x6e, 0xe5, 0x1b, 0x5a, 0xa0, 0xcd, 0xbc, 0x88, 0x9e, 0xd3, 0xd0, 0x33, 0x4b,
-            0x6b, 0x52, 0x2e, 0xef, 0xfc, 0x24, 0x0e, 0x1b, 0x76, 0x91, 0x90, 0x34, 0x23, 0x46, 0xcd, 0xc7,
-            0x94, 0x19, 0x04, 0x0d, 0x20, 0x82, 0x72, 0x31, 0x93, 0x0b, 0x6d, 0xb1, 0x00, 0x13, 0xbf, 0x30,
-            0xf9, 0x23, 0x75, 0xf8, 0x68, 0x3e, 0xe4, 0xa1, 0x13, 0x26, 0x49, 0x23, 0xbf, 0x86, 0x57, 0x32,
-            0x2d, 0xd3, 0x4e, 0xba, 0xaf, 0xaa, 0x98, 0xb0, 0xc1, 0xa6, 0xa2, 0x45, 0x9c, 0x48, 0x7b, 0x3a,
-            0x21, 0xae, 0xb1, 0x13, 0x17, 0x98, 0x32, 0xc3, 0x2d, 0x9b, 0x2a, 0x2e, 0xc9, 0x03, 0x26, 0x7c,
-            0xdb, 0x41, 0x8d, 0xc1, 0x42, 0x99, 0xf6, 0x32, 0xc5, 0x48, 0xf6, 0xdd, 0x59, 0x48, 0xc0, 0xa4,
-            0x30, 0x59, 0x2b, 0x79, 0x55, 0xc2, 0xf8, 0x2b, 0xe3, 0x84, 0x08, 0x13, 0xce, 0xb8, 0x82, 0xdf,
-            0xb8, 0x3a, 0x4e, 0x5c, 0x40, 0x37, 0x51, 0x95, 0xec, 0x91, 0x3c, 0x99, 0xfd, 0xe4, 0xc4, 0xd5,
-            0xff, 0xbd, 0x0a, 0x60, 0x6f, 0x4b, 0x3f, 0x2e, 0x30, 0x24, 0xcc, 0xb1, 0x59, 0xb8, 0xcd, 0xa3,
-            0xff, 0x77, 0xf4, 0xb8, 0x4c, 0xf0, 0x37, 0x1e, 0xcc, 0xc4, 0x46, 0xee, 0x45, 0x41, 0x9b, 0xac,
-            0xb6, 0xc2, 0x41, 0xd2, 0x3d, 0xc5, 0xeb, 0x39, 0x08, 0x0d, 0x94, 0x0a, 0x72, 0x66, 0xb9, 0x19,
-            0x88, 0x21, 0xe6, 0x95, 0x1e, 0x2c, 0x13, 0xc9, 0x10, 0x4b, 0xb1, 0xf5, 0xa9, 0xc4, 0x8e, 0x96,
-            0x25, 0x28, 0x86, 0xf5, 0x1e, 0xf1, 0x5b, 0x4c, 0xbc, 0x5e, 0x4b, 0xc0, 0x7f, 0x93, 0x74, 0x22,
-            0x75, 0x4a, 0x11, 0x5e, 0xe1, 0x72, 0x99, 0x60, 0x44, 0x47, 0xeb, 0x2d, 0x77, 0xb2, 0x10, 0xf3,
-            0xd2, 0xd7, 0x15, 0x55, 0xa9, 0x62, 0xc1, 0x7b, 0x32, 0xe1, 0x4b, 0x6b, 0x19, 0x70, 0xc2, 0xd8,
-            0x12, 0x09, 0xc6, 0x77, 0xeb, 0x01, 0xfa, 0x64, 0x2a, 0xa7, 0x3a, 0x0b, 0xa1, 0xa4, 0x07, 0xa1,
-            0x71, 0x8b, 0xbc, 0x80, 0x63, 0x46, 0x58, 0xb1, 0xde, 0x2e, 0x53, 0x32, 0xe3, 0x03, 0x19, 0x46,
-            0x33, 0xfc, 0x1d, 0x19, 0x16, 0xaa, 0x87, 0x89, 0x72, 0xeb, 0x8a, 0xa2, 0xd7, 0x35, 0xdb, 0x7b,
-            0xf9, 0x2a, 0x94, 0xe5, 0xd5, 0x6a, 0x71, 0x3b, 0xea, 0x22, 0xaa, 0xf6, 0x15, 0x54, 0x2e, 0x7a,
-            0x94, 0x5a, 0x37, 0x6b, 0x72, 0x21, 0x43, 0xdd, 0xf9, 0xaf, 0xeb, 0x72, 0x9c, 0x10, 0x8f, 0x68,
-            0x65, 0x16, 0xf9, 0x07, 0x7c, 0x55, 0x35, 0x64, 0x64, 0x85, 0xc8, 0x66, 0xcf, 0xa4, 0x37, 0x73,
-            0xa8, 0xa7, 0x4d, 0xd6, 0xe7, 0x41, 0xf1, 0x6e, 0x16, 0x22, 0xd2, 0x9c, 0x64, 0x94, 0x49, 0xd5,
-            0x16, 0x0c, 0x63, 0x5e, 0x2d, 0x5f, 0x3e, 0x9c, 0x41, 0xc2, 0x7c, 0x2e, 0xb7, 0x26, 0xa3, 0xee,
-            0x6b, 0xb1, 0x8a, 0x8a, 0x47, 0xac, 0xc5, 0x6f, 0x76, 0x6d, 0x2d, 0x8a, 0x57, 0x19, 0x0d, 0x68,
-            0xb8, 0x29, 0xae, 0x52, 0x71, 0x08, 0xa4, 0xb8, 0xc9, 0x86, 0xf4, 0x53, 0x7c, 0x8f, 0x41, 0x81,
-            0x37, 0x5a, 0xe0, 0x37, 0x76, 0xfd, 0xd9, 0x87, 0x65, 0x6a, 0x4b, 0x36, 0xf2, 0xfa, 0x69, 0x9b,
-            0x06, 0xcf, 0x3d, 0xf6, 0x7e, 0x81, 0x9f, 0x89, 0x73, 0x2e, 0xdb, 0x92, 0xd4, 0x25, 0xa0, 0x5c,
-            0x67, 0x32, 0xb5, 0xe1, 0xe5, 0xd0, 0x98, 0x0e, 0x52, 0xe6, 0x77, 0x60, 0xdf, 0x6c, 0x61, 0x98,
-            0xda, 0x48, 0xf3, 0x10, 0x59, 0x7b, 0x21, 0x1d, 0xc9, 0xf2, 0xbe, 0xeb, 0x46, 0x6a, 0x85, 0x66,
-            0x5e, 0xff, 0xa5, 0x39, 0xf8, 0x7c, 0xaa, 0xb7, 0x32, 0xc2, 0x1f, 0x07, 0x55, 0x64, 0xed, 0x74,
-            0x6a, 0x5a, 0x34, 0x40, 0xef, 0xb6, 0x4d, 0xbc, 0x78, 0x0d, 0x5a, 0x0c, 0xf9, 0xd5, 0xac, 0x8c,
-            0x2e, 0x21, 0xfe, 0x72, 0x8e, 0x66, 0xca, 0x64, 0xb0, 0x28, 0xb3, 0x37, 0xa5, 0xf6, 0xc8, 0x54,
-            0x66, 0x75, 0xca, 0x6d, 0x5a, 0xe6, 0xf5, 0x32, 0xa1, 0x59, 0xae, 0xf9, 0xc5, 0xa2, 0x0a, 0x74,
-            0x68, 0x91, 0x4a, 0x2f, 0x28, 0x6b, 0xf8, 0x07, 0x2a, 0x1a, 0xa4, 0x3e, 0x81, 0x24, 0x1b, 0xef,
-            0x2f, 0x9c, 0x62, 0x14, 0x2d, 0x96, 0xc9, 0x39, 0x44, 0xdc, 0x2c, 0x7e, 0x73, 0x10, 0xbd, 0x90,
-            0xd4, 0xa8, 0xd2, 0x83, 0x88, 0x64, 0xcb, 0x3c, 0xfe, 0x67, 0x34, 0xb3, 0x20, 0x6c, 0x4b, 0x0a,
-            0xf3, 0x9a, 0x40, 0xc9, 0x60, 0xbb, 0xa7, 0x9d, 0xce, 0xeb, 0xa6, 0xbf, 0x2b, 0x4e, 0x52, 0x96,
-            0x2f, 0xf6, 0x2d, 0xd5, 0xef, 0x99, 0xd1, 0xa9, 0x39, 0x2e, 0xf5, 0xcb, 0x66, 0x30, 0x66, 0x7f,
-            0xda, 0x26, 0xd6, 0xe7, 0x15, 0x9c, 0x29, 0x87, 0xc4, 0x23, 0xd3, 0xca, 0x59, 0x71, 0x61, 0x01,
-            0xcd, 0x59, 0xca, 0x38, 0x50, 0x8a, 0xdd, 0x6b, 0x1a, 0xe2, 0x75, 0x9f, 0xc0, 0x69, 0x22, 0x93,
-            0xbc, 0xc9, 0x9f, 0x03, 0x52, 0x23, 0x3a, 0x40, 0x4e, 0x8c, 0x9d, 0x5a, 0x8b, 0x42, 0x4f, 0x9b,
-            0x4d, 0x82, 0x9c, 0x47, 0x2a, 0x85, 0x0c, 0xea, 0x81, 0xeb, 0xeb, 0x72, 0x7e, 0xe9, 0xd7, 0x4d,
-            0xf2, 0xa7, 0xcd, 0x53, 0x71, 0x4b, 0xfc, 0x46, 0xd5, 0x30, 0x11, 0x3a, 0xdf, 0x64, 0x9f, 0x5e,
-            0x97, 0x4b, 0x97, 0x4d, 0x3e, 0xfa, 0x31, 0xb6, 0xb2, 0xd6, 0x5b, 0xac, 0x65, 0x8e, 0x24, 0xc8,
-            0x42, 0xa9, 0xc3, 0x85, 0x06, 0xa8, 0x32, 0x3a, 0x32, 0xa7, 0xbe, 0xad, 0x51, 0xfa, 0x3e, 0x4c,
-            0xb6, 0xb0, 0x5c, 0xfd, 0x6f, 0xca, 0x16, 0xb9, 0x24, 0x8a, 0xcb, 0x40, 0x7d, 0x6d, 0x35, 0x44,
-            0x94, 0x6f, 0xa3, 0xd9, 0x0f, 0xf5, 0x8e, 0x68, 0x24, 0xba, 0xdb, 0x24, 0xfb, 0x93, 0x6e, 0x20,
-            0x59, 0xcf, 0x33, 0x8b, 0x74, 0x52, 0x04, 0x4e, 0x6d, 0x95, 0x4a, 0x9f, 0xaa, 0xfc, 0x62, 0x13,
-            0x6e, 0xac, 0xf6, 0x05, 0x8d, 0x05, 0xc9, 0xf9, 0x84, 0x87, 0x02, 0x5b, 0x6b, 0xc5, 0x4e, 0x1a,
-            0xcc, 0x42, 0xa8, 0x8b, 0x60, 0xe9, 0xd6, 0x4c, 0x82, 0x14, 0x0d, 0x1b, 0xc7, 0x54, 0x46, 0xfc,
-            0x1a, 0x3b, 0x16, 0x00, 0xcd, 0xad, 0x72, 0xa6, 0xe7, 0x58, 0xd9, 0x68, 0x09, 0xae, 0xba, 0xbd,
-            0x24, 0x96, 0x10, 0x2c, 0x55, 0x70, 0xd6, 0x12, 0x86, 0xec, 0xb4, 0x8a, 0xf6, 0x8f, 0xa9, 0xee,
-            0x87, 0xcd, 0xbe, 0x17, 0x4e, 0xe6, 0xcf, 0x61, 0xc1, 0xc6, 0x77, 0x0e, 0xd5, 0x60, 0x9a, 0x21,
-            0xda, 0xd1, 0xd2, 0x0c, 0xb2, 0xcc, 0x10, 0xda, 0x98, 0x89, 0x6e, 0x42, 0x49, 0xa6, 0xa4, 0x10,
-            0x33, 0x29, 0xfe, 0x50, 0x00, 0xbf, 0xad, 0x54, 0x68, 0x04, 0xa6, 0xe9, 0xac, 0x70, 0x51, 0xe8,
-            0x18, 0x24, 0x3e, 0x77, 0x20, 0xe3, 0x4d, 0x02, 0x31, 0xf6, 0xdd, 0x4d, 0xfc, 0x5e, 0x1c, 0xbe,
-            0xa3, 0x4c, 0x3a, 0xfc, 0x20, 0xc9, 0xd5, 0xf0, 0xb2, 0x56, 0xd7, 0x47, 0xb3, 0x4d, 0x92, 0xac,
-            0xbd, 0x22, 0xb6, 0x4c, 0x79, 0x46, 0x0f, 0x1c, 0x54, 0x65, 0x79, 0xa8, 0x84, 0xf4, 0x21, 0x9e,
-            0xf7, 0x30, 0x8c, 0xd3, 0x01, 0x53, 0x43, 0x0c, 0x3e, 0xac, 0x68, 0x65, 0xa9, 0x22, 0xd5, 0xcf,
-            0xcc, 0xe9, 0xa8, 0xfd, 0x4e, 0x7b, 0x2e, 0xc9, 0x81, 0x24, 0x26, 0xd0, 0x9b, 0x69, 0xb9, 0x04,
-            0xe8, 0x80, 0xd5, 0x13, 0xef, 0xf0, 0xac, 0x0a, 0x5d, 0x0d, 0x59, 0x72, 0x6a, 0xe6, 0x97, 0x03,
-            0x1d, 0x3a, 0xbd, 0xdd, 0xb7, 0x4f, 0x94, 0xb3, 0x7f, 0xd3, 0xc5, 0x35, 0xd8, 0x2d, 0x94, 0xc2,
-            0x87, 0xa2, 0x58, 0x8d, 0x2e, 0xd1, 0x01, 0x45, 0xf7, 0x45, 0xbe, 0xaf, 0x2b, 0x4b, 0x46, 0x4c,
-            0x5a, 0x47, 0xde, 0x14, 0x83, 0x53, 0x26, 0xce, 0xd2, 0xd0, 0x13, 0xa2, 0x39, 0xf9, 0x44, 0x78,
-            0x64, 0xb9, 0xd5, 0x95, 0xc0, 0x51, 0xa6, 0x83, 0x29, 0xac, 0xad, 0xb8, 0x94, 0x62, 0x0f, 0x2b,
-            0xad, 0xd7, 0xbc, 0x8d, 0xcd, 0x8e, 0x76, 0x3e, 0xe9, 0xd6, 0x59, 0xf6, 0xf3, 0xc9, 0xe1, 0xe0,
-            0xe0, 0xd1, 0xe9, 0xf1, 0x2d, 0x77, 0x8f, 0x8a, 0x99, 0x04, 0x1b, 0x1c, 0x12, 0x70, 0x47, 0xb5,
-            0x99, 0xf9, 0x72, 0x01, 0x85, 0x20, 0xc1, 0x77, 0xe3, 0x36, 0x27, 0xce, 0x30, 0xda, 0xf6, 0x70,
-            0xa8, 0x9b, 0x9e, 0x1f, 0x3f, 0x41, 0x19, 0x41, 0x85, 0x38, 0xae, 0xe4, 0xe8, 0x1e, 0xa0, 0xba,
-            0x09, 0xcc, 0x3c, 0x56, 0x4b, 0xd4, 0x32, 0x13, 0x11, 0xa6, 0x88, 0x9a, 0x86, 0x58, 0x8d, 0xcc,
-            0x23, 0x30, 0x48, 0x31, 0xff, 0xc6, 0x73, 0xba, 0xfc, 0xc3, 0xed, 0xed, 0x76, 0x04, 0x9c, 0x63,
-            0x86, 0x43, 0xad, 0x06, 0x24, 0x26, 0xf9, 0x6e, 0xf3, 0xdc, 0x52, 0xa3, 0x38, 0x29, 0x40, 0xa2,
-            0x22, 0x91, 0x2d, 0xf2, 0xbf, 0x84, 0x6f, 0xcd, 0x36, 0x48, 0x83, 0x73, 0xca, 0x0e, 0x92, 0xb0,
-            0xc4, 0x68, 0x77, 0xac, 0x6d, 0x4c, 0x43, 0x39, 0x90, 0x84, 0x4b, 0xa6, 0x0c, 0x80, 0x69, 0xc1,
-            0xa5, 0xce, 0x3a, 0xcb, 0x05, 0x9e, 0xf6, 0xce, 0x59, 0x32, 0x8c, 0x73, 0x9c, 0x9f, 0xab, 0x37,
-            0xf2, 0x36, 0x0c, 0x85, 0x83, 0x17, 0x28, 0x1f, 0x7d, 0xd8, 0xaf, 0x7d, 0xcc, 0x08, 0x07, 0x8a,
-            0x67, 0x42, 0x69, 0x2a, 0x5b, 0xba, 0x06, 0xcf, 0x16, 0x96, 0x52, 0xb9, 0xa5, 0x92, 0xb1, 0x29,
-            0x92, 0x91, 0x95, 0xda, 0x7f, 0xa6, 0x51, 0xce, 0x0d, 0xfd, 0x7a, 0xcf, 0xf9, 0xde, 0x2a, 0x5a,
-            0xeb, 0xed, 0x8a, 0x28, 0x22, 0xed, 0x11, 0x94, 0xac, 0xfa, 0xe2, 0x9d, 0x01, 0xf1, 0xc2, 0x4c,
-            0x2e, 0x83, 0x24, 0x7a, 0x87, 0x35, 0x19, 0x0c, 0x5b, 0x2f, 0x17, 0xb9, 0x3a, 0xae, 0xd5, 0xb5,
-            0xc5, 0xda, 0xbf, 0xf2, 0x6a, 0x5f, 0x07, 0x12, 0x19, 0x4d, 0x79, 0xef, 0x80, 0x25, 0xf5, 0xbb,
-            0x34, 0x37, 0xbc, 0xd9, 0x78, 0x04, 0xe4, 0x60, 0x8f, 0x39, 0x97, 0x91, 0x03, 0x97, 0xcf, 0x8e,
-            0x5b, 0x18, 0x92, 0x2e, 0x42, 0x17, 0xce, 0x99, 0x72, 0xe9, 0xe1, 0xdc, 0xb2, 0x4c, 0x54, 0x61,
-            0x98, 0x79, 0x59, 0x5e, 0xc3, 0xee, 0xa4, 0x1f, 0x58, 0x30, 0x25, 0x2c, 0x59, 0x1d, 0xce, 0xc4,
-            0xf1, 0x2b, 0xd7, 0xa6, 0x58, 0xe5, 0x46, 0xce, 0x11, 0xf1, 0x35, 0x15, 0xda, 0x55, 0xe1, 0xd1,
-            0xbd, 0x03, 0x64, 0x9b, 0x32, 0x44, 0x76, 0x3c, 0xaf, 0x82, 0xe2, 0x4d, 0x18, 0x48, 0x6c, 0x2d,
-            0xf8, 0xdf, 0xee, 0xad, 0xdd, 0x70, 0x8d, 0xe0, 0x84, 0x95, 0x4a, 0x90, 0x6c, 0x3b, 0x22, 0xec,
-            0x24, 0xe9, 0xfe, 0x8a, 0x61, 0x3a, 0xea, 0x5b, 0x89, 0x1b, 0xc2, 0x83, 0x2b, 0xbd, 0x98, 0x89,
-            0x97, 0x42, 0xfd, 0xd2, 0xe4, 0x22, 0x44, 0x63, 0x2d, 0xd9, 0x45, 0x1d, 0xbf, 0xd8, 0xf1, 0x9c,
-            0x03, 0x17, 0xdc, 0x28, 0x8b, 0x6d, 0xe8, 0xce, 0xb4, 0x32, 0xd1, 0x30, 0xc5, 0x0e, 0x65, 0x06,
-            0x20, 0xf0, 0x56, 0xe6, 0x58, 0x82, 0x93, 0x3f, 0xb4, 0x9d, 0x94, 0xf5, 0xe8, 0x8a, 0xa9, 0x5d,
-            0x9e, 0xaa, 0x36, 0xe5, 0xcd, 0xba, 0x16, 0xd1, 0xcc, 0x3e, 0x70, 0xc0, 0x17, 0x1a, 0xca, 0xd2,
-            0x94, 0x91, 0x8f, 0x35, 0x1f, 0xcf, 0xc2, 0x48, 0x35, 0x68, 0xa6, 0x36, 0x62, 0x20, 0x94, 0xc2,
-            0xc7, 0x2f, 0x79, 0xde, 0x35, 0xf7, 0x72, 0x9f, 0x7b, 0x1a, 0xa4, 0x6b, 0x99, 0xc5, 0x38, 0xe5,
-            0xf0, 0xbe, 0xb0, 0x4b, 0xc7, 0x55, 0x66, 0x68, 0xef, 0x4a, 0x8c, 0xbd, 0x1a, 0x28, 0xb8, 0xea,
-            0xd4, 0x6e, 0x8a, 0x30, 0x13, 0x9b, 0xfa, 0x15, 0x37, 0x13, 0x6d, 0xc1, 0x83, 0x96, 0xf9, 0x76,
-            0xaa, 0x96, 0x83, 0x20, 0xfc, 0xfb, 0xac, 0x29, 0xe3, 0xfa, 0x18, 0xae, 0x25, 0x9b, 0x10, 0x42,
-            0xf9, 0xc4, 0xbd, 0x15, 0x24, 0xe9, 0xcf, 0x8a, 0x5a, 0x39, 0x82, 0x96, 0xa1, 0xe7, 0x3c, 0x5c,
-            0xfa, 0x3f, 0xac, 0x62, 0x13, 0xa0, 0x19, 0xdc, 0x85, 0xcb, 0x30, 0x38, 0x98, 0x29, 0x0f, 0xad,
-            0x43, 0x06, 0xa9, 0x0a, 0x51, 0x3e, 0x1b, 0x72, 0xc9, 0x56, 0x59, 0x9a, 0x7a, 0xdb, 0x5b, 0x00,
-            0x47, 0x0f, 0x84, 0xd9, 0x77, 0x0c, 0xa8, 0xcc, 0x8e, 0xd9, 0x7b, 0xa7, 0x0f, 0x63, 0xcb, 0xdf,
-            0x8e, 0x69, 0x45, 0x74, 0xc3, 0xbd, 0x77, 0x65, 0x13, 0x8d, 0x8e, 0x82, 0x42, 0x16, 0x5d, 0x4d,
-            0x88, 0xfa, 0x1c, 0xf6, 0x10, 0x03, 0xe4, 0xcf, 0xe0, 0xc7, 0x4f, 0x80, 0x5d, 0x21, 0x13, 0x61,
-            0xc5, 0x4e, 0xf9, 0xbc, 0xd2, 0xcb, 0xe5, 0x8b, 0x59, 0x52, 0x46, 0x73, 0xea, 0xdb, 0xcb, 0xb3,
-            0x59, 0xff, 0x10, 0x3b, 0xd0, 0x16, 0x9a, 0x49, 0xd6, 0x97, 0xa3, 0x9e, 0xc8, 0xfc, 0xd1, 0x8a,
-            0x58, 0x5d, 0x6d, 0x3c, 0x9a, 0x4e, 0xfa, 0x52, 0xa1, 0x61, 0xe0, 0x11, 0x7f, 0x8b, 0x50, 0x3d,
-            0xa3, 0x6a, 0x6f, 0x3d, 0xf6, 0x0a, 0x65, 0x20, 0x93, 0x2d, 0xb7, 0x1c, 0xc7, 0xa6, 0x77, 0x80,
-            0x98, 0x4f, 0xf0, 0x57, 0x58, 0xd1, 0x05, 0x47, 0x76, 0xf4, 0x45, 0xde, 0xb1, 0xbd, 0xff, 0x0c,
-            0x54, 0x4c, 0x49, 0xa9, 0xd2, 0xa8, 0x05, 0x48, 0xbd, 0x43, 0x73, 0x85, 0x70, 0xf2, 0xe2, 0xb1,
-            0xab, 0x42, 0xf0, 0x3e, 0x49, 0x32, 0x72, 0x03, 0x71, 0x0a, 0x59, 0x5e, 0x31, 0x7a, 0xc4, 0xd5,
-            0x2c, 0x38, 0xc3, 0x77, 0x5e, 0x14, 0x7a, 0x37, 0x74, 0xb4, 0xc6, 0x6f, 0x46, 0x13, 0x5e, 0xf6,
-            0x26, 0x9a, 0xf8, 0x6b, 0xa5, 0x11, 0x89, 0xb5, 0x22, 0x3a, 0x36, 0xec, 0x75, 0x59, 0xae, 0xfb,
-            0x48, 0xfa, 0xd9, 0xdc, 0x39, 0xb2, 0x08, 0xe2, 0xbb, 0x06, 0x3a, 0x80, 0xc0, 0x91, 0x54, 0x56,
-            0xab, 0xee, 0xac, 0xd8, 0xe1, 0x83, 0xb6, 0x2d, 0xfc, 0xf2, 0x9b, 0xe0, 0xe9, 0x37, 0xc8, 0xba,
-            0x78, 0x8d, 0x85, 0xf6, 0xba, 0x15, 0x96, 0x92, 0x6a, 0x3c, 0x91, 0xcb, 0x45, 0x23, 0x7f, 0xa4,
-            0x57, 0x65, 0xc0, 0x59, 0x32, 0xb6, 0x1e, 0x47, 0x0d, 0x6b, 0x66, 0xa9, 0xda, 0x02, 0x37, 0xd3,
-            0xff, 0xe5, 0x86, 0x65, 0x22, 0x5b, 0x60, 0xa9, 0xd2, 0xc7, 0xe3, 0xff, 0x70, 0x7e, 0xbc, 0x75,
-            0x77, 0xde, 0x4a, 0x3f, 0xea, 0xc0, 0x92, 0x88, 0x2b, 0x26, 0x06, 0xd0, 0x1e, 0xa2, 0x98, 0x4a,
-            0x6a, 0xf8, 0x58, 0x9c, 0xd4, 0x3e, 0xf6, 0xe5, 0x77, 0x7c, 0xbe, 0x14, 0x93, 0x64, 0xa1, 0xdf,
-            0x14, 0x69, 0xb6, 0x36, 0x01, 0xc5, 0x0b, 0xc3, 0x7c, 0xb6, 0x0a, 0x19, 0xe4, 0xb7, 0xef, 0x58,
-            0xfc, 0xfc, 0x98, 0x82, 0xe7, 0xf6, 0xb9, 0x92, 0xcb, 0x0a, 0x87, 0x9a, 0x2b, 0x43, 0xd8, 0x91,
-            0xde, 0x45, 0xa4, 0xa3, 0x95, 0xf8, 0x7d, 0x98, 0xe9, 0x45, 0xa1, 0x32, 0x71, 0xd8, 0xdc, 0xa3,
-            0xa0, 0xbb, 0xa7, 0xe1, 0xb2, 0x3f, 0xe3, 0x4c, 0x11, 0x90, 0xea, 0x85, 0x1c, 0x82, 0xf9, 0x3d,
-            0x4d, 0x1f, 0x4c, 0x0b, 0xe6, 0xf6, 0xad, 0xb8, 0x12, 0x1c, 0x23, 0xe2, 0x2c, 0xba, 0xcd, 0x7c,
-            0x1b, 0x9f, 0xa3, 0x5e, 0xdc, 0x78, 0x96, 0xdf, 0x5d, 0x81, 0xd1, 0x01, 0xea, 0x3f, 0x15, 0xb3,
-            0x84, 0x99, 0x98, 0x5e, 0xb5, 0xf4, 0x8c, 0x0a, 0xb1, 0x97, 0xce, 0x5e, 0xb5, 0x52, 0x47, 0x17,
-            0xef, 0xbe, 0x59, 0x8e, 0x85, 0xfd, 0x60, 0xc4, 0xe1, 0xd7, 0xe0, 0x4a, 0x6c, 0x59, 0xc3, 0x07,
-            0x3b, 0x7b, 0x72, 0xcb, 0x57, 0x23, 0x8a, 0x3d, 0x66, 0x3b, 0x22, 0x6d, 0x9a, 0x05, 0x4d, 0xf8,
-            0xe1, 0xe8, 0xf9, 0x77, 0xcd, 0xbd, 0x42, 0x34, 0xb2, 0x6c, 0x39, 0xa1, 0x59, 0xd5, 0x64, 0x11,
-            0x1d, 0x74, 0x5b, 0x99, 0xc4, 0xf9, 0xcc, 0x9e, 0x62, 0x09, 0x98, 0x4d, 0xe4, 0x3f, 0x76, 0x62,
-            0x12, 0x2d, 0xff, 0xcc, 0x3a, 0x31, 0x1a, 0xa4, 0x67, 0xff, 0x0c, 0xdb, 0xc7, 0xcf, 0x64, 0x4f,
-            0x37, 0x9c, 0x8d, 0x05, 0x90, 0x48, 0x20, 0x39, 0x03, 0x18, 0x3a, 0xd9, 0x04, 0x3c, 0xf5, 0xbc,
-            0x98, 0xb2, 0x96, 0x8d, 0x74, 0x94, 0xf9, 0xf7, 0x58, 0xf7, 0x62, 0x3e, 0xf5, 0xcd, 0x2a, 0x83,
-            0xab, 0xc0, 0xdd, 0xed, 0x29, 0x06, 0x7c, 0xeb, 0x53, 0x89, 0x99, 0xa7, 0x64, 0xd8, 0x11, 0x11,
-            0xbb, 0xb4, 0xcd, 0x9c, 0xee, 0x25, 0x15, 0xcd, 0xd3, 0xa0, 0x19, 0xd2, 0xed, 0x65, 0x42, 0x54,
-            0x27, 0x44, 0x9d, 0x1a, 0x0d, 0x22, 0x70, 0xf7, 0x94, 0x8f, 0x9b, 0x77, 0xe2, 0x91, 0x4e, 0x25,
-            0xe3, 0x4c, 0xa0, 0x0f, 0x3c, 0x44, 0xa7, 0x22, 0x73, 0x17, 0x0f, 0xcc, 0xa5, 0x41, 0x49, 0x0b,
-            0xbf, 0x97, 0x45, 0x18, 0x96, 0xf6, 0xc4, 0x3c, 0x56, 0xbd, 0xba, 0x76, 0x78, 0x53, 0x6d, 0x9f,
-            0x24, 0xe2, 0xa7, 0x5c, 0xc8, 0xe6, 0xb6, 0x4f, 0x38, 0x76, 0x21, 0xa4, 0xc7, 0x3f, 0x16, 0x56,
-            0x7e, 0x42, 0x19, 0xb7, 0x87, 0xa2, 0x5c, 0x48, 0xca, 0x99, 0xb1, 0xaf, 0x57, 0x1e, 0xef, 0xbf,
-            0x8f, 0xed, 0x0b, 0x59, 0x3d, 0xf0, 0x7c, 0x86, 0x53, 0xfc, 0xc3, 0x12, 0x95, 0x97, 0x08, 0x06,
-            0xc0, 0x45, 0x1b, 0xf7, 0x0f, 0x5c, 0x7b, 0xfb, 0x35, 0xfd, 0xba, 0xe7, 0x3f, 0x8f, 0x49, 0x7d,
-            0x48, 0x5a, 0xd6, 0x77, 0xc7, 0x9a, 0xc0, 0xae, 0xf1, 0x01, 0x5d, 0x10, 0x1b, 0x15, 0xf4, 0xa5,
-            0xfc, 0xa5, 0xd8, 0x4f, 0xa7, 0x7c, 0x1c, 0xce, 0xf9, 0x91, 0x09, 0x44, 0x94, 0x97, 0x8b, 0x25,
-            0xfb, 0x69, 0xd9, 0x96, 0x29, 0x22, 0x66, 0x17, 0xac, 0xe7, 0xe3, 0xbd, 0xc7, 0xe4, 0x6b, 0x8d,
-            0xf6, 0xeb, 0xd8, 0x7e, 0x8c, 0x36, 0x34, 0x12, 0x79, 0x9e, 0x81, 0x10, 0xe2, 0x96, 0x44, 0xb3,
-            0xda, 0xe1, 0x5b, 0xfb, 0xb4, 0x06, 0x2a, 0x4a, 0xb6, 0x7e, 0xb8, 0x57, 0x82, 0xab, 0x72, 0x6e,
-            0x6f, 0xc2, 0x3b, 0xce, 0x74, 0xae, 0x5d, 0xc4, 0xbe, 0xf8, 0xd3, 0x71, 0xea, 0x30, 0x9a, 0x2b,
-            0x1c, 0xa4, 0xa8, 0x23, 0xd0, 0x14, 0x58, 0xb2, 0x95, 0xf6, 0x43, 0x11, 0x73, 0x73, 0x9b, 0x75,
-            0x66, 0xdf, 0x3d, 0x62, 0x49, 0x95, 0x98, 0x91, 0x0e, 0x7b, 0xba, 0x27, 0xe0, 0xb4, 0xe0, 0x16,
-            0x6e, 0xab, 0x2a, 0x9b, 0xb4, 0xaf, 0xe6, 0x30, 0xbf, 0x90, 0x87, 0xa7, 0x81, 0xfc, 0xa1, 0x88,
-            0x96, 0xc7, 0xe6, 0xad, 0xb5, 0xe7, 0xce, 0xaa, 0x48, 0x59, 0x34, 0xb1, 0x20, 0xf7, 0xc0, 0xec,
-            0x5f, 0xd6, 0x62, 0xff, 0xd6, 0xd1, 0x69, 0x5d, 0x9b, 0xad, 0x1c, 0x07, 0x2d, 0x63, 0x92, 0xeb,
-            0x9b, 0x54, 0x5b, 0x67, 0x40, 0x0d, 0x8e, 0xa2, 0xcb, 0xac, 0x54, 0x8d, 0x0c, 0xa7, 0x35, 0xe1,
-            0x39, 0x8d, 0x02, 0x50, 0x38, 0x40, 0xde, 0x13, 0x08, 0x89, 0xd7, 0x18, 0x00, 0x11, 0xc4, 0x58,
-            0xd4, 0x1a, 0x16, 0x1b, 0x06, 0x39, 0x9e, 0xce, 0xdd, 0x4d, 0xb4, 0x38, 0xbe, 0x02, 0x5b, 0xec,
-            0xb6, 0xb0, 0xdb, 0x18, 0xcb, 0x86, 0x60, 0x32, 0x1b, 0x4d, 0xdb, 0x5c, 0x65, 0x89, 0x07, 0x68,
-            0x6f, 0x7f, 0x82, 0xba, 0x18, 0xee, 0xf2, 0xf3, 0x11, 0xf0, 0x2e, 0x04, 0xe2, 0xf5, 0x5b, 0x15,
-            0x0f, 0x36, 0x4a, 0xb9, 0x11, 0x7a, 0x27, 0x5c, 0x64, 0x07, 0xea, 0x26, 0x9b, 0xd0, 0x51, 0x3b,
-            0x3b, 0xa9, 0x6a, 0x91, 0x7f, 0x44, 0x2d, 0xe6, 0xfa, 0x50, 0x49, 0xf4, 0x81, 0xbb, 0xdd, 0xed,
-            0xef, 0xef, 0x7e, 0x4d, 0xe9, 0xe0, 0xfa, 0x66, 0x08, 0x53, 0x6c, 0x90, 0x9a, 0x94, 0xe6, 0x56,
-            0x7e, 0x33, 0x4e, 0x1b, 0x41, 0x68, 0xb9, 0x97, 0xb3, 0xb9, 0x7f, 0x2f, 0x4b, 0x41, 0x6c, 0xf0,
-            0x75, 0xb8, 0x70, 0x4f, 0x95, 0x6c, 0x08, 0xef, 0xb6, 0x1f, 0x82, 0x06, 0x2f, 0x86, 0xba, 0x1d,
-            0x74, 0xfb, 0xcd, 0x38, 0x65, 0xe2, 0x81, 0x7b, 0xb9, 0xd7, 0xf8, 0xba, 0xb3, 0x94, 0x89, 0x6f,
-            0x70, 0x6c, 0x0c, 0x0c, 0xce, 0x57, 0x9c, 0xc4, 0xcb, 0x23, 0x3d, 0xb4, 0xb6, 0x49, 0xac, 0x30,
-            0x36, 0x2a, 0x13, 0x6c, 0x91, 0xee, 0x2d, 0x8c, 0x01, 0x15, 0xad, 0x39, 0x28, 0xee, 0xb9, 0x70,
-            0xb3, 0x25, 0xda, 0xd2, 0xa7, 0xe7, 0x90, 0x10, 0x52, 0x0c, 0x12, 0x23, 0x4e, 0x8d, 0xe8, 0xad,
-            0x4d, 0xce, 0x26, 0x1e, 0xa3, 0xb0, 0x89, 0xf9, 0xf6, 0x52, 0x18, 0xf7, 0x6f, 0xed, 0x66, 0x71,
-            0x11, 0x3d, 0x3c, 0x4d, 0xf0, 0xe3, 0x7e, 0x97, 0xc1, 0x2c, 0xb7, 0x63, 0x24, 0x7a, 0xfb, 0x42,
-            0x5e, 0x45, 0xd3, 0x4b, 0x81, 0xb5, 0xa1, 0x19, 0x25, 0x88, 0x4c, 0x97, 0xa4, 0xf3, 0xe9, 0xac,
-            0xf4, 0x6d, 0xe3, 0x62, 0x46, 0xf6, 0x91, 0x8f, 0x66, 0xd6, 0xd4, 0x92, 0x15, 0x0c, 0x90, 0x6e,
-            0xaf, 0x51, 0x4d, 0xe2, 0xd7, 0x8e, 0x43, 0x7f, 0x69, 0xd3, 0x5f, 0x19, 0xd4, 0x5f, 0xb8, 0x09,
-            0x56, 0x66, 0x6a, 0x2d, 0x6e, 0xdb, 0x72, 0x29, 0xb7, 0xe6, 0xca, 0x18, 0x4f, 0xcd, 0x0b, 0x9d,
-            0x3c, 0x97, 0xc8, 0xd3, 0x3d, 0x27, 0xcc, 0xf2, 0xe3, 0x2c, 0xf1, 0x76, 0x39, 0x15, 0x25, 0x3e,
-            0x3b, 0xe4, 0x5b, 0x10, 0x5c, 0x3e, 0xc5, 0x29, 0xef, 0x35, 0x5d, 0x0b, 0x77, 0x9f, 0x02, 0xfb,
-            0x0c, 0x8d, 0xbd, 0x73, 0xb6, 0xa5, 0xb3, 0x9a, 0x62, 0xb7, 0x22, 0x0d, 0x7e, 0xc6, 0xee, 0xbc,
-            0xef, 0x4e, 0x6d, 0x00, 0x72, 0xb9, 0x53, 0xb7, 0xc2, 0xe9, 0xd0, 0xae, 0xd7, 0x35, 0x12, 0x3c,
-            0x99, 0x74, 0xba, 0xcb, 0x5e, 0xc4, 0x6e, 0x41, 0xdf, 0xde, 0x87, 0x2a, 0x33, 0x20, 0x15, 0x67,
-            0x17, 0x13, 0x8e, 0xc0, 0x8e, 0x84, 0x49, 0x63, 0x81, 0x7e, 0x47, 0xb9, 0x0e, 0x76, 0xda, 0x2e,
-            0x7c, 0xa3, 0x2c, 0x1f, 0xcf, 0x7b, 0x37, 0xa9, 0xd9, 0xb8, 0x48, 0x2d, 0x7d, 0x9a, 0xaf, 0x7f,
-            0x6e, 0x5f, 0x06, 0x82, 0x11, 0x54, 0xab, 0xfc, 0xc8, 0xf4, 0xd9, 0x43, 0xfb, 0x9c, 0xa3, 0xf8,
-            0xb4, 0x72, 0xf0, 0xa2, 0x77, 0x8b, 0x91, 0x89, 0x82, 0x62, 0xef, 0x47, 0xb2, 0x3f, 0xf4, 0x18,
-            0xfc, 0x46, 0x2f, 0x30, 0xc6, 0x3b, 0x6a, 0xd2, 0xf3, 0x86, 0xf8, 0xb0, 0x3e, 0x73, 0xd4, 0x6a,
-            0xc8, 0x6b, 0xe0, 0x84, 0x98, 0xb6, 0xe5, 0x86, 0xd7, 0x55, 0x09, 0x82, 0x46, 0x97, 0xb6, 0xe0,
-            0xf8, 0x63, 0xbb, 0x5f, 0x0a, 0x14, 0xf9, 0x97, 0x7f, 0x8e, 0xd1, 0x51, 0xfa, 0xda, 0x7d, 0xec,
-            0x9c, 0x32, 0xbe, 0x30, 0xcf, 0x98, 0x89, 0xe7, 0x46, 0x21, 0xfe, 0x44, 0x89, 0x07, 0xe2, 0xec,
-            0x6f, 0x79, 0x5b, 0x4f, 0x9d, 0x3a, 0xa2, 0xc9, 0xdb, 0xa2, 0x70, 0xcf, 0x7e, 0xf7, 0x39, 0x3d,
-            0x06, 0xd4, 0x55, 0x83, 0x0a, 0x7a, 0xcd, 0x2e, 0x49, 0x0b, 0x75, 0x77, 0x6f, 0x56, 0x17, 0x9b,
-            0xae, 0xee, 0x6e, 0x41, 0x46, 0xee, 0xde, 0x3a, 0xf7, 0x6b, 0xd8, 0x46, 0xd1, 0xb5, 0xa6, 0xf1,
-            0x56, 0xae, 0x56, 0xdb, 0x0d, 0xdb, 0xd6, 0x15, 0x4b, 0x53, 0xfa, 0x1c, 0xb4, 0xf3, 0xd5, 0xe2,
-            0x8f, 0x44, 0xc1, 0x2b, 0x3e, 0x0f, 0xff, 0xfb, 0x77, 0xba, 0x41, 0x88, 0x5e, 0x51, 0x6f, 0x0c,
-            0xd1, 0x06, 0xa9, 0x1f, 0x9b, 0xec, 0x76, 0x7c, 0xa5, 0x2e, 0x9b, 0x09, 0xe8, 0xe8, 0xa0, 0x68,
-            0x23, 0xcb, 0x86, 0xa4, 0x73, 0x16, 0xbf, 0x28, 0xeb, 0xa8, 0x44, 0x9d, 0xff, 0x6a, 0x77, 0x76,
-            0xa4, 0x82, 0x29, 0xee, 0xc2, 0xf9, 0x64, 0xfa, 0xfb, 0x3a, 0x7a, 0xff, 0xcb, 0x82, 0x0b, 0x9a,
-            0x40, 0xb5, 0x06, 0xf2, 0xe7, 0x98, 0x8b, 0x84, 0xc2, 0x77, 0x7e, 0xcc, 0xda, 0x1f, 0x3e, 0xfe,
-            0x89, 0x3a, 0x89, 0x28, 0xe0, 0x73, 0x53, 0xde, 0xe5, 0x7a, 0x78, 0x77, 0x42, 0xbd, 0x44, 0x49,
-            0x59, 0x2f, 0x77, 0x45, 0x6f, 0x25, 0x6e, 0xf8, 0x21, 0xcd, 0x6e, 0x9d, 0x9a, 0x2a, 0x07, 0x30,
-            0x9c, 0xe6, 0xd1, 0x5a, 0x77, 0x52, 0xbc, 0xc8, 0x08, 0x8f, 0x57, 0x45, 0x15, 0x43, 0x36, 0xdf,
-            0x24, 0x96, 0x34, 0xb0, 0xa8, 0xd7, 0x63, 0xcc, 0xbe, 0x3b, 0x51, 0x54, 0x06, 0xc4, 0xce, 0x57,
-            0x4b, 0xfd, 0x2e, 0x0f, 0xd2, 0x53, 0x40, 0x4c, 0x27, 0xa6, 0x5c, 0xf4, 0x59, 0x24, 0x36, 0xe9,
-            0x6a, 0xf3, 0x24, 0x09, 0x10, 0xdc, 0x99, 0x57, 0x51, 0x75, 0x6f, 0x54, 0x59, 0x92, 0x0f, 0x68,
-            0xd5, 0xfa, 0x94, 0x54, 0xfb, 0xc9, 0x39, 0xd7, 0xe6, 0xe3, 0xa8, 0x78, 0x64, 0xff, 0xae, 0x16,
-            0xd1, 0x01, 0xb0, 0x4b, 0xf4, 0x46, 0x3e, 0x87, 0x27, 0x70, 0x4a, 0x9f, 0xa9, 0xbe, 0xbc, 0x61,
-            0x57, 0xf2, 0xc5, 0xf9, 0x2a, 0x30, 0x5a, 0x53, 0x81, 0xdb, 0xde, 0x94, 0xbf, 0x00, 0xc1, 0x35,
-            0xb8, 0x61, 0x25, 0x17, 0x1e, 0x7f, 0xe3, 0x07, 0xde, 0x23, 0x61, 0xc6, 0x20, 0x92, 0x31, 0x07,
-            0xf0, 0x85, 0x54, 0x78, 0x30, 0xf7, 0xc6, 0x3e, 0x71, 0x54, 0x54, 0x6f, 0x44, 0x44, 0x08, 0x3d,
-            0x2c, 0x58, 0xfc, 0x46, 0xc7, 0x2c, 0xf3, 0x2a, 0xdc, 0xc8, 0xea, 0x66, 0xc9, 0x8e, 0x03, 0xb4,
-            0xf6, 0xdb, 0xce, 0x24, 0x76, 0x45, 0xd6, 0x3c, 0x44, 0x3e, 0xc8, 0xf2, 0x66, 0x21, 0x7c, 0x77,
-            0xec, 0x78, 0xb5, 0xc2, 0x56, 0xdc, 0x88, 0xdc, 0xc3, 0xc9, 0x9f, 0xc3, 0x4f, 0x45, 0xd1, 0x7f,
-            0x9b, 0x9d, 0x42, 0xc3, 0xd7, 0x88, 0x95, 0x86, 0xea, 0xc0, 0xee, 0x89, 0xfd, 0x65, 0x9b, 0x68,
-            0xcb, 0x1a, 0xfd, 0xf4, 0x95, 0x6b, 0x6c, 0x88, 0xf4, 0xa6, 0x13, 0x4f, 0x74, 0x50, 0x6b, 0x3c,
-            0xc7, 0x61, 0x04, 0xb2, 0x5a, 0x71, 0x40, 0xb4, 0x70, 0x85, 0xb0, 0xc2, 0x6f, 0xed, 0x70, 0xc7,
-            0xe0, 0x15, 0x34, 0x5e, 0xed, 0x9d, 0x7e, 0x9f, 0x1c, 0x15, 0x2c, 0xb7, 0x2f, 0x71, 0xf6, 0x0e,
-            0x08, 0xcb, 0x3c, 0xbc, 0x0c, 0x2f, 0x94, 0x3f, 0x4f, 0xee, 0x7f, 0xa5, 0xc1, 0x2f, 0xdb, 0x6e,
-            0x65, 0xff, 0xf8, 0x5e, 0xf3, 0x1f, 0xf2, 0x9f, 0x58, 0x97, 0x9b, 0x8c, 0x6d, 0xbd, 0xb9, 0x50,
-            0x9a, 0x85, 0x3c, 0x35, 0x41, 0x40, 0x72, 0xe9, 0xe6, 0x03, 0x8b, 0x04, 0x8e, 0xa5, 0xb3, 0x91,
-            0x29, 0x7c, 0x5f, 0x22, 0x06, 0x38, 0x9d, 0x90, 0x59, 0x68, 0x0c, 0x26, 0x1a, 0x70, 0x15, 0x3b,
-            0xad, 0x30, 0x40, 0x75, 0x63, 0x2a, 0x1b, 0x9f, 0x14, 0x9c, 0x80, 0x00, 0xb7, 0xb5, 0x5a, 0x22,
-            0xbb, 0x1c, 0x03, 0xfb, 0xc6, 0x7b, 0xd5, 0x8d, 0xa6, 0xa5, 0x1a, 0xd0, 0xcf, 0xf4, 0xf2, 0x4c,
-            0xbe, 0xec, 0xe1, 0xa8, 0x37, 0x9c, 0xd0, 0xd7, 0xcb, 0x47, 0x48, 0xec, 0x28, 0x35, 0x63, 0xef,
-            0xe1, 0x7e, 0x39, 0xad, 0x37, 0xce, 0x76, 0xe3, 0x26, 0x7d, 0x69, 0xae, 0xfa, 0xcd, 0x3d, 0x1b,
-            0x0a, 0x4f, 0x32, 0x71, 0x68, 0x27, 0x0f, 0xb5, 0x59, 0x27, 0x56, 0x38, 0x14, 0x76, 0xdc, 0x5e,
-            0xb9, 0x50, 0x6d, 0xdf, 0xe8, 0x0c, 0xf7, 0x57, 0xad, 0xe4, 0xd1, 0x85, 0xbc, 0xc1, 0x67, 0x9f,
-            0x56, 0x3e, 0x90, 0x6b, 0x00, 0x60, 0x8e, 0x80, 0x0b, 0x7d, 0xff, 0xbd, 0x3e, 0x21, 0xb5, 0xa8,
-            0xdf, 0xab, 0xd1, 0x47, 0x2b, 0xf1, 0xa9, 0xfd, 0x26, 0x0e, 0xe7, 0x46, 0xb1, 0x42, 0xb8, 0x3a,
-            0x35, 0x1a, 0x62, 0x93, 0x88, 0x67, 0xe9, 0x99, 0x3a, 0xd5, 0x21, 0xd6, 0xa2, 0x9f, 0xe9, 0xe8,
-            0xd5, 0xec, 0xb3, 0x4e, 0x87, 0xd1, 0x01, 0x66, 0x38, 0x93, 0xe7, 0xfb, 0x8c, 0xcd, 0x6d, 0xe2,
-            0x6c, 0x2b, 0x55, 0x6c, 0x33, 0xe4, 0x92, 0x75, 0x4b, 0x6b, 0xa1, 0xb8, 0x9e, 0x6b, 0xee, 0x78,
-            0x92, 0x21, 0x1a, 0x6f, 0x52, 0x72, 0xf1, 0x4a, 0xac, 0xc8, 0x1a, 0x45, 0x67, 0x73, 0x8a, 0xe4,
-            0x5b, 0xb9, 0xaf, 0xa6, 0x97, 0x8f, 0xb0, 0xbd, 0xa5, 0x69, 0x2e, 0xb4, 0xae, 0x99, 0x5d, 0x29,
-            0xb4, 0x97, 0xf2, 0xf9, 0xd6, 0xae, 0x8d, 0xe6, 0x13, 0x76, 0x0d, 0x5a, 0x18, 0xe2, 0xdf, 0xcf,
-            0x3d, 0xc7, 0xd1, 0x42, 0x6b, 0x1a, 0xf6, 0x57, 0xb8, 0xe8, 0xc7, 0xc6, 0x6b, 0x39, 0x75, 0x0b,
-            0x1e, 0x5a, 0x3d, 0x1d, 0x1f, 0xc0, 0xcd, 0xc5, 0x80, 0x1f, 0xd1, 0x1c, 0x7b, 0xd5, 0xad, 0x38,
-            0x1b, 0x49, 0xe5, 0xa6, 0x45, 0x5a, 0x6f, 0xa6, 0x5f, 0x90, 0x42, 0x07, 0x19, 0x81, 0x8d, 0x42,
-            0x8c, 0x10, 0xa7, 0xdb, 0xf9, 0x13, 0x81, 0x49, 0x17, 0xce, 0x6a, 0xc0, 0x81, 0xd1, 0x5b, 0x9c,
-            0xce, 0xd4, 0xd1, 0x29, 0x87, 0x5c, 0xb6, 0x7d, 0xd6, 0xe6, 0x35, 0x8b, 0xac, 0xa3, 0x4b, 0x24,
-            0xa3, 0x0e, 0x63, 0xac, 0x16, 0xff, 0xe3, 0x38, 0x72, 0x61, 0x15, 0x28, 0x68, 0x4f, 0x5c, 0x66,
-            0x6b, 0x62, 0xfd, 0x51, 0x04, 0x83, 0x0f, 0xcf, 0x12, 0x5a, 0xfb, 0xfa, 0x90, 0x0f, 0x61, 0x80,
-            0x92, 0x05, 0x68, 0x87, 0x0f, 0x29, 0xc0, 0xfe, 0xa3, 0x27, 0xbc, 0x59, 0x16, 0x5d, 0xe4, 0x4a,
-            0xe2, 0x0d, 0x2b, 0x42, 0x4e, 0xd1, 0x6e, 0x42, 0xf7, 0x11, 0xdf, 0xe6, 0xeb, 0xeb, 0xfb, 0x4e,
-            0x5e, 0x29, 0x59, 0xc4, 0xbf, 0x2d, 0x39, 0x25, 0x4c, 0xa0, 0xd8, 0x57, 0xac, 0xf1, 0xde, 0x64,
-            0x38, 0xa0, 0xdb, 0xa9, 0x81, 0xb5, 0xf1, 0x79, 0x69, 0x12, 0x68, 0x7a, 0x6e, 0x9a, 0xe0, 0x09,
-            0x7e, 0x68, 0x7f, 0x0c, 0x49, 0x87, 0x3d, 0x75, 0x3d, 0xf8, 0xc3, 0x7d, 0x59, 0x59, 0xb7, 0x15,
-            0xf6, 0xf7, 0xb1, 0x59, 0xae, 0x77, 0xf1, 0x5c, 0xb4, 0xd7, 0x94, 0x3b, 0x11, 0x58, 0xf1, 0x35,
-            0x9c, 0xb6, 0xde, 0xa7, 0x43, 0xcc, 0xb0, 0xd7, 0x83, 0x18, 0xa2, 0x36, 0xbe, 0x4a, 0x52, 0xcf,
-            0x52, 0xd2, 0x2c, 0x97, 0x32, 0xc6, 0x89, 0x4d, 0xc7, 0xde, 0x7a, 0xc9, 0x17, 0xf2, 0x9a, 0x9f,
-            0xf5, 0x61, 0x2b, 0xa6, 0xbf, 0x59, 0x06, 0x69, 0x90, 0x77, 0x10, 0x11, 0x7d, 0x4d, 0x51, 0x67,
-            0x9e, 0xd8, 0x8c, 0x29, 0x2a, 0x57, 0x0b, 0x0c, 0xf9, 0x48, 0x73, 0xb1, 0x73, 0x82, 0xa0, 0x24,
-            0x50, 0x63, 0xce, 0xb0, 0x63, 0xaf, 0x20, 0xdd, 0x02, 0x85, 0x79, 0xf1, 0x8a, 0x6c, 0x27, 0xe5,
-            0x70, 0x49, 0x30, 0x78, 0x1a, 0x32, 0x84, 0x9e, 0x4e, 0x3d, 0x10, 0x2d, 0x59, 0xb8, 0x62, 0x51,
-            0xa1, 0xbf, 0xc9, 0xbb, 0x7a, 0xae, 0xaa, 0xd5, 0xe5, 0x5d, 0x51, 0x48, 0x90, 0x4f, 0x16, 0xc7,
-            0x1a, 0x15, 0x2c, 0xd9, 0x2e, 0xa0, 0x23, 0xa0, 0x3b, 0xb5, 0x0f, 0xf3, 0xf5, 0x7c, 0x5d, 0x46,
-            0x95, 0xed, 0x51, 0xe6, 0x44, 0x05, 0x77, 0xa7, 0xae, 0x45, 0xe7, 0xa8, 0xe4, 0xc5, 0xb6, 0x42,
-            0x22, 0x09, 0x3d, 0xa3, 0x7e, 0x8f, 0x07, 0x3a, 0x2f, 0xd7, 0xde, 0xa4, 0x59, 0xbd, 0xd2, 0x79,
-            0x08, 0xd0, 0x2c, 0xb7, 0x15, 0x7f, 0xa2, 0x8e, 0x1d, 0xdf, 0xdd, 0x90, 0x50, 0x30, 0xfe, 0x7b,
-            0x8e, 0xae, 0xea, 0xd5, 0x22, 0xf0, 0x00, 0xe5, 0x99, 0xa0, 0x17, 0x28, 0x50, 0x00, 0x69, 0x89,
-            0x0c, 0x09, 0xd2, 0x89, 0x2d, 0x49, 0xcc, 0xac, 0x66, 0xb8, 0xa8, 0x18, 0x71, 0x3d, 0x40, 0x6b,
-            0xbe, 0x97, 0xc3, 0x6d, 0xc7, 0x13, 0x6e, 0xb5, 0x4d, 0xc4, 0x9f, 0x4c, 0xcb, 0xf1, 0x57, 0xc0,
-            0xbb, 0x16, 0x17, 0xcf, 0x22, 0x2b, 0x4f, 0xc8, 0x82, 0x8a, 0x17, 0xa5, 0x1a, 0x5d, 0x9f, 0x52,
-            0x26, 0x76, 0x53, 0x9a, 0x31, 0x5c, 0x6a, 0x09, 0xda, 0x15, 0x76, 0x95, 0x56, 0x8d, 0xf6, 0x6b,
-            0xa5, 0x99, 0x16, 0x2d, 0xd8, 0x88, 0x89, 0x83, 0xcd, 0x43, 0x2c, 0xb8, 0x61, 0x17, 0x06, 0x2f,
-            0x43, 0xc4, 0xa5, 0xce, 0xf6, 0xd9, 0x6c, 0x93, 0x23, 0x24, 0xaf, 0x5e, 0x4b, 0xe9, 0xd7, 0x5d,
-            0xc1, 0xd0, 0xbb, 0x11, 0x9d, 0x95, 0x26, 0xc7, 0xe6, 0x64, 0xb1, 0x51, 0x58, 0xbd, 0x2f, 0x23,
-            0xac, 0x92, 0x66, 0xa6, 0xed, 0x5f, 0x5f, 0x42, 0x1f, 0x48, 0xb5, 0x21, 0xa9, 0x8d, 0x9d, 0x5b,
-            0xe6, 0x63, 0x75, 0x55, 0x1a, 0xa4, 0x12, 0x3f, 0x88, 0xdf, 0xe1, 0xa4, 0x12, 0xed, 0x7e, 0xf8,
-            0x60, 0x90, 0xb3, 0x37, 0xe6, 0x2a, 0xbe, 0xf0, 0xd5, 0xaa, 0x70, 0xa5, 0x17, 0x29, 0x9a, 0x87,
-            0xe4, 0x1a, 0x46, 0x0f, 0xa6, 0x03, 0x8d, 0xca, 0xf9, 0xab, 0x2d, 0x29, 0x1a, 0xb0, 0x0a, 0xb8,
-            0xc2, 0x12, 0x7a, 0xc2, 0xc7, 0x42, 0xca, 0x4b, 0x86, 0x1f, 0xf9, 0x25, 0xb0, 0x15, 0xe7, 0x23,
-            0x18, 0xee, 0x42, 0xe4, 0xce, 0x20, 0x3b, 0x4e, 0xff, 0xe2, 0x11, 0x75, 0xa1, 0xe1, 0xbb, 0xd2,
-            0xcb, 0x01, 0xa0, 0x1e, 0xb4, 0x97, 0x77, 0x3e, 0x0c, 0x8c, 0x74, 0x4f, 0x33, 0xa4, 0xae, 0x12,
-            0xd0, 0x03, 0x06, 0x87, 0xb6, 0xe0, 0xf9, 0xc3, 0x77, 0x1d, 0x60, 0xd0, 0x7e, 0x42, 0x4f, 0x3b,
-            0x64, 0xd6, 0x29, 0x8a, 0xf6, 0x34, 0x12, 0xa6, 0x4b, 0xca, 0x04, 0xfb, 0xd9, 0xd6, 0xee, 0x8b,
-            0xa7, 0xa6, 0x85, 0xd9, 0xf2, 0x81, 0x7b, 0xca, 0x9d, 0x61, 0x3f, 0x90, 0x14, 0x1f, 0xc5, 0xd4,
-            0xdd, 0xb2, 0xe9, 0x3a, 0x31, 0xa3, 0xcf, 0x32, 0x7c, 0x07, 0x41, 0xb3, 0x70, 0xc3, 0x25, 0x37,
-            0x66, 0x93, 0xf4, 0x33, 0x6b, 0xa5, 0x3b, 0x58, 0x69, 0xe8, 0x58, 0xa1, 0x77, 0x4b, 0x41, 0x13,
-            0x97, 0x7f, 0x0b, 0xa9, 0xd6, 0x9d, 0xe4, 0x2e, 0x2e, 0x47, 0x3a, 0x4a, 0xaa, 0x4b, 0x7c, 0x71,
-            0x2e, 0xbc, 0x83, 0x0b, 0xce, 0xcf, 0xf7, 0x81, 0xc1, 0xd7, 0xb4, 0x25, 0xeb, 0x3f, 0x08, 0x25,
-            0xaa, 0x31, 0xac, 0xa3, 0xcf, 0x10, 0x73, 0x2f, 0x0d, 0xad, 0x5a, 0xe6, 0xad, 0x13, 0xc1, 0xa8,
-            0xae, 0xf3, 0x0a, 0x7c, 0xc2, 0x0b, 0x8a, 0xe5, 0x7a, 0x8e, 0x63, 0xa7, 0xa7, 0x41, 0x4d, 0x21,
-            0x8c, 0x53, 0xb0, 0xe8, 0x2c, 0xff, 0xd1, 0xae, 0x2d, 0x50, 0x55, 0x6a, 0x4f, 0xeb, 0x2e, 0x71,
-            0xc0, 0x44, 0xc0, 0xe4, 0xd4, 0xe2, 0x4f, 0x77, 0xf0, 0x3b, 0x5d, 0x03, 0xd0, 0x13, 0xc7, 0xc9,
-            0x3f, 0x03, 0x99, 0x9a, 0xea, 0x8d, 0x35, 0x28, 0x87, 0x0f, 0x19, 0x9c, 0x60, 0x02, 0xb0, 0x36,
-            0x06, 0x99, 0xb7, 0xb7, 0x6a, 0x3e, 0x8b, 0x06, 0x90, 0xfe, 0x7e, 0x72, 0x82, 0x86, 0x1f, 0x00,
-            0x53, 0x0a, 0x5b, 0xa9, 0xce, 0x69, 0xaf, 0x00, 0x62, 0xf5, 0x73, 0x4e, 0xd6, 0xf0, 0xdd, 0x2a,
-            0x69, 0x47, 0x73, 0xc7, 0x89, 0x16, 0x2d, 0x85, 0x67, 0xeb, 0x02, 0x66, 0x33, 0x66, 0x71, 0x5d,
-            0x34, 0xc3, 0xa8, 0xce, 0x69, 0xb2, 0x63, 0xb5, 0xee, 0x1c, 0x36, 0xc2, 0x0f, 0xf3, 0xe8, 0x7d,
-            0xf4, 0x88, 0x56, 0xd6, 0x8f, 0xe7, 0xf0, 0x5a, 0x9c, 0xc8, 0x09, 0x8f, 0x0d, 0x92, 0x81, 0x0a,
-            0xf7, 0xfe, 0xc0, 0x70, 0xc7, 0xb5, 0x56, 0x2b, 0xc5, 0x91, 0xf3, 0x9e, 0x14, 0xec, 0x2e, 0x0f,
-            0x46, 0xfe, 0xf7, 0x27, 0x53, 0x37, 0x79, 0xb4, 0xf8, 0xcb, 0x2f, 0xed, 0xa0, 0x72, 0xb4, 0xc3,
-            0x22, 0xd3, 0x71, 0xff, 0x12, 0xe4, 0x5a, 0xce, 0x9e, 0x08, 0x13, 0x1c, 0xd7, 0x44, 0xca, 0x35,
-            0xe7, 0x22, 0xc0, 0x8c, 0x9f, 0xc9, 0xbf, 0x8f, 0xd5, 0xd3, 0x4b, 0x7f, 0x7b, 0xc4, 0x38, 0xbd,
-            0x36, 0x07, 0x05, 0x07, 0x57, 0x44, 0xfe, 0x4e, 0xbd, 0x66, 0x87, 0x75, 0x4f, 0x28, 0xe8, 0xce,
-            0x57, 0x17, 0x65, 0xb0, 0xba, 0x05, 0xd0, 0x41, 0x5e, 0x5b, 0x3b, 0x1c, 0x8e, 0xd7, 0x8f, 0xf0,
-            0xb2, 0x3c, 0x84, 0x9a, 0x9c, 0x33, 0xd9, 0xb2, 0x0d, 0xcf, 0x07, 0xa4, 0xfd, 0x9b, 0x9f, 0xfc,
-            0xde, 0xa3, 0xbe, 0xcf, 0xf2, 0xda, 0xd0, 0xfd, 0xb9, 0xae, 0xb5, 0xec, 0x08, 0x5e, 0xaa, 0xb3,
-            0xf2, 0x7d, 0x60, 0x70, 0x25, 0x6b, 0x36, 0x4c, 0x44, 0x88, 0xb3, 0x26, 0xa5, 0x4b, 0x4c, 0x1c,
-            0x2d, 0x6d, 0x10, 0xe4, 0xad, 0x74, 0x20, 0x99, 0xc0, 0xca, 0x90, 0xdb, 0x4c, 0x13, 0xd5, 0x41,
-            0x21, 0x05, 0xec, 0x95, 0x49, 0x71, 0x40, 0x1f, 0x66, 0x1b, 0x4b, 0x8e, 0x43, 0x9d, 0x42, 0x00,
-            0x31, 0xf2, 0x63, 0xd2, 0x0b, 0xd9, 0x6d, 0x6e, 0x54, 0x73, 0x20, 0x97, 0x0c, 0x3e, 0xa4, 0x58,
-            0x2e, 0xb8, 0xfe, 0xb4, 0x6c, 0x63, 0x2a, 0xb7, 0x30, 0xb9, 0x49, 0x55, 0x50, 0xb8, 0x19, 0xe5,
-            0xac, 0xaa, 0x94, 0x4e, 0xbc, 0x73, 0xb3, 0x0c, 0xc5, 0x85, 0xcf, 0xbd, 0x08, 0xed, 0x24, 0x1c,
-            0x10, 0xfc, 0x91, 0x3e, 0x49, 0x6f, 0x14, 0x63, 0xdf, 0x20, 0x8b, 0xef, 0xe6, 0x34, 0x4e, 0x5d,
-            0xdd, 0xe2, 0xb0, 0xdc, 0x0b, 0xff, 0xa4, 0xab, 0x64, 0xc4, 0x64, 0xa5, 0x6e, 0x7b, 0xcd, 0xaa,
-            0xb2, 0x07, 0xbe, 0x76, 0x2a, 0x6c, 0xe0, 0x6a, 0xf0, 0xfb, 0x73, 0x90, 0xe0, 0xc0, 0xa5, 0x97,
-            0x13, 0x4c, 0xf2, 0x74, 0x49, 0x0d, 0x2d, 0x48, 0xef, 0x47, 0xa7, 0x3a, 0xfd, 0x59, 0xe1, 0xab,
-            0xc4, 0x12, 0x40, 0x22, 0xfb, 0x9e, 0xde, 0x92, 0xed, 0x2e, 0x82, 0x85, 0x1d, 0x79, 0x5f, 0x0a,
-            0xd6, 0x06, 0xc3, 0xae, 0xac, 0x8c, 0xe0, 0xee, 0xff, 0x9c, 0x18
-        };
-
-    }
-}

+ 0 - 415
src/Static/HtmxSseResource.vala

@@ -1,415 +0,0 @@
-using Spry;
-using Invercargill;
-
-namespace Spry.Static {
-
-    // Generated by spry-mkssr
-    public class HtmxSseResource : ConstantStaticResource {
-
-        public override string name { get { return "htmx-sse.js"; } }
-        public override string file_hash { get { return "8357797afa6479580d65394c88ad347b793cdce0541da5eba62f9f617e80fee575287b4056c430f03855bc453a17d64e255fdcb8a2e5aacf9dc6d439e8a23545"; } }
-        public override string content_type { get { return "text/javascript"; } }
-
-        public override string get_best_encoding(Set<string> supported) {
-            if (supported.has("br")) return "br";
-            if (supported.has("zstd")) return "zstd";
-            if (supported.has("gzip")) return "gzip";
-            return "identity";
-        }
-
-        public override unowned uint8[] get_encoding(string encoding) {
-            switch (encoding) {
-                case "identity": return IDENTITY_DATA;
-                case "gzip": return GZIP_DATA;
-                case "zstd": return ZSTD_DATA;
-                case "br": return BR_DATA;
-                default: return IDENTITY_DATA;
-            }
-        }
-
-        private const uint8[] IDENTITY_DATA = {
-            0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20,
-            0x67, 0x3b, 0x68, 0x74, 0x6d, 0x78, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x45, 0x78, 0x74,
-            0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x22, 0x73, 0x73, 0x65, 0x22, 0x2c, 0x7b, 0x69, 0x6e,
-            0x69, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x67,
-            0x3d, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x68, 0x74, 0x6d, 0x78, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74,
-            0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3d, 0x3d, 0x75, 0x6e,
-            0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x29, 0x7b, 0x68, 0x74, 0x6d, 0x78, 0x2e, 0x63, 0x72,
-            0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3d,
-            0x74, 0x7d, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73,
-            0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75,
-            0x72, 0x6e, 0x5b, 0x22, 0x5b, 0x73, 0x73, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
-            0x5d, 0x22, 0x2c, 0x22, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x73, 0x73, 0x65, 0x2d, 0x63, 0x6f,
-            0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5d, 0x22, 0x2c, 0x22, 0x5b, 0x73, 0x73, 0x65, 0x2d, 0x73, 0x77,
-            0x61, 0x70, 0x5d, 0x22, 0x2c, 0x22, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x73, 0x73, 0x65, 0x2d,
-            0x73, 0x77, 0x61, 0x70, 0x5d, 0x22, 0x5d, 0x7d, 0x2c, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74,
-            0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x76,
-            0x61, 0x72, 0x20, 0x72, 0x3d, 0x74, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x7c, 0x7c, 0x74,
-            0x2e, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x2e, 0x65, 0x6c, 0x74, 0x3b, 0x73, 0x77, 0x69, 0x74,
-            0x63, 0x68, 0x28, 0x65, 0x29, 0x7b, 0x63, 0x61, 0x73, 0x65, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a,
-            0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x45, 0x6c, 0x65,
-            0x6d, 0x65, 0x6e, 0x74, 0x22, 0x3a, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x67, 0x2e, 0x67, 0x65,
-            0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x72, 0x29,
-            0x3b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x3d, 0x6e, 0x2e, 0x73, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e,
-            0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x73, 0x29, 0x7b, 0x67, 0x2e,
-            0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x28, 0x72, 0x2c, 0x22,
-            0x68, 0x74, 0x6d, 0x78, 0x3a, 0x73, 0x73, 0x65, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x22, 0x2c, 0x7b,
-            0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x73, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x6e,
-            0x6f, 0x64, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x22, 0x7d, 0x29, 0x3b, 0x6e,
-            0x2e, 0x73, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e,
-            0x63, 0x6c, 0x6f, 0x73, 0x65, 0x28, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x63,
-            0x61, 0x73, 0x65, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x50, 0x72,
-            0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x22, 0x3a, 0x69, 0x28, 0x72, 0x29, 0x7d,
-            0x7d, 0x7d, 0x29, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x65,
-            0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x45, 0x76, 0x65,
-            0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x28, 0x65, 0x2c, 0x7b, 0x77, 0x69, 0x74, 0x68,
-            0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x3a, 0x74, 0x72, 0x75, 0x65,
-            0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x28, 0x6e, 0x29,
-            0x7b, 0x69, 0x66, 0x28, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
-            0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x6e, 0x2c, 0x22, 0x73, 0x73, 0x65, 0x2d, 0x73,
-            0x77, 0x61, 0x70, 0x22, 0x29, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x3d, 0x67, 0x2e, 0x67,
-            0x65, 0x74, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x6e,
-            0x2c, 0x76, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x73, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x76, 0x61, 0x72, 0x20,
-            0x65, 0x3d, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44,
-            0x61, 0x74, 0x61, 0x28, 0x73, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, 0x65, 0x2e, 0x73,
-            0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3b, 0x76, 0x61,
-            0x72, 0x20, 0x74, 0x3d, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
-            0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x6e, 0x2c, 0x22, 0x73, 0x73, 0x65, 0x2d, 0x73,
-            0x77, 0x61, 0x70, 0x22, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x74, 0x2e, 0x73, 0x70,
-            0x6c, 0x69, 0x74, 0x28, 0x22, 0x2c, 0x22, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72,
-            0x20, 0x69, 0x3d, 0x30, 0x3b, 0x69, 0x3c, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b,
-            0x69, 0x2b, 0x2b, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x75, 0x3d, 0x72, 0x5b, 0x69,
-            0x5d, 0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63,
-            0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x6c, 0x28, 0x73, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x69, 0x66, 0x28,
-            0x21, 0x67, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x28,
-            0x6e, 0x29, 0x29, 0x7b, 0x61, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e,
-            0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x75, 0x2c, 0x63, 0x29, 0x3b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x69, 0x66, 0x28, 0x21, 0x67, 0x2e, 0x74, 0x72, 0x69, 0x67,
-            0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x28, 0x6e, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78,
-            0x3a, 0x73, 0x73, 0x65, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
-            0x65, 0x22, 0x2c, 0x65, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x66, 0x28,
-            0x6e, 0x2c, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x67, 0x2e, 0x74, 0x72, 0x69, 0x67,
-            0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x28, 0x6e, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78,
-            0x3a, 0x73, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2c, 0x65, 0x29, 0x7d,
-            0x3b, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x61,
-            0x74, 0x61, 0x28, 0x6e, 0x29, 0x2e, 0x73, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69,
-            0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x3d, 0x63, 0x3b, 0x61, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76,
-            0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x75, 0x2c, 0x63, 0x29,
-            0x7d, 0x7d, 0x69, 0x66, 0x28, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62,
-            0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x6e, 0x2c, 0x22, 0x68, 0x78, 0x2d, 0x74,
-            0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x22, 0x29, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x3d,
-            0x67, 0x2e, 0x67, 0x65, 0x74, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x4d, 0x61, 0x74, 0x63,
-            0x68, 0x28, 0x6e, 0x2c, 0x76, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x73, 0x3d, 0x3d, 0x6e, 0x75, 0x6c,
-            0x6c, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x76,
-            0x61, 0x72, 0x20, 0x65, 0x3d, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e,
-            0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x73, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d,
-            0x65, 0x2e, 0x73, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65,
-            0x3b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x72, 0x69, 0x67,
-            0x67, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x73, 0x28, 0x6e, 0x29, 0x3b, 0x6f, 0x2e, 0x66, 0x6f,
-            0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74,
-            0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2e, 0x73,
-            0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2c, 0x34, 0x29, 0x21, 0x3d, 0x3d, 0x22, 0x73, 0x73, 0x65,
-            0x3a, 0x22, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x72,
-            0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28,
-            0x6c, 0x28, 0x73, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x69, 0x66, 0x28,
-            0x21, 0x67, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x28,
-            0x6e, 0x29, 0x29, 0x7b, 0x61, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e,
-            0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x74, 0x2e, 0x74, 0x72, 0x69, 0x67,
-            0x67, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x34, 0x29, 0x2c, 0x72, 0x29, 0x7d,
-            0x68, 0x74, 0x6d, 0x78, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x28, 0x6e, 0x2c, 0x74,
-            0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x2c, 0x65, 0x29, 0x3b, 0x68, 0x74, 0x6d, 0x78,
-            0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x28, 0x6e, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78,
-            0x3a, 0x73, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2c, 0x65, 0x29, 0x7d,
-            0x3b, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x61,
-            0x74, 0x61, 0x28, 0x6e, 0x29, 0x2e, 0x73, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69,
-            0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x3d, 0x72, 0x3b, 0x61, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76,
-            0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x74, 0x2e, 0x74, 0x72,
-            0x69, 0x67, 0x67, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x34, 0x29, 0x2c, 0x72,
-            0x29, 0x7d, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28,
-            0x65, 0x2c, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29,
-            0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x69, 0x66, 0x28,
-            0x67, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61,
-            0x6c, 0x75, 0x65, 0x28, 0x65, 0x2c, 0x22, 0x73, 0x73, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
-            0x63, 0x74, 0x22, 0x29, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x67, 0x2e, 0x67, 0x65,
-            0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28,
-            0x65, 0x2c, 0x22, 0x73, 0x73, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x22, 0x29,
-            0x3b, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x7d, 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x2c, 0x74, 0x29, 0x7d, 0x61, 0x28, 0x65,
-            0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x72, 0x2c, 0x65,
-            0x2c, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x3d, 0x68, 0x74, 0x6d, 0x78, 0x2e, 0x63,
-            0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65,
-            0x28, 0x65, 0x29, 0x3b, 0x73, 0x2e, 0x6f, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3d, 0x66, 0x75,
-            0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x67, 0x2e, 0x74, 0x72, 0x69, 0x67,
-            0x67, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x28, 0x72, 0x2c,
-            0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x73, 0x73, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c,
-            0x7b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x65, 0x2c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a,
-            0x73, 0x7d, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6c, 0x28, 0x72, 0x29, 0x29, 0x7b, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x7d, 0x69, 0x66, 0x28, 0x73, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74,
-            0x61, 0x74, 0x65, 0x3d, 0x3d, 0x3d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63,
-            0x65, 0x2e, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x29, 0x7b, 0x6e, 0x3d, 0x6e, 0x7c, 0x7c, 0x30,
-            0x3b, 0x6e, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x4d, 0x61, 0x74, 0x68,
-            0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x6e, 0x2a, 0x32, 0x2c, 0x31, 0x32, 0x38, 0x29, 0x2c, 0x31, 0x29,
-            0x3b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2a, 0x35, 0x30, 0x30, 0x3b, 0x77, 0x69, 0x6e,
-            0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x66,
-            0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x28, 0x72, 0x2c, 0x6e, 0x29,
-            0x7d, 0x2c, 0x74, 0x29, 0x7d, 0x7d, 0x3b, 0x73, 0x2e, 0x6f, 0x6e, 0x6f, 0x70, 0x65, 0x6e, 0x3d,
-            0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x67, 0x2e, 0x74, 0x72,
-            0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x28, 0x72, 0x2c, 0x22, 0x68, 0x74,
-            0x6d, 0x78, 0x3a, 0x73, 0x73, 0x65, 0x4f, 0x70, 0x65, 0x6e, 0x22, 0x2c, 0x7b, 0x73, 0x6f, 0x75,
-            0x72, 0x63, 0x65, 0x3a, 0x73, 0x7d, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x26, 0x26, 0x6e, 0x3e,
-            0x30, 0x29, 0x7b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x3d, 0x72, 0x2e, 0x71, 0x75, 0x65,
-            0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x22, 0x5b,
-            0x73, 0x73, 0x65, 0x2d, 0x73, 0x77, 0x61, 0x70, 0x5d, 0x2c, 0x20, 0x5b, 0x64, 0x61, 0x74, 0x61,
-            0x2d, 0x73, 0x73, 0x65, 0x2d, 0x73, 0x77, 0x61, 0x70, 0x5d, 0x2c, 0x20, 0x5b, 0x68, 0x78, 0x2d,
-            0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5d, 0x2c, 0x20, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d,
-            0x68, 0x78, 0x2d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5d, 0x22, 0x29, 0x3b, 0x66, 0x6f,
-            0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x3d, 0x30, 0x3b, 0x65, 0x3c, 0x74, 0x2e, 0x6c, 0x65,
-            0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, 0x2b, 0x2b, 0x29, 0x7b, 0x61, 0x28, 0x74, 0x5b, 0x65, 0x5d,
-            0x29, 0x7d, 0x6e, 0x3d, 0x30, 0x7d, 0x7d, 0x3b, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x6e, 0x74,
-            0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x72, 0x29, 0x2e, 0x73, 0x73, 0x65,
-            0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3d, 0x73, 0x3b, 0x76, 0x61,
-            0x72, 0x20, 0x74, 0x3d, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
-            0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x72, 0x2c, 0x22, 0x73, 0x73, 0x65, 0x2d, 0x63,
-            0x6c, 0x6f, 0x73, 0x65, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x73, 0x2e, 0x61,
-            0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28,
-            0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x67, 0x2e, 0x74,
-            0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x28, 0x72, 0x2c, 0x22, 0x68,
-            0x74, 0x6d, 0x78, 0x3a, 0x73, 0x73, 0x65, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x22, 0x2c, 0x7b, 0x73,
-            0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x73, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x6d, 0x65,
-            0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x7d, 0x29, 0x3b, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65,
-            0x28, 0x29, 0x7d, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c,
-            0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x67, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x43, 0x6f,
-            0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x28, 0x65, 0x29, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74,
-            0x3d, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x61,
-            0x74, 0x61, 0x28, 0x65, 0x29, 0x2e, 0x73, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x6f,
-            0x75, 0x72, 0x63, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x21, 0x3d, 0x75, 0x6e, 0x64, 0x65, 0x66,
-            0x69, 0x6e, 0x65, 0x64, 0x29, 0x7b, 0x67, 0x2e, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45,
-            0x76, 0x65, 0x6e, 0x74, 0x28, 0x65, 0x2c, 0x22, 0x68, 0x74, 0x6d, 0x78, 0x3a, 0x73, 0x73, 0x65,
-            0x43, 0x6c, 0x6f, 0x73, 0x65, 0x22, 0x2c, 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x74,
-            0x2c, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x6e, 0x6f, 0x64, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x69,
-            0x6e, 0x67, 0x22, 0x7d, 0x29, 0x3b, 0x74, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x28, 0x29, 0x3b,
-            0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x7d, 0x72, 0x65, 0x74,
-            0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
-            0x6f, 0x6e, 0x20, 0x66, 0x28, 0x74, 0x2c, 0x72, 0x29, 0x7b, 0x67, 0x2e, 0x77, 0x69, 0x74, 0x68,
-            0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e,
-            0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x3d, 0x65, 0x2e, 0x74, 0x72, 0x61,
-            0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x72,
-            0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x74, 0x29, 0x7d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65,
-            0x3d, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66,
-            0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6e,
-            0x3d, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x28, 0x74, 0x29, 0x3b,
-            0x67, 0x2e, 0x73, 0x77, 0x61, 0x70, 0x28, 0x6e, 0x2c, 0x72, 0x2c, 0x65, 0x2c, 0x7b, 0x63, 0x6f,
-            0x6e, 0x74, 0x65, 0x78, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x74, 0x7d, 0x29,
-            0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x28, 0x65, 0x29, 0x7b, 0x72,
-            0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72,
-            0x6e, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x65, 0x29, 0x2e, 0x73, 0x73, 0x65, 0x45, 0x76,
-            0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x21, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d,
-            0x7d, 0x29, 0x28, 0x29, 0x3b
-        };
-
-        private const uint8[] GZIP_DATA = {
-            0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0xbd, 0x56, 0x4d, 0x8f, 0xdb, 0x36,
-            0x10, 0xfd, 0x2b, 0x5e, 0x1d, 0x02, 0x31, 0xd1, 0x0a, 0x4e, 0x90, 0x02, 0x85, 0x18, 0x16, 0x48,
-            0x37, 0x7b, 0x28, 0x90, 0x6d, 0x8a, 0x38, 0xe8, 0x65, 0xb1, 0x07, 0xae, 0x34, 0x96, 0x09, 0xd0,
-            0x23, 0x97, 0x1c, 0xed, 0x07, 0xbc, 0xfc, 0xef, 0x1d, 0xea, 0xc3, 0xd6, 0x7a, 0xed, 0x36, 0x45,
-            0x8b, 0xde, 0x24, 0x92, 0x43, 0xce, 0xbc, 0x79, 0xf3, 0x66, 0xd2, 0x65, 0x8b, 0x25, 0x99, 0x06,
-            0x53, 0xb1, 0xbd, 0xd3, 0x6e, 0x56, 0xcb, 0x15, 0xad, 0x1f, 0xf2, 0x0a, 0x96, 0x06, 0xe1, 0xf2,
-            0x81, 0x00, 0x7d, 0xdc, 0x4c, 0xbc, 0x87, 0x24, 0xdb, 0x1a, 0x34, 0x54, 0xec, 0x2c, 0x40, 0x6c,
-            0x6b, 0x05, 0xd2, 0x2c, 0xd3, 0xce, 0xa6, 0x74, 0xa0, 0x09, 0x2e, 0xef, 0x00, 0x69, 0xd1, 0xb4,
-            0xae, 0x04, 0xa5, 0x5a, 0xec, 0x2f, 0xaa, 0xc4, 0xf6, 0xc4, 0x11, 0x0a, 0x21, 0xab, 0x81, 0x16,
-            0x60, 0xa1, 0xa4, 0xc6, 0xf9, 0x62, 0xe2, 0x8f, 0x03, 0x6a, 0x1d, 0x5e, 0x27, 0xd7, 0xfc, 0xf8,
-            0x79, 0xd9, 0x20, 0xf2, 0x91, 0x9b, 0x24, 0x4b, 0xae, 0x2b, 0x4d, 0xfa, 0xfc, 0x70, 0x31, 0xfe,
-            0xfb, 0x7b, 0xbd, 0x79, 0x7e, 0xa2, 0x5f, 0xb9, 0x09, 0x59, 0x83, 0xdd, 0xb3, 0x13, 0xef, 0x33,
-            0xea, 0x43, 0x76, 0x8a, 0x72, 0xd2, 0x8e, 0xbd, 0x78, 0x7a, 0x22, 0x8e, 0x9c, 0xb4, 0xb1, 0x39,
-            0x58, 0x92, 0xfe, 0xde, 0x50, 0xb9, 0x8a, 0x61, 0x96, 0x9a, 0xc3, 0x8f, 0x11, 0x14, 0xb7, 0xb0,
-            0x6c, 0x1c, 0x5c, 0x58, 0xd0, 0xd8, 0x6e, 0x2e, 0x2d, 0xac, 0xf9, 0xce, 0xa4, 0x88, 0xd7, 0xa0,
-            0xaa, 0x73, 0xbe, 0xe3, 0x17, 0x24, 0x70, 0xa8, 0xed, 0x27, 0xf6, 0x20, 0x75, 0x42, 0xc6, 0x2d,
-            0xaf, 0x30, 0x67, 0x67, 0x26, 0x71, 0x47, 0xd0, 0x3c, 0xc3, 0x97, 0x93, 0x33, 0x75, 0x0d, 0xae,
-            0xdb, 0x4a, 0x5d, 0xd6, 0x3f, 0xc2, 0x67, 0x2f, 0x6c, 0xd3, 0x21, 0xee, 0xbb, 0xe3, 0x85, 0xcf,
-            0xe8, 0x71, 0x03, 0x45, 0x82, 0x4d, 0x05, 0x5f, 0x61, 0x63, 0x75, 0x09, 0x55, 0x12, 0x84, 0x3c,
-            0xbc, 0x37, 0x2f, 0xa3, 0x5d, 0x2a, 0x42, 0x8f, 0x9d, 0xdc, 0x3b, 0xae, 0x97, 0xec, 0xd7, 0x6f,
-            0xae, 0x29, 0xc1, 0xfb, 0x5f, 0xf9, 0x96, 0xa4, 0x30, 0xec, 0x5e, 0x08, 0x7c, 0xc9, 0x08, 0xc9,
-            0x8c, 0x62, 0xac, 0xbd, 0xe5, 0x0c, 0xe1, 0x7e, 0x36, 0xb9, 0x98, 0xe1, 0xda, 0x32, 0x1c, 0xab,
-            0x0b, 0x07, 0x15, 0x2f, 0x1a, 0x6d, 0x7d, 0x41, 0xae, 0x85, 0x20, 0xc2, 0xce, 0x5c, 0xa7, 0x28,
-            0xb6, 0x1c, 0x58, 0x87, 0xc3, 0x47, 0xe2, 0xd0, 0x6e, 0x5b, 0x82, 0xdf, 0xb5, 0x6d, 0x21, 0xc5,
-            0x2c, 0x19, 0xd3, 0x91, 0x88, 0x1e, 0x77, 0xdf, 0x03, 0xd6, 0x45, 0xea, 0xe9, 0x4a, 0x47, 0xac,
-            0x31, 0xbb, 0x13, 0x1d, 0x36, 0x4a, 0x61, 0x6b, 0xed, 0xde, 0x1b, 0xfe, 0x09, 0xd1, 0x08, 0x8e,
-            0xa0, 0xec, 0x7b, 0x94, 0xb5, 0x82, 0x43, 0x94, 0xe3, 0x32, 0xa9, 0xbf, 0xf5, 0x47, 0x8e, 0x34,
-            0xf0, 0x1b, 0x6b, 0x28, 0x65, 0x02, 0x31, 0x28, 0x8d, 0x4b, 0xe3, 0xb2, 0x51, 0x73, 0x69, 0x3e,
-            0xb8, 0xdc, 0x02, 0xd6, 0xb4, 0x92, 0xe6, 0xcd, 0x1b, 0xa6, 0x43, 0x83, 0x9e, 0x66, 0xad, 0x72,
-            0xd7, 0xe6, 0x26, 0x66, 0x70, 0x9d, 0x0a, 0xd9, 0xaf, 0x95, 0x6a, 0x5a, 0x1d, 0x1c, 0x88, 0x65,
-            0xef, 0xc6, 0x28, 0x02, 0xff, 0x9f, 0xd5, 0xf9, 0x6d, 0x53, 0x3d, 0x5e, 0x34, 0xc8, 0x34, 0x43,
-            0xcf, 0x88, 0x89, 0xad, 0xce, 0x1d, 0xac, 0x9b, 0xbb, 0xde, 0xf3, 0xcf, 0xc6, 0x73, 0xd1, 0x81,
-            0x4b, 0xdb, 0xac, 0x14, 0xf2, 0x99, 0xe1, 0x33, 0xae, 0xe0, 0x9e, 0x2b, 0x3f, 0x77, 0x9c, 0xbc,
-            0xe2, 0xc4, 0xea, 0x9a, 0x39, 0x03, 0xfb, 0x07, 0x97, 0x7c, 0x0c, 0xf2, 0x58, 0x0c, 0x42, 0x9e,
-            0xb6, 0x9f, 0x58, 0x06, 0xf9, 0x12, 0x5e, 0x14, 0x3b, 0x58, 0x47, 0xe7, 0x54, 0x29, 0x75, 0xae,
-            0xab, 0xea, 0xa5, 0xc7, 0x21, 0x9c, 0x26, 0xc0, 0xea, 0xe1, 0x7c, 0x70, 0xe1, 0x7f, 0xa6, 0x40,
-            0xd3, 0x5b, 0x7c, 0xeb, 0x1f, 0x5f, 0x6c, 0xa0, 0x8c, 0xc0, 0xcb, 0x26, 0x67, 0xdc, 0x2e, 0x35,
-            0xbf, 0xb9, 0x4b, 0x1a, 0x75, 0x49, 0xa3, 0x11, 0xaa, 0xdc, 0x5b, 0xc3, 0xdc, 0x9f, 0x67, 0xef,
-            0xc5, 0x99, 0x52, 0x91, 0x31, 0x45, 0xb2, 0x03, 0xb7, 0x27, 0xcd, 0x7f, 0x96, 0xef, 0xc3, 0x47,
-            0xdf, 0x8b, 0x8c, 0xeb, 0xb3, 0x93, 0xcd, 0x61, 0x83, 0xa1, 0xd9, 0x1d, 0xe2, 0x5c, 0xc9, 0x83,
-            0xbd, 0x7f, 0x93, 0x4f, 0x77, 0x2c, 0x9f, 0xc7, 0x3d, 0xe2, 0x14, 0xef, 0x2a, 0xde, 0xf4, 0x2a,
-            0xca, 0x71, 0xc2, 0xb1, 0x6c, 0x9d, 0xa0, 0x02, 0xf4, 0xb5, 0x37, 0x88, 0xf7, 0xc8, 0x05, 0xa7,
-            0xbe, 0xe7, 0x6c, 0x64, 0x86, 0x7b, 0xfe, 0x56, 0x88, 0x5a, 0xee, 0xd8, 0x8f, 0xa0, 0x39, 0x09,
-            0x7b, 0xe7, 0x90, 0xf5, 0x14, 0x32, 0x1c, 0x99, 0x76, 0xbc, 0x01, 0xb1, 0x85, 0xf4, 0x79, 0xc3,
-            0xe1, 0xba, 0xe6, 0x79, 0x32, 0xf7, 0xf5, 0x12, 0xb7, 0x5e, 0x08, 0x74, 0xb7, 0xca, 0x02, 0xdd,
-            0x19, 0x16, 0x90, 0x8d, 0x42, 0x1d, 0x3a, 0x17, 0x2d, 0x6b, 0xeb, 0x94, 0x06, 0x9e, 0x53, 0xae,
-            0xab, 0xc7, 0x05, 0xf1, 0xeb, 0x4a, 0xa9, 0xa9, 0x62, 0x5f, 0x7c, 0xfe, 0xb2, 0xb8, 0xfc, 0x24,
-            0xb6, 0xa8, 0xf0, 0xe9, 0x69, 0x2e, 0x51, 0x71, 0x19, 0xac, 0xf2, 0xb5, 0x7e, 0x48, 0xfb, 0x0f,
-            0x83, 0x29, 0xbe, 0x7e, 0x97, 0xbd, 0x7d, 0xf7, 0xa3, 0xc8, 0xde, 0x8a, 0x41, 0xd2, 0xf0, 0xf5,
-            0x0f, 0xf3, 0xb9, 0xbc, 0x37, 0x58, 0x35, 0xf7, 0xb9, 0x67, 0x6a, 0x9b, 0x35, 0x34, 0x2d, 0xa5,
-            0x93, 0xee, 0xc9, 0xf2, 0xce, 0xc1, 0x87, 0x88, 0x4b, 0xe8, 0x42, 0x6c, 0x36, 0x80, 0x27, 0x22,
-            0x3c, 0x0c, 0xee, 0x0b, 0x1f, 0x9d, 0x34, 0x9f, 0x3e, 0x26, 0x7c, 0xf5, 0x0a, 0x7f, 0x9a, 0x8f,
-            0xea, 0x47, 0xca, 0xe5, 0x7f, 0xb4, 0xe0, 0x1e, 0xc7, 0xd6, 0xfd, 0xd1, 0xda, 0x74, 0xd2, 0x85,
-            0xb3, 0xd9, 0x41, 0x13, 0xe6, 0x85, 0xbd, 0x00, 0xec, 0xb6, 0x27, 0x4b, 0x83, 0xe8, 0x5a, 0x20,
-            0x2e, 0xf1, 0xb9, 0x84, 0x0f, 0x34, 0x8a, 0x2e, 0x44, 0xd1, 0xd5, 0x29, 0x5d, 0xc3, 0x8d, 0x08,
-            0xa8, 0xe6, 0xe1, 0x18, 0xad, 0x9d, 0x38, 0x28, 0x7d, 0xe5, 0xff, 0x42, 0xff, 0xdd, 0xc0, 0xab,
-            0xae, 0xcd, 0x76, 0xe1, 0x31, 0x8f, 0xfd, 0x91, 0x1a, 0xc8, 0x26, 0x90, 0xfe, 0xe3, 0x76, 0xbd,
-            0x1e, 0x2a, 0x31, 0x44, 0x92, 0x8d, 0xad, 0x79, 0x5a, 0x40, 0x76, 0x90, 0x8d, 0x43, 0x99, 0x80,
-            0xa1, 0x28, 0xe8, 0x88, 0xd6, 0x81, 0x38, 0x32, 0x4c, 0xd0, 0xd9, 0x74, 0xd8, 0x3a, 0x70, 0x14,
-            0x4e, 0x3a, 0x4a, 0x93, 0xb9, 0xe2, 0xca, 0x78, 0x6f, 0xb0, 0x8e, 0xce, 0xd2, 0xe8, 0xec, 0xd0,
-            0x80, 0x66, 0x5d, 0xab, 0x1f, 0x86, 0x8a, 0xd9, 0x92, 0x9b, 0x3f, 0xec, 0x63, 0xe0, 0xc7, 0x59,
-            0x17, 0xf8, 0xcd, 0x38, 0x1f, 0xec, 0x46, 0x46, 0x3f, 0x85, 0x2e, 0x8e, 0x15, 0x2c, 0xcd, 0xe4,
-            0x34, 0x7a, 0xce, 0xf1, 0xfa, 0x2b, 0xf8, 0x0d, 0x1f, 0x89, 0x69, 0x88, 0x95, 0x1c, 0x39, 0xda,
-            0x33, 0x7b, 0xd0, 0xf6, 0x05, 0x13, 0x26, 0xca, 0xb4, 0x59, 0x9a, 0x52, 0x0f, 0xc2, 0x2c, 0x27,
-            0x43, 0xd6, 0xb7, 0x6e, 0x5c, 0x8b, 0x8b, 0x75, 0x1e, 0xc9, 0xc5, 0xea, 0x17, 0x6b, 0x3d, 0x52,
-            0x93, 0xe0, 0x81, 0x86, 0xb9, 0xac, 0xa0, 0xe9, 0x74, 0x72, 0x37, 0x19, 0x6e, 0xbe, 0x03, 0xd4,
-            0xb3, 0x4e, 0x63, 0x78, 0x3c, 0x4a, 0x85, 0xfc, 0x13, 0xe5, 0xa4, 0x7f, 0xad, 0x25, 0x0b, 0x00,
-            0x00
-        };
-
-        private const uint8[] ZSTD_DATA = {
-            0x28, 0xb5, 0x2f, 0xfd, 0x60, 0x25, 0x0a, 0x05, 0x21, 0x00, 0x36, 0x35, 0x95, 0x25, 0x00, 0x91,
-            0x56, 0x07, 0xd5, 0x8f, 0xd1, 0x24, 0x42, 0xb4, 0x62, 0x61, 0xe3, 0x7f, 0xde, 0x12, 0x22, 0x1d,
-            0xb6, 0xf3, 0xca, 0x06, 0xf4, 0x98, 0x53, 0xce, 0xa7, 0x0a, 0x8f, 0x95, 0xf0, 0x2c, 0x54, 0x55,
-            0x55, 0xd5, 0xac, 0x88, 0x00, 0x89, 0x00, 0x88, 0x00, 0x53, 0x5c, 0x7e, 0xef, 0x43, 0x5f, 0x72,
-            0x12, 0x5c, 0xa7, 0xe9, 0xbd, 0xe5, 0x93, 0xe4, 0x42, 0x6d, 0xfc, 0x14, 0x39, 0xcf, 0xe8, 0x19,
-            0x4e, 0x73, 0x1a, 0x9f, 0xca, 0xd3, 0x32, 0x43, 0x5f, 0x4f, 0x77, 0x93, 0x8c, 0x7d, 0xc8, 0x75,
-            0x47, 0x47, 0x5f, 0xe2, 0xd8, 0xae, 0x21, 0x77, 0xdb, 0xd9, 0x2a, 0xc6, 0x25, 0x66, 0x28, 0x41,
-            0xec, 0x08, 0x51, 0x9a, 0xd6, 0x60, 0xf4, 0xf3, 0xdd, 0xf9, 0x10, 0x9c, 0x52, 0x4a, 0x43, 0x59,
-            0xa6, 0xfa, 0xec, 0x50, 0x9e, 0xfd, 0x7c, 0xfa, 0xa4, 0x2f, 0xb5, 0x5a, 0xbb, 0x62, 0xd0, 0x52,
-            0x10, 0xfe, 0x61, 0x6a, 0x4e, 0x7a, 0x8f, 0x91, 0xbc, 0xe3, 0xf9, 0x59, 0x91, 0x7c, 0x87, 0x52,
-            0xc5, 0xee, 0xb4, 0x5c, 0x59, 0xb5, 0xe6, 0x94, 0x36, 0x74, 0xdf, 0x1b, 0x92, 0xaf, 0x8c, 0x0e,
-            0xb9, 0x0d, 0x4b, 0x57, 0x9e, 0xf4, 0xe0, 0x88, 0xa9, 0xd8, 0xda, 0x29, 0xfb, 0x59, 0x2a, 0x5a,
-            0x01, 0x6c, 0x60, 0x40, 0xbe, 0x4a, 0x4b, 0xfb, 0xc9, 0xb1, 0x82, 0x7c, 0x10, 0x28, 0x17, 0xcf,
-            0xa8, 0x35, 0xab, 0xe5, 0x74, 0xa1, 0x0f, 0xf6, 0x61, 0xa4, 0xaf, 0xd3, 0x44, 0x2d, 0x84, 0x0c,
-            0xd3, 0x36, 0x46, 0x34, 0xa5, 0xac, 0x69, 0xda, 0xae, 0x53, 0x53, 0xbc, 0x78, 0x53, 0x19, 0x92,
-            0xbb, 0x19, 0x56, 0x24, 0x2b, 0xb6, 0x2b, 0x56, 0x56, 0x4f, 0x71, 0x3b, 0x74, 0x8a, 0xb2, 0xf7,
-            0xd0, 0x39, 0x52, 0x69, 0x99, 0xa9, 0xda, 0xd7, 0x23, 0xf3, 0x7d, 0x7c, 0xf5, 0xe3, 0xb1, 0x5a,
-            0x2b, 0xe3, 0x25, 0x9d, 0xe6, 0xd0, 0x94, 0xa0, 0xf4, 0xcf, 0x64, 0x0a, 0x7e, 0x47, 0xf1, 0x55,
-            0xb6, 0x1e, 0xf7, 0x58, 0x6d, 0xa0, 0x3f, 0x71, 0xba, 0xbc, 0xe2, 0xd0, 0xdc, 0xc6, 0xf9, 0x85,
-            0xa3, 0x1b, 0x75, 0xe8, 0x9c, 0x22, 0xa7, 0xb4, 0xf1, 0xe2, 0x4b, 0x92, 0xe4, 0x76, 0x52, 0xc5,
-            0x28, 0xa5, 0x6e, 0x21, 0x7d, 0x8c, 0x57, 0xec, 0xe8, 0x10, 0xef, 0xd8, 0x13, 0x0e, 0x28, 0x9e,
-            0x1d, 0xe5, 0x35, 0xd5, 0x76, 0x67, 0x32, 0x7f, 0xa7, 0xa3, 0x8f, 0x7d, 0x6d, 0x7b, 0xe3, 0xb5,
-            0x5f, 0xb1, 0xb2, 0x6e, 0x5c, 0x19, 0x72, 0xd3, 0xfe, 0xf6, 0x25, 0x2b, 0xe3, 0xc7, 0xde, 0xda,
-            0xae, 0xca, 0xb8, 0xb1, 0x83, 0xc6, 0x81, 0x10, 0x80, 0x1d, 0x34, 0xc8, 0xfa, 0x23, 0x27, 0xea,
-            0xba, 0x2b, 0x4f, 0x94, 0xf0, 0x8c, 0xdc, 0x7c, 0xcf, 0x2f, 0x13, 0x8b, 0x49, 0xb0, 0x51, 0xa9,
-            0x15, 0x82, 0xa2, 0x8b, 0xef, 0x81, 0x94, 0x3a, 0xb6, 0xaf, 0x3e, 0xe6, 0xde, 0x76, 0x45, 0x6f,
-            0xcd, 0xa5, 0x48, 0xe9, 0x23, 0x1a, 0xf6, 0xb1, 0xa7, 0x51, 0x8b, 0xbf, 0x6f, 0x2a, 0x21, 0x30,
-            0xd3, 0x72, 0x76, 0xb1, 0x62, 0x6c, 0x17, 0x5d, 0x19, 0x7b, 0x67, 0x84, 0x03, 0x9a, 0x19, 0x4e,
-            0x02, 0xa8, 0x8c, 0xae, 0x09, 0x3e, 0x8f, 0x2d, 0x0b, 0x86, 0xa4, 0x30, 0xa4, 0x1e, 0x4d, 0x77,
-            0x3e, 0x55, 0x8f, 0x2d, 0x56, 0x2b, 0x00, 0xa6, 0x9d, 0xde, 0x78, 0xb7, 0x5d, 0x4e, 0xb2, 0xd8,
-            0xf8, 0xc8, 0x48, 0x4e, 0x1e, 0xa3, 0x3b, 0x2f, 0xf4, 0x15, 0x16, 0x9e, 0x11, 0xdd, 0xc8, 0xed,
-            0x0e, 0x99, 0x72, 0xeb, 0x15, 0x9d, 0x4e, 0x31, 0xaa, 0xaf, 0xa5, 0x95, 0x94, 0xca, 0x88, 0x3e,
-            0xc0, 0x3f, 0x55, 0x4b, 0xa3, 0x15, 0x6b, 0xa6, 0x90, 0x2b, 0x04, 0x6e, 0x65, 0x18, 0xa7, 0xf4,
-            0x8a, 0x6f, 0x85, 0xff, 0xd1, 0x9f, 0x1e, 0x6d, 0x4d, 0x13, 0x03, 0x07, 0x9f, 0xd2, 0x70, 0x0c,
-            0x1b, 0xb2, 0xb0, 0x01, 0x01, 0xbb, 0xbf, 0x4c, 0xec, 0x2f, 0xb3, 0x56, 0xb6, 0x8d, 0x97, 0x6c,
-            0x6a, 0xde, 0x22, 0x2d, 0xfa, 0xd4, 0x65, 0x26, 0xb4, 0x32, 0xf3, 0x20, 0x10, 0x04, 0x81, 0x65,
-            0x05, 0x8d, 0x25, 0x18, 0x14, 0x34, 0x03, 0x81, 0x5d, 0x2b, 0xd7, 0x46, 0xb4, 0xb8, 0x4a, 0xc7,
-            0x08, 0xb8, 0x0f, 0xd2, 0xd1, 0xb1, 0x70, 0x2b, 0xe6, 0x20, 0x99, 0x4c, 0x40, 0x44, 0x1c, 0x84,
-            0x30, 0x80, 0xbc, 0xa8, 0x21, 0x39, 0x53, 0x0c, 0x8d, 0x88, 0x48, 0x50, 0x90, 0x24, 0x69, 0x0e,
-            0x40, 0x44, 0x20, 0x08, 0x4d, 0x99, 0x79, 0x62, 0xd0, 0x38, 0x90, 0xb1, 0x18, 0xe3, 0x84, 0x30,
-            0x62, 0x44, 0x48, 0x02, 0x11, 0x49, 0xca, 0x29, 0xac, 0x51, 0x68, 0x0c, 0x67, 0x60, 0x08, 0xcb,
-            0x1b, 0x70, 0x24, 0x57, 0x42, 0x91, 0x80, 0x6d, 0x26, 0xee, 0x09, 0xdd, 0x7b, 0x30, 0xc0, 0xe0,
-            0x71, 0x22, 0xd9, 0xe4, 0x3b, 0x31, 0x1c, 0xe3, 0x8c, 0xa8, 0x1a, 0xbe, 0x34, 0x0e, 0x7f, 0xb7,
-            0x3b, 0x65, 0xd3, 0x3c, 0x6a, 0x14, 0x8f, 0x68, 0xcf, 0x3e, 0x15, 0xb5, 0x51, 0xba, 0x11, 0xe4,
-            0xef, 0x66, 0xf9, 0x23, 0x34, 0x10, 0xc2, 0x7d, 0x9c, 0xd2, 0x9f, 0x04, 0x1b, 0x4c, 0xd4, 0xb6,
-            0x90, 0x07, 0x17, 0xb0, 0xe0, 0x84, 0x4b, 0x7c, 0x70, 0xd2, 0xef, 0x6c, 0xa0, 0x40, 0x60, 0x30,
-            0xad, 0x02, 0xb7, 0xe8, 0x37, 0x51, 0x27, 0xcf, 0x05, 0x68, 0xd2, 0x6b, 0x9c, 0x10, 0xca, 0x2e,
-            0x6a, 0xf5, 0xf6, 0x07, 0xbf, 0xb2, 0xf8, 0x64, 0x16, 0x01, 0xe3, 0x0f, 0x08, 0xd6, 0xe5, 0x20,
-            0x2c, 0x43, 0x9b, 0x7a, 0x8c, 0xdc, 0xee, 0xd9, 0x78, 0x49, 0x58, 0x1a, 0xe2, 0x6b, 0x02, 0x6a,
-            0xb4, 0x50, 0xc4, 0x95, 0x4a, 0x5c, 0x3c, 0xfa, 0x2e, 0xc6, 0x80, 0xf4, 0xb9, 0x22, 0xf7, 0x45,
-            0x06, 0x8c, 0x58, 0x97, 0x41, 0xcd, 0xb0, 0xdb, 0xb8, 0x7b, 0x1f, 0x3d, 0x41, 0x6a, 0x0d, 0x91,
-            0x9c, 0x04, 0x45, 0x08, 0xb5, 0x15, 0x78, 0x6e, 0x82, 0x8f, 0x35, 0x69, 0xb8, 0x9b, 0x87, 0x9c,
-            0x61, 0xd2, 0xe4, 0x79, 0xda, 0x4c, 0x29, 0x00, 0x9a, 0x99, 0x09, 0x6d, 0x62, 0x6d, 0xb0, 0x5d,
-            0x92, 0xe6, 0x73, 0x5d, 0xfc, 0x77, 0x08, 0x19, 0x9f, 0xd1, 0x83, 0x87, 0x81, 0x9b, 0x58, 0x07,
-            0x7e, 0x8f, 0x7d, 0x6f, 0xe3, 0xd7, 0xfa, 0xb6, 0x5c, 0x01, 0x13, 0x88, 0x9a, 0xae, 0xc3, 0xc7,
-            0x20, 0xfa, 0xce, 0x8b, 0x9d, 0x5e, 0x0a, 0x27, 0x01, 0x9b, 0x5f, 0xe1, 0xb8, 0x02, 0x18, 0x4b,
-            0x3d, 0xe9, 0xe2, 0x17, 0x97, 0x26, 0x23, 0x54, 0x31, 0xdf, 0x36, 0x40, 0x99, 0x21, 0x33, 0x03,
-            0x68, 0x60, 0x98, 0x86, 0x04, 0x50, 0xb1, 0x6b, 0x53, 0x06, 0x34, 0xc9, 0xc5, 0x26, 0xfb, 0x53,
-            0x79, 0x60, 0x0b, 0x62, 0x04, 0x88, 0x6e, 0x79, 0xc9, 0x34, 0x58, 0x78, 0xa1, 0x65, 0x71, 0x43,
-            0xde, 0x13, 0x30, 0xca, 0x4f, 0x8e, 0x1e, 0x2e, 0x85, 0xd4, 0xd7, 0xc5, 0x88, 0xe2, 0xb2, 0x34,
-            0xb2, 0x31, 0xb1, 0x0a, 0x30, 0xa1, 0xc9, 0x46, 0xc7, 0x1d, 0x92, 0xfb, 0xd2, 0xd6, 0xf1, 0x1f,
-            0x86, 0x4a, 0x04, 0x83, 0x8f, 0xd5, 0x37, 0xab, 0x76, 0x58, 0x1a, 0xda, 0x7b, 0x77, 0x4d, 0xb2,
-            0x9c, 0x16, 0x8e, 0x99, 0x05, 0xe2, 0xe7, 0xda, 0xcf, 0xe3, 0xf2, 0x16, 0x33, 0xe7, 0x39, 0xfc,
-            0xa9, 0x72, 0x9b, 0xda, 0x36, 0xc2, 0xa5, 0x80, 0xea, 0xbc, 0x80, 0x76, 0x84, 0xdb, 0x38, 0x4e,
-            0xbc, 0xcf, 0xa0, 0x1e, 0xa6, 0x15, 0x3e, 0x15, 0xf1, 0xb3, 0x1a, 0x52, 0x3b, 0x7e, 0x10, 0x28,
-            0xf4, 0x36, 0x95, 0xc4, 0x72, 0x9b, 0xe1, 0x82, 0x98, 0xa8, 0x27, 0xda, 0xa2, 0x79, 0x8a, 0x19,
-            0x82, 0x7f, 0x2d, 0xf9, 0xfa, 0xcf, 0x81, 0x2e, 0xae, 0x02
-        };
-
-        private const uint8[] BR_DATA = {
-            0x1b, 0x24, 0x0b, 0x00, 0x8c, 0xc2, 0x71, 0xef, 0xd3, 0x1e, 0xad, 0x6d, 0x11, 0x4b, 0xd9, 0xe4,
-            0xfb, 0xe9, 0x74, 0x5a, 0x63, 0x97, 0xf4, 0xfb, 0x7e, 0xae, 0xc0, 0xa7, 0xa8, 0x38, 0x8c, 0x1d,
-            0x03, 0x00, 0xe7, 0xa2, 0x2d, 0x6b, 0x4e, 0x54, 0x76, 0xc4, 0xd5, 0x65, 0x30, 0x1b, 0x27, 0x42,
-            0xb9, 0xfe, 0x1e, 0xb2, 0x0b, 0xdc, 0x5f, 0x67, 0xea, 0xf7, 0x2d, 0x9d, 0xbd, 0xf6, 0x7c, 0x54,
-            0x7c, 0x94, 0x6b, 0x08, 0x85, 0x53, 0xc9, 0xfc, 0x9d, 0xa1, 0x96, 0x36, 0xb7, 0xf4, 0xee, 0x52,
-            0x14, 0x38, 0x24, 0x0e, 0x87, 0xb5, 0x4d, 0x1b, 0xd0, 0x35, 0xd2, 0xef, 0x18, 0x43, 0x09, 0x18,
-            0xec, 0xb2, 0x1e, 0x27, 0x49, 0xbe, 0x16, 0x87, 0x7e, 0x8b, 0xf5, 0x6f, 0x10, 0xae, 0x24, 0x02,
-            0x73, 0xf3, 0x5b, 0x4a, 0xe3, 0x9c, 0x8f, 0x32, 0x6a, 0xe2, 0xa3, 0x4a, 0x31, 0x5b, 0x18, 0x06,
-            0xcd, 0x89, 0xcc, 0x4c, 0xea, 0x50, 0x95, 0x01, 0xbd, 0xc5, 0x06, 0x9a, 0x77, 0x41, 0x79, 0xb7,
-            0xc5, 0x76, 0x67, 0x8c, 0x0b, 0x25, 0x3e, 0xd9, 0x1e, 0x52, 0x0a, 0xa2, 0xd0, 0xa5, 0xcd, 0xd6,
-            0xac, 0x34, 0xae, 0x03, 0x3a, 0xd1, 0xce, 0xd9, 0x9a, 0xa5, 0xcf, 0x7a, 0x03, 0x5d, 0x97, 0x9b,
-            0x7e, 0xfa, 0xbb, 0x7b, 0xf1, 0x6e, 0xbc, 0xed, 0xdc, 0x9b, 0xa4, 0x43, 0x12, 0x34, 0xd2, 0x62,
-            0x0f, 0xca, 0x1c, 0x40, 0x1a, 0xac, 0x2a, 0x07, 0x25, 0x4c, 0x06, 0xac, 0x0a, 0x45, 0x8f, 0x44,
-            0xa5, 0xf6, 0xd5, 0x68, 0x5e, 0x19, 0x95, 0x8a, 0xaf, 0xb3, 0x35, 0x7d, 0xed, 0xb8, 0xa1, 0x3e,
-            0x8f, 0x4f, 0xd5, 0x47, 0x8b, 0xb0, 0x94, 0xef, 0x84, 0x51, 0x8c, 0xe5, 0x2a, 0x55, 0x6c, 0xde,
-            0x28, 0x63, 0xa8, 0x24, 0x3b, 0x01, 0x37, 0x55, 0x28, 0x23, 0x68, 0x13, 0xb3, 0x4e, 0x11, 0x13,
-            0xaa, 0xab, 0xb4, 0xac, 0xd8, 0xa8, 0x1b, 0xe5, 0xb5, 0xc7, 0xa2, 0x89, 0xd6, 0xc7, 0x56, 0x36,
-            0xb9, 0xfd, 0xb6, 0x57, 0x47, 0xb9, 0x43, 0x9f, 0x1b, 0x91, 0xdd, 0x68, 0x3a, 0x9c, 0x78, 0x55,
-            0xe6, 0x61, 0x34, 0xdc, 0x08, 0x14, 0x45, 0xf8, 0xe2, 0x93, 0x98, 0x22, 0xb8, 0x3b, 0xd4, 0x48,
-            0xba, 0x2d, 0x70, 0xa3, 0xd2, 0x4b, 0x57, 0xbd, 0xe9, 0x17, 0xf0, 0xb1, 0x3c, 0xe7, 0x63, 0xfd,
-            0x68, 0xbc, 0x29, 0xe6, 0xfd, 0x55, 0x8a, 0xb6, 0xd6, 0xe3, 0xf0, 0xa7, 0x88, 0x4c, 0xe1, 0x8b,
-            0x9c, 0x48, 0x04, 0xdb, 0x04, 0x0d, 0x0c, 0x0b, 0xd9, 0x54, 0xd2, 0x98, 0x03, 0xfb, 0xca, 0x02,
-            0x8d, 0xdb, 0x9e, 0x43, 0xb8, 0xec, 0x06, 0xc8, 0x3f, 0xf0, 0xa9, 0xb7, 0x41, 0x45, 0x25, 0x39,
-            0xa2, 0x2b, 0xca, 0xfd, 0x81, 0xa7, 0x01, 0xe9, 0xa0, 0x8a, 0x9d, 0x06, 0xda, 0x3b, 0xde, 0x57,
-            0x9e, 0xaa, 0xd4, 0x14, 0x84, 0x40, 0xca, 0x78, 0xb5, 0x14, 0xc6, 0x95, 0x69, 0x5d, 0xb3, 0xa1,
-            0x1f, 0x6e, 0x81, 0xca, 0xa5, 0x39, 0xff, 0xfe, 0xda, 0x6d, 0xe2, 0x7a, 0x72, 0x24, 0x9d, 0x72,
-            0xe8, 0xec, 0xca, 0x69, 0x36, 0x06, 0x3c, 0x86, 0x97, 0x14, 0x24, 0x29, 0x77, 0xde, 0xab, 0x8f,
-            0x50, 0x14, 0x25, 0x96, 0x79, 0x53, 0x04, 0xca, 0x59, 0x49, 0x43, 0xee, 0x4d, 0x13, 0x68, 0xef,
-            0x8e, 0x0f, 0x72, 0xf3, 0x84, 0x3e, 0x38, 0x6c, 0x2f, 0x71, 0x34, 0x4c, 0xcb, 0x1d, 0x9e, 0xbb,
-            0x42, 0x24, 0x3a, 0x3e, 0x11, 0x12, 0xbd, 0x7d, 0xb8, 0x23, 0xf4, 0x39, 0xf4, 0xa3, 0x6f, 0x71,
-            0x85, 0xb8, 0x85, 0x80, 0x56, 0x32, 0x98, 0xdf, 0x4e, 0x9d, 0xc4, 0x83, 0x5c, 0xdf, 0xd1, 0xdd,
-            0x08, 0xba, 0x66, 0xbf, 0xf5, 0x6c, 0xfc, 0xa7, 0x5d, 0xb0, 0xb9, 0xe5, 0x34, 0xee, 0xb3, 0x3d,
-            0x81, 0x3f, 0x4f, 0x77, 0xb8, 0xb6, 0x87, 0x68, 0xe9, 0x95, 0x28, 0xce, 0x77, 0xb5, 0xe1, 0x42,
-            0x20, 0x4f, 0xd6, 0x74, 0x7e, 0x90, 0x0d, 0xcb, 0x67, 0x2d, 0xb1, 0x01, 0x0c, 0xc3, 0xf9, 0x1b,
-            0x3a, 0xb7, 0x27, 0x9c, 0x9e, 0xf7, 0x53, 0x70, 0x3d, 0xc9, 0x8d, 0x3d, 0x42, 0xde, 0x31, 0x87,
-            0x80, 0x1e, 0x0e, 0x53, 0xa7, 0x81, 0xf6, 0x9d, 0xab, 0x2b, 0xf0, 0x52, 0x3f, 0x98, 0x02, 0xc2,
-            0x76, 0x1a, 0x34, 0xb6, 0x27, 0x73, 0x70, 0xa0, 0x09, 0x5c, 0x36, 0x8e, 0xf6, 0x79, 0x7f, 0x58,
-            0x47, 0x12, 0x7d, 0xdd, 0x37, 0x02, 0x8a, 0x86, 0xf7, 0x05, 0x94, 0xb4, 0x9c, 0x22, 0x82, 0xb4,
-            0xb6, 0x3d, 0x38, 0xa1, 0x29, 0x01, 0xb4, 0x62, 0x5d, 0x11, 0x56, 0xa8, 0x2a, 0x33, 0x74, 0xb3,
-            0x9d, 0xa4, 0x71, 0x4b, 0x66, 0x84, 0x07, 0x77, 0x47, 0x90, 0xac, 0x3b, 0x1c, 0x6a, 0x0a, 0x89,
-            0x3a, 0x52, 0x3d, 0x3e, 0x79, 0x66, 0xc3, 0x58, 0xdb, 0x44, 0x0f, 0xfa, 0xbb, 0x28, 0x69, 0xac,
-            0xaa, 0xae, 0xb4, 0xbf, 0x67, 0x1f, 0xfc, 0xf5, 0x7f, 0xe5, 0xc2, 0x47, 0xf3, 0x8d, 0xf0, 0xfc,
-            0x9a, 0xef, 0xeb, 0x47, 0x9c, 0xa9, 0x02, 0xad, 0xa5, 0xaf, 0x1d, 0xba, 0xbb, 0xbc, 0x54, 0x6f,
-            0xbf, 0xbb, 0x27, 0x5f, 0x57, 0xa6, 0x88, 0x84, 0x63, 0x53, 0xe1, 0x62, 0x92, 0xeb, 0xdf, 0x7d,
-            0xba, 0x8b, 0x80, 0xf4, 0x2d, 0xe1, 0xcc, 0xd4, 0x22, 0xd7, 0x32, 0x9e, 0x9e, 0xf2, 0xf9, 0x92,
-            0x01, 0x1d, 0xa3, 0x87, 0x25, 0xe2, 0xbe, 0xb3, 0xdf, 0xd6, 0x12, 0x4f, 0xdc, 0xc2, 0xd7, 0xb4,
-            0xe4, 0x4a, 0x45, 0x02, 0x25, 0x77, 0xd1, 0x57, 0x33, 0xf1, 0xc6, 0xd6, 0xb8, 0xa8, 0x21, 0x8a,
-            0x86, 0x3d, 0xfc, 0xea, 0x14, 0x37, 0xd1, 0x86, 0x6f, 0xac, 0xbb, 0x69, 0x07, 0x52, 0xe8, 0xde,
-            0xd5, 0xca, 0x07, 0x04, 0x82, 0xcb, 0x34, 0x96, 0x55, 0xc8, 0x28, 0xab, 0x1c, 0xd4, 0x10, 0xb5,
-            0x83, 0x76, 0xd9, 0x5c, 0xd5, 0x22, 0x6f, 0x5d, 0x53, 0xee, 0x39, 0x54, 0x88, 0x9c, 0x85, 0xb9,
-            0x95, 0x2a, 0x5c, 0xb0, 0x00, 0x76, 0x61, 0x93, 0x02, 0x9b, 0x23, 0x59, 0x85, 0xcb, 0x9e, 0xd9,
-            0xa2, 0xe1, 0xa8, 0xeb, 0x16, 0xdc, 0xea, 0x26, 0x4d, 0xab, 0x9d, 0xe1, 0x63, 0xfa, 0x23, 0xd5,
-            0x9b, 0xdc, 0xbf, 0x4f, 0xa1, 0xe4, 0x18, 0xbf, 0xc4, 0x54, 0xba, 0x54, 0x47, 0x50, 0x51, 0x3a,
-            0xbc, 0x66, 0x1a, 0x5c, 0x8f, 0x0c, 0xbd, 0x55, 0x91, 0x78, 0x16, 0xd6, 0x8b, 0xa5, 0x99, 0xec,
-            0xf4, 0x2a, 0x94, 0xdf, 0x73, 0x3f, 0x7f, 0xe6, 0xae, 0x8f, 0x9f, 0x95, 0xbe, 0x4f, 0x40, 0xd3,
-            0xa6, 0x25, 0xdd, 0x50, 0x1f, 0xc1, 0xc0, 0xb6, 0x08, 0x29, 0x82, 0x4f, 0xad, 0x98, 0xeb, 0x66,
-            0xd7, 0xa2, 0x6b, 0x28, 0x47, 0xff, 0x15, 0x9c, 0xfd, 0x02, 0x5b, 0x91, 0xf1, 0x4c, 0x85, 0xbf,
-            0xd0, 0x02
-        };
-
-    }
-}

+ 0 - 90
src/Static/MemoryStaticResource.vala

@@ -1,90 +0,0 @@
-using Inversion;
-using Astralis;
-using Invercargill;
-
-namespace Spry {
-
-    public class MemoryStaticResource : Object, StaticResource {
-
-        private uint8[] identity;
-        private uint8[] gzip;
-        private uint8[] zstd;
-        private uint8[] br;
-        private string _name;
-        private string _content_type;
-        private string _e_tag;
-
-        public MemoryStaticResource(string name, string content_type, string e_tag, owned uint8[] identity, owned uint8[] gzip, owned uint8[] zstd, owned uint8[] br) {
-            _name = name;
-            _content_type = content_type;
-            _e_tag = e_tag;
-            this.identity = (owned)identity;
-            this.gzip = (owned)gzip;
-            this.zstd = (owned)zstd;
-            this.br = (owned)br;
-        }
-
-        public string get_best_encoding (Set<string> supported) {
-            var best = "identity";
-            var best_size = identity.length;
-            foreach(var encoding in supported) {
-                switch(encoding) {
-                    case "gzip":
-                        if(gzip.length != 0 && gzip.length < best_size){
-                            best = encoding;
-                            best_size = gzip.length;
-                        }
-                        break;
-                    case "zstd":
-                        if(zstd.length != 0 && zstd.length < best_size){
-                            best = encoding;
-                            best_size = zstd.length;
-                        }
-                        break;
-                    case "br":
-                        if(br.length != 0 && br.length < best_size){
-                            best = encoding;
-                            best_size = br.length;
-                        }
-                        break;
-                }
-            }
-            return best;
-        }
-
-        public string get_etag_for (string encoding) {
-            return @"\"$encoding-$_e_tag\"";
-        }
-
-        public HttpResult to_result(string encoding, StatusCode status = StatusCode.OK) throws Error {
-            HttpResult result;
-            switch(encoding) {
-                case "identity":
-                    result = new HttpDataResult(Wrap.byte_array(identity), status);
-                    break;
-                case "gzip":
-                    result = new HttpDataResult(Wrap.byte_array(gzip), status);
-                    break;
-                case "zstd":
-                    result = new HttpDataResult(Wrap.byte_array(zstd), status);
-                    break;
-                case "br":
-                    result = new HttpDataResult(Wrap.byte_array(br), status);
-                    break;
-                default:
-                    throw new Error.literal (Quark.from_string ("Not Found"), 404, "No such encoding");
-            }
-
-            result.set_header("Content-Type", _content_type);
-            result.set_header("Content-Encoding", encoding);
-            result.set_header("ETag", get_etag_for(encoding));
-            return result;
-        }
-
-        public string name { get { return _name; } }
-        public string content_type { get { return _content_type; } }
-        public string e_tag { get { return _e_tag; } }
-
-
-    }
-}

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/Static/Sources/htmx-sse.min.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/Static/Sources/htmx.min.js


+ 0 - 15
src/Static/StaticResource.vala

@@ -1,15 +0,0 @@
-using Inversion;
-using Astralis;
-using Invercargill;
-
-namespace Spry {
-
-    public interface StaticResource : Object {
-
-        public abstract string name { get; }
-        public abstract string get_best_encoding(Set<string> supported);
-        public abstract string get_etag_for(string encoding);
-        public abstract HttpResult to_result(string encoding, StatusCode status = StatusCode.OK) throws Error;
-
-    }
-}

+ 0 - 35
src/Static/StaticResourceProvider.vala

@@ -1,35 +0,0 @@
-using Astralis;
-using Invercargill.DataStructures;
-using Inversion;
-using Invercargill;
-
-namespace Spry {
-
-
-    public sealed class StaticResourceProvider : Object, Endpoint {
-
-        private Dictionary<string, StaticResource> resource_map =  inject_all<StaticResource>().to_dictionary<string>(r => r.name);
-
-        public async Astralis.HttpResult handle_request (Astralis.HttpContext http_context, Astralis.RouteContext route_context) throws Error {
-            StaticResource resource;
-            if(!resource_map.try_get(route_context.mapped_parameters["resource"], out resource)) {
-                return new HttpStringResult(@"No such resource \"$(route_context.mapped_parameters["resource"])\".", StatusCode.NOT_FOUND);
-            }
-
-            var accepts = http_context.request.headers
-                .get_or_empty ("Accept-Encoding")
-                .select_many<string>(h => Wrap.array<string>(h.split(",")))
-                .select<string>(s => s.chomp().chug())
-                .to_hash_set();
-
-            var best = resource.get_best_encoding (accepts);
-            var etag = resource.get_etag_for(best);
-            if(http_context.request.headers.get_or_empty("If-None-Match").contains (etag)) {
-                return new HttpEmptyResult(StatusCode.NOT_MODIFIED);
-            }
-
-            return resource.to_result (best);
-        }
-    }
-
-}

Некоторые файлы не были показаны из-за большого количества измененных файлов